Django - "return render(...)" doesn't work in a view that interacts with an ajax request

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.

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>
Back to Top