Dominik21222
Dominik21222

Reputation: 11

Django: is_ajax() doesn't work while is_ajax does

So I'm trying to understand ajax in django. I try to make a view (MessageCreate) which will create a message and then display that in ChatView (DetailView) which is constantly reloading (that is already done and works fine). But while trying to make this MassageCreate, there are always problems with "POST not allowed". So while trying to understand what's exactly going on with that ajax, I've done small tests and it turned out that request.is_ajax() returns false while request.is_ajax works fine. How is that possible?

Here is my ajax function

     $(function() {
// This function gets cookie with a given name
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
    var cookies = document.cookie.split(';');
    for (var i = 0; i < cookies.length; i++) {
        var cookie = jQuery.trim(cookies[i]);
        // Does this cookie string begin with the name we want?
        if (cookie.substring(0, name.length + 1) == (name + '=')) {
            cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
            break;
        }
    }
}
return cookieValue;
}
var csrftoken = getCookie('csrftoken');

/*
The functions below will create a header with csrftoken
*/

function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
function sameOrigin(url) {
// test that a given url is a same-origin URL
// url could be relative or scheme relative or absolute
var host = document.location.host; // host + port
var protocol = document.location.protocol;
var sr_origin = '//' + host;
var origin = protocol + sr_origin;
// Allow absolute or scheme relative URLs to same origin
return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||
    (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||
    // or any other URL that isn't scheme relative or absolute i.e relative.
    !(/^(\/\/|http:|https:).*/.test(url));
}

$.ajaxSetup({
beforeSend: function(xhr, settings) {
    if (!csrfSafeMethod(settings.type) && sameOrigin(settings.url)) {
        // Send the token to same-origin, relative URLs only.
        // Send the token only if the method warrants CSRF protection
        // Using the CSRFToken value acquired earlier
        xhr.setRequestHeader("X-CSRFToken", csrftoken);
    }
}
});
});

function update_Msg(messages){
  var chat_field = $('.chat_update')
  chat_field.empty()
  for(i = 0; i < 10; i++){
    chat_field.append("<p>" + messages[i]['message'] + '</p>')
  }
};


function get_Msg(){
    $.ajax({
      url: "",
      method: "GET",
      data: {},
      success: function(json){
        update_Msg(json['messages'])
      } ,
      error: function(errorData){
      }
    })
}


  $(document).ready(function(){
    var messageForm = $('.form-message-ajax')
    messageForm.submit(function(event){
      event.preventDefault();
      var thisForm = messageForm
      var actionEndPoint = thisForm.attr('action') + '1'
      var httpMethod = thisForm.attr('method')
      var formData = thisForm.serializeArray()[1]['value']
      console.log(actionEndPoint, httpMethod, formData)
      $.ajax({
        url: "",
        method: "POST",
        headers: {
    'X-Requested-With': 'XMLHttpRequest'
  },
        data: {
          "form" : thisForm.serializeArray()[1]["value"]},
        success: function(json){
          window.location.replace(json['chat_id'])
        } ,
        error: function(errorData){
        }
      })
    })
  })

Here is my views.py:

class ChatView(DetailView):
model = Chat
template_name = 'WebChat/chat_view.html'
def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    # messages = self.get_object().messages.all()
    # context['messages'] = messages
    context['form'] = MessageForm
    return context
def get(self,request,*args, **kwargs):
    if request.is_ajax():
        messages = self.get_object().messages.all().values()
        return JsonResponse({'messages': list(messages)})
    return super().get(request, *args, **kwargs)

def MessageCreate(request):
        if request.method == "POST":
            print('this is POST')
        if request.is_ajax:
            print('this is ajax')
        return HttpResponseRedirect(reverse_lazy('WebChat:chat', kwargs={"pk":'1'}))

here my template:

<div class="container">
    <div class="chat_update">
    </div>
    <form  class='form-message-ajax' method='POST' action='{% url "WebChat:create" %}'>
        {% csrf_token %}
        {% bootstrap_form form %}
        <button type="submit" value="Send!" class="btn btn-default">Send</button>
    </form>
</div>

and my urls.py

app_name = 'WebChat'
urlpatterns = [
    path("<int:pk>", views.ChatView.as_view(),name='chat'),
    path('', views.MessageCreate, name = "create")
]

Does anyone have any idea what's going on here?

Upvotes: 0

Views: 663

Answers (2)

tim-mccurrach
tim-mccurrach

Reputation: 6835

Why do I get different results for is_ajax and is_ajax()

request.is_ajax is a function, request.is_ajax() returns the result of that function. The 'truthy-ness' of any function itself is True even if that function returns something that is always false. See the following:

def my_function():
    return False

if my_function:
    print("my_function is truthy")

if my_function():
    print("this will not get printed")

Why is request.is_ajax() False

This is just because the request isn't an ajax request. It's just a normal form POST request.

Also Note...

It's also worth noting that as of django 3.1 request.is_ajax is deprecated. I think at the moment it still works, (and should give you a deprecation warning), but it won't continue to work.

Upvotes: 1

rahul.m
rahul.m

Reputation: 5854

try this

$.ajax({
    url: "",
    method: "POST",
    headers: {
     'X-Requested-With': 'XMLHttpRequest'
   }
    data: {
      "form" : thisForm.serializeArray()[1]["value"]},
    success: function(json){
      console.log('hi)
    } ,
    error: function(errorData){
    }
  })

https://api.jquery.com/jquery.ajax/

Upvotes: 0

Related Questions