Reputation: 11
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
Reputation: 6835
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")
request.is_ajax()
FalseThis is just because the request isn't an ajax request. It's just a normal form POST request.
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
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