Django, jquery, and modelforms - ajax

Looking to get some insight and tips on using ajax with django.
Say I have a function:
def add_comment(request, pk):
if request.method == 'POST' and request.is_ajax():
comment_form = CommentForm(request.POST)
if comment_form.is_valid():
comment = comment_form.save(commit=True)
comment.save()
json = simplejson.dumps(comment, ensure_ascii=False)
return HttpResponse(json, mimetype='application/json')
return render_to_response({{ post.id }}', {'comment': comment,}), context_instance=RequestContext(request), mimetype='application/json')
and I'm trying to post the comments to a page without a redirect with ajax function:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script></javascript>
<script type="text/javascript">
$(document).click(function()
{
$('#comment_form').submit(function()
{
var dataString = $('#comment_form').serialize();
$.ajax({
type: 'POST',
url: '',
data: dataString,
success: function(data){
$('').html(data);
},
});
return false;
});
});
</script>
I believe I'm mixing up a few things here. I am trying to get the page to load comments without a redirect. I don't need an exact answer, maybe just steered in the right direction.

This can helps:
this could be your view:
import json
def add_comment(request, pk):
if request.method == 'POST' and request.is_ajax():
comment_form = CommentForm(request.POST)
if comment_form.is_valid():
comment = comment_form.save(commit=True)
comment.save()
json_response = json.dumps({"status":"Success"})
return HttpResponse(json_response)
errors = {}
for k, v in job_type_form.errors.items():
errors[k.capitalize()] = v
response = {
'success': False,
'errors': errors
}
return HttpResponse(json.dumps(response))
and your jquery could be like this:
$('#comment_form').submit(function() {
var dataString = $('#comment_form').serialize();
$.ajax({
type: 'POST',
url: '',// you need to put this to something like '{% url to_your_view %}'
data: dataString,
dataType: 'json'
success: function(data){
// you can access to your json object like data.status or data.something
$('').html(data.status);
},
});
return false;
});

Thanks for the posts I finally got things worked out. The jquery was the main issue.
$(document).ready(function() {
$('#comment_form').submit(function(e) {
e.preventDefault();
$.ajax({
type: 'POST',
url: '{% url art.views.post %}',
data: $('#comment_form').serialize(),
dataType: 'json';
success: function(){
location.reload();
$('#comment_form').get(0).reset();
},
});
return false;
});
});
I was sending the DOM object not the actual form data to the view.
In the view I combined two functions to get the two sharing the same URL.
def post(request, pk):
post = Post.objects.get.(pk=int(pk))
comments = Comment.objects.filter(post=post)
_dict = dict(post=post, comments=comments, form=Comment_form(), user=request.user)
_dict.update(csrf(request))
cf_obj = Comment(post = Post.objects.get(pk=pk))
if request.method == 'POST' and request.is_ajax():
if comment_form.is_valid():
comment = comment_form.save(commit=True)
else:
raise Http404
response = serializers.serialize('json', [comment])
return HttpResponse(response, mimetype='application/json')
return render_to_response('post.html', d)

Related

Ajax in Django : url not found

I am coding a small Django project where an user can select an object and save it in a database. I am trying to implement an Ajax call on a button to delete this object if necessary.
I am doing it step by step, debugging with the console.
my urls:
app_name = 'register'
urlpatterns = [
path('<int:user_id>/', views.account, name='account'),
path('/delete/', views.delete, name='delete'),
]
my view.py:
def delete(request):
data = {'success': False}
if request.method=='POST':
product = request.POST.get('product')
print(product)
data['success'] = True
return JsonResponse(data)
my ajax.js:
$("#form_id").on('submit', function(event) {
event.preventDefault();
var product = 'coca-cola'
console.log('ok till this point')
$.ajax({
url: '{% url "register/delete" %}',
type: "POST",
data:{
'product':product,
'csrfmiddlewaretoken': $('input[name=csrfmiddlewaretoken]').val()
},
datatype:'json',
success: function(data) {
if (data['success'])
console.log('working fine')
}
});
});
My view isn't doing much for now but I haven't any knowledge about Ajax and I am doing it one step at a time.
This is the error I get in the console:
jquery.min.js:2 POST http://127.0.0.1:8000/register/6/%7B%%20url%20%22register/delete%22%20%%7D 404 (Not Found)
As far as I understand, Ajax can't find my url: '{% url "register/delete" %}'.
I have tried '{% url "register:delete" %}' with no luck either.
I found an answer after some tweaking, I defined my url before the Ajax call and then pass it in it:
$("#form_id").on('submit', function(event) {
event.preventDefault();
var product = 'coca-cola'
var url = '/register/delete/'
console.log( url)
$.ajax({
url: url,
type: "POST",
data:{
'product':product,
'csrfmiddlewaretoken': $('input[name=csrfmiddlewaretoken]').val()
},
datatype:'json',
success: function(data) {
if (data['success'])
console.log('working fine')
}
});
});
Also you can add just the string of url to "url" parameter without characters {% url %}. Maybe you copied the code from pattern Django and added it to JS-file. So it does not work.

ajax post request to view

I am trying to make a simple ajax request to a view but keep having a not Found error for the given url:
Not Found: /myapp/start_session/1/scan_ports/
"POST /myapp/start_session/1/scan_ports/ HTTP/1.1" 404 5711
js
$(document).ready(function() {
$.ajax({
method: 'POST',
url: 'scan_ports/',
data: {'csrfmiddlewaretoken': '{{csrf_token}}'},
success: function (data) {
alert("OK!");
},
error: function (data) {
alert("NOT OK!");
}
});
});
url
url(r'^scan_ports/$',views.ScanPorts,name='scan_ports'),
view
#login_required
def ScanPorts(request):
user = request.user
if request.method == 'POST':
currentSetting = models.UserSetting.objects.filter(isCurrent=True)
if currentSetting.serialPort:
print("GOT IT!")
return HttpResponse('')
Is the ajax request not set properly?
Assuming you are in the "myapp" app, replace:
method: 'POST',
url: 'scan_ports/',
for this:
method: 'POST',
url: '/myapp/scan_ports/',
First check your urls, the url on which you posted is incorrect hence 404 not found error.
Try to define your url in your JS as: {% url 'scan_ports' %} which will search your urls with the name your provided in urls.py
In addition, this may not be a good approach to submit a form via ajax.
Your JS should be something like this:
$('.form-class-name').on('submit', function (e) {
e.preventDefault();
console.log("ajax is called");
$.ajax({
type: $(this).attr('method'),
url: "/url-name/",
data: $(this).serialize(),
dataType: 'json',
success: function(data) {
alert("success");
},
error: function(data) {
alert("Failure");
}
})
}
e.preventDefault() prevents the natural/default action, and prevents from submitting the form twice.
.serialize(), serializes the form data in a json format.
append a "/" before and after your action url.
Your view must return a dictionary as ajax deals with JSON format.
Edit your view like this:
if request.method == "POST":
currentSetting = models.UserSetting.objects.filter(isCurrent=True)
if currentSetting.serialPort:
print("GOT IT!")
a = {'data':'success'}
return HttpResponse(json.dumps(a))
This will return a dictionary required by the ajax.

How do django send ajax response?

Here is my code ,I got response is 200 OK but ajax came to error part
I can't figure it out
My html:
$(".statics").click(function(){
var name = $(this).attr("data-name");
$.ajax({
url: 'statics/',
data: {
'name':name
},
type: 'POST',
async: false,
dataType: 'json',
success: function(dataArr){
console.log("ssss:",dataArr)
if(dataArr == "IS_PASS"){
alert('PASS!');
}else if(dataArr == "NOT_PASS"){
alert('NOT_PASS');
}
},
error: function(ts){
console.log("eeee:",ts)
alert('fail');
},
});
});
My views.py
def statics_r(request):
if request.is_ajax():
name = request.POST['name']
...
if is_pass:
return HttpResponse("IS_PASS")
else:
return HttpResponse("NOT_PASS")
And the console is : eeee: Object {readyState: 4, responseText: "NOT_PASS", status: 200, statusText: "OK"}
Why it is not success???
For an ajax response, you should be returning json, the easiest way is to use the JsonResponse class instead of HttpResponse, or set the content_type
HttpResponse("{'result': 'IS_PASS'}", content_type="application/json")
You would need to adjust your success function to access the results, i.e dataArr.result

Django AJAX post not working with CSRF

I have this ajax like vote on my article model:
#csrf_exempt
#login_required
def like(request):
args = {}
if request.method == 'POST':
user = request.POST.get('user')
lu= request.user
post_id = int(request.POST.get('post_id'))
try:
liked_article = Article.objects.get(id = post_id)
except:
liked_article = None
if ArticleLike.objects.filter(liker=lu.id, article=post_id).exists():
liked_article.likes -=1
liked_article.save()
ArticleLike.objects.filter(article=post_id, liker=lu.id).delete()
else:
liked_article.likes +=1
liked_article.save()
newliker = ArticleLike(article=post_id, liker=lu.id)
newliker.save()
args.update(csrf(request))
args['likes'] = str(liked_article.likes)
return render(request, 'ajax_like.html', args)
Here is the ajax snippet:
$(function(){
$('#like').click(function(){
$.ajax({
type: "POST",
url: "/article/like/",
data: {
'post_id': $(this).attr('name'),
'csrfmiddlewaretoken': '{{csrf_token}}'
},
success: likeSuccess,
dataType: 'html'
});
});
});
function likeSuccess(data, textStatus, jqXHR)
{
$('#like_count').html(data);
}
and ajax_lik.html
<p id="like_count">
{% if likes > 0 %}
{{likes}}
</p>
{% else %}
wow
</i>
{% endif %}
The view works perfectly well with #csrf_exempt decorator active, but with csrf, I get 403 Forbidden error.
I tried different tweaks but could not figure out how solve this, so I appreciate your help.
If you are using a #csrfexempt decorator then you don't need to send a csrf_token. BTW, csrf_token shouldn't be part of the POST data,
data: {
'post_id': $(this).attr('name'),
'csrfmiddlewaretoken': '{{csrf_token}}'
}
it should be in the request's header "X-CSRFToken".
Here a little example to set custom headers to an ajax request using jquery (docs here):
$.ajax({
url: "/article/like/",
data: { post_id: $(this).attr('name') },
type: "POST",
beforeSend: function(xhr){xhr.setRequestHeader('X-CSRFToken', "{{csrf_token}}");},
success: likeSuccess,
dataType: 'html'
});
You can see Django's docs for this here

Error when returning single json object after an ajax call in django

when i get multiple objects, it works fine but if i only get 1, it returns an error
views.py
def get_incident_personnel(request):
args = {}
store = Store.objects.get(store_id=request.POST['store'])
data = serializers.serialize('json', store)
return HttpResponse(data, mimetype='application/json')
and here is my ajax.js
$('#id_store').change(function() {
var store = $('#id_store').val();
$.ajax({
url: '/incidents/get_incident_personnel/',
type: 'POST',
dataType: 'json',
data: {
'store': store,
'csrfmiddlewaretoken': $('input[name=csrfmiddlewaretoken]').val()
},
success: function(data) {
console.log(data);
}
});
});
You can't use serializers.serialize on a model instance, only on a QuerySet. Use filter even though you know you're only going to get one object.
store = Store.objects.filter(...)

Resources