I want to solve this task: I click a button on the first page and after that my view creates a chat room and redirects me to the chat page.
I decided to use ajax request for this task, but I have a problem, my view works until line return render(request, 'chat/chatroom.html')
, the chat room is created, but the chat/chatroom.html
page doesn't open, I don't understand why. I have no errors, the return render(request, 'chat/chatroom.html')
line does nothing.
My code:
html
<button type="submit" id="chat-button" value="{{advertisement.author.id}}">Write to the author</button>
<script>
$(document).on('click', '#chat-button', function (e) {
e.preventDefault();
$.ajax({
type: 'POST',
url: '{% url "main_app:create-chat" %}',
data: {
send_to_id: $('#chat-button').val(),
csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val(),
action: 'post'
},
success: function (json) {
},
error: function (xhr, errmsg, err) {
}
});
})
</script>
views.py
from django.contrib.auth import get_user_model
from django.shortcuts import render, redirect, get_object_or_404
from django.db.models import Q
from django.utils.decorators import method_decorator
from django.views import View
from django.views.decorators.csrf import csrf_exempt
from chat.models import Thread
User = get_user_model()
@method_decorator(csrf_exempt, name='dispatch')
class CreateChat(View):
def post(self, request):
send_to_id = int(request.POST.get('send_to_id'))
send_to = User.objects.get(id=send_to_id)
auth_user = request.user
final_q = Q(Q(first_person=send_to) & Q(second_person=auth_user)) \
| Q(Q(first_person=auth_user) & Q(second_person=send_to))
thread = Thread.objects.filter(final_q)
if not thread:
Thread.objects.create(first_person=auth_user, second_person=send_to)
return render(request, 'chat/chatroom.html')
urls.py
app_name = 'main_app'
urlpatterns = [
...
path('create_chat', CreateChat.as_view(), name='create-chat')
]
I guess ajax request is not the best solution, but I don't know how to implement this feature in another way. Thanks for the help.
CodePudding user response:
AJAX always returns to request when it is called, so you can't render it to a new view. so to do this, when the request has been successfully completed, return status 200, etc. when getting the success response in AJAX call. likely in
success: function (json) {
},
redirect it to the desired view. so the code will be like that.
from http.client import OK
from django.http import JsonResponse
@method_decorator(csrf_exempt, name='dispatch')
class CreateChat(View):
def get(self,request):
return render(request, 'chat/chatroom.html')
def post(self, request):
send_to_id = int(request.POST.get('send_to_id'))
send_to = User.objects.get(id=send_to_id)
auth_user = request.user
final_q = Q(Q(first_person=send_to) & Q(second_person=auth_user)) \
| Q(Q(first_person=auth_user) & Q(second_person=send_to))
thread = Thread.objects.filter(final_q)
if not thread:
Thread.objects.create(first_person=auth_user, second_person=send_to)
return JsonResponse({},status=OK)
and the AJAX request will be like that
<script>
$(document).on('click', '#chat-button', function (e) {
e.preventDefault();
$.ajax({
type: 'POST',
url: '{% url "main_app:create-chat" %}',
data: {
send_to_id: $('#chat-button').val(),
csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val(),
action: 'post'
},
success: function (json) {
location.href = "create-chat" // from here render create-chat
},
error: function (xhr, errmsg, err) {
}
});
})
</script>