Django returns invalid ajax response - python

I have a ajax call in my django template file as:
$(document).ready(function () {
$("button#wdsubmit").click(function(){
$.ajax({
type: "post",
url: "/audit/addwd/",
data: $('form.wddetails').serialize(),
dataType: "json",
success: function(msg){
alert(msg);
alert('Added Successfully');
$("#newwd").modal('hide'); //hide popup
},
error: function(msg){
alert(msg.success);
}
});
});
});
Form:
class WDForm(ModelForm):
class Meta:
model = WDModel
fields = '__all__'
and view in django is :
def addwd(request):
if request.method == 'POST':
updated_request = request.POST.copy()
updated_request.update({'updated_by': request.user.username})
form = WDForm(updated_request)
if form.is_valid():
form.save()
response = simplejson.dumps({'success': True})
return HttpResponse(response, content_type="application/json", mimetype='application/json')
else:
response = simplejson.dumps({'error': True})
return HttpResponse(response , content_type="application/json")
Whenever I make a Ajax call it always returns error even though I have sent Success(Means the form is valid and data is successfully pushed to database).
I also tried to send response={'success':True} doesn't work.
Please help me to solve this issue.
Environment Details:
Python verion: 3.4
Django :1.7
Windows OS 8
I doubt on this line " response = simplejson.dumps({'success': success})
"

you can try JsonResponse objects.
from django.http import JsonResponse
return JsonResponse({'foo':'bar'})

Related

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>

Unable to render a template after using fetch in django

I have the following requirement:
Send data to backend using fetch()
receive the data in a view and render another template ( route to a different view)
The following is my code snippet:
JS:
fetch("/addpost", {
method: "POST",
body: JSON.stringify({ value: selecteddict }),
headers: {
"Content-type": "application/json;",
},
})
.then((res) => {
return res.text();
})
.then((text) => {
console.log(text);
});
// the data is being sent successfully
Django View1:
#csrf_exempt
def addpost(request):
if request.method == 'POST':
song = json.loads(request.body.decode('utf-8'))['value']
print(song)
# I want to redirect to another view called createpost that renders a new page
return JsonResponse({'status':201})
return render(request, 'addpost.html')
Django createpost view:
def createpost(request):
return render(request, 'createpost.html')
The view createpost is working fine when given the required path but it is not rendering when it's redirected from addpost
Please suggest a solution to this.
Your addpost view returns as JsonResponse in case of a POST request. If you want to redirect somewhere you need to use redirect() instead of JsonResponse()

Unable to receive json response from Django view to template?

I am trying to send a json response from django view to template but when I try to console.log the response in my ajax, I am getting nothing. What could i be doing wrong ? I am trying to pass the result data from views to my ajax success function. I also noticed something strange that when I mention the datatype = json in my ajax then I dont receive any response in the success function but when I remove the dataType = json then I get the entire html of my template in my success function as a response. Why is that ??
views.py
class ChangePassword(View):
def post(self, request, *args, **kwargs):
form = PasswordChangeForm(request.POST)
#current_password = json.loads(get_value.current_password)
#print ('current password',get_value['current_password'])
if form.is_valid():
print("valid form")
user = CustomUser.objects.get(email=request.user.email)
current_password = form.cleaned_data['current_password']
print('current_password',current_password)
new_password = form.cleaned_data['new_password']
print('newpassword',new_password)
if user.check_password(current_password):
print('entered')
update_session_auth_hash(self.request, self.request.user) # Important!
user.set_password(new_password)
user.save()
result = {'success': "Succefully reset your password"};
result = json.dumps(result)
print ('result',result)
return render(request, 'change_password.html',context={'result': result})
else:
return render(request, 'change_password.html', {'error': "We were unable to match you old password"
" with the one we have. <br>"
"Please ensure you are entering your correct password"
"then try again."})
else:
print("not valid")
return render(request, 'change_password.html', {'form':form})
def get(self, request, *args, **kwargs):
return render(request, 'change_password.html', {})
template
function changePassword() {
csrfSetUP()
new_pass = document.getElementById('new_pass')
cur_pass = document.getElementById('current_pass')
if (validpassword(new_pass) && cur_pass!= "") {
var cpass = $('#current_password').val();
var npass = $('#new_pass').val();
var data = {current_password:cpass,new_password:npass}
$.ajax({
url: '/account/change_password/',
type: 'post',
data: data,
dataType: "json",
success: function(json) {
console.log(json)
}
});
} else {
$('#change_password').submit()
}
}
When you are working with AJAX you have to use JSONResponse() instead of render()
from django.http import JsonResponse
return JsonResponse({'foo':'bar'})
If you need to have generated some HTML with that JSON - it is even better to use render_to_string method and return a html string to your AJAX, smth like that:
html = render_to_string('ajax/product_details.html', {"most_visited": most_visited_prods})
return HttpResponse(html)
NOTE: When using render_to_string remember to delete dataType: "json" from your AJAX, cuz u return not JSON, but a string.
P.S. Under this question there are plenty of examples how this can be done, but look at newer ones.

The render do not render to the template

In the admin index page I bind a id to a button, and use jquery ajax to request a logout event:
$("#logout").click(function(){
$.ajax({
url:'/logout/',
type:'POST'
})
})
And in the frontend/views.py:
def logout(request):
if request.method == 'POST':
request.session['username'] = None
request.session['is_login'] = False
import app_admin.views as app_admin_views
app_admin_views.conn = None # clean the connection
print ('before logout')
return render(request,'frontend/login.html')
In the Terminal have printed the 'before logout', but the page do not render to the frontend/login.html, and I also tried use redirect, all failure.
In logout view function, return a redirect
return redirect('login-or-something')
In javascript AJAX request handle the redirect response,
function handleSuccess(data, textStatus, jqXHR) {
location.href = jqXHR.getResponseHeader('Location');
}
function handleError(jqXHR, textStatus, errorThrown) {
console.log(errorThrown); // send to some error log collectors
}
$.ajax({
url:'/logout/',
type:'POST'
success: handleSuccess,
error: handleErr
});

django rest framework 3 ImageField send ajax result “No file was submitted.”

I have an API endpoint with Django Rest Framework to upload an image.
Can you spot what I'm doing incorrectly?
#models.py
class test(models.Model):
...
upload_path = 'upload/'
image = models.ImageField(upload_to=upload_path, null=True, blank=True)
...
#serializers.py
class TestSerializer(serializers.ModelSerializer):
image = serializers.ImageField(
max_length=None, use_url=True,
)
class Meta:
model = test
fields = ('id','name','image',...)
#views.py
#api_view(['GET', 'POST'])
def test_list(request, site_id, block_id):
....
if request.method == 'POST':
serializer = TestSerializer(data=request.DATA)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(
serializer.errors, status=status.HTTP_400_BAD_REQUEST)
else :
return Response(status=status.HTTP_403_FORBIDDEN)
#js
function setimage() {
var $input = $("#js_teaser_img");
var fd = new FormData;
fd.append('image', $input.prop('files')[0]);
$.ajax({
url: '/api/....',
data: fd,
processData: false,
contentType: false,
type: 'POST',
success: function (data) {
alert(data);
}
});
}
result image: ["No file was submitted."] 0: "No file was submitted."
result
Django REST Framework upload image: "The submitted data was not a file"
+
var reader = new FileReader();
reader.onload = function(e) {
var img_local = e.target.result;
$('.js_img_src').attr('src', img_local);
$.post('/api/..../7/', {'image':img_local} , function( data ) {
console.log(data);
});
}
reader.readAsDataURL(file);
From the client side in order to send files, you should use "multipart/form-data" (jQuery sets contentType as "application/x-www-form-urlencoded" instead by default).
Read this question on SO: Sending multipart/formdata with jQuery.ajax
Regarding instead python and django rest framework, you should use MultiPartParser and/or FileUploadParser in your API view and the preferred method for fle upload should be "put", as you can see in the reference here: http://www.django-rest-framework.org/api-guide/parsers/#fileuploadparser.
ps. if you use django rest framework, I strongly encourage you to use Angular instead of jQuery, since it offers an excellent integration for rest services... trust me is FAR BETTER! ;)

Categories

Resources