Django:how to render template and send context to template with ajax? - python

(sorry for my bad English)
Hello. I know partly how ajax is used with Django. but I have some problems. Some of them are: how to render a template with ajax? How to send Django to template with ajax? I searched the internet but I couldn't find exactly what I wanted.
I would be glad if you could also recommend a detailed resource on the use of ajax and Django. (free:( ).please help me guy.thanks now.

First you have to create instances in your Django's views.py file which returns the data you wanna display in template.
Then you need to create an ajax function inside the template. Here is a basic ajax function that can be modified to your needs:
<script>
function loadDoc() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("demo").innerHTML = this.responseText;
}
};
xhttp.open("GET", "demo_get.asp", true);
xhttp.send();
}
</script>
What it does is reach out to the source of data in your case it will probably be the instances in views.py. "readyState == 4" tells you the data load is complete, while "this.status == 200" tells you if the request is successful.
The question on how to display the data depends on you and the type of data.

Related

AJAX request returns HTML file instead of data. ( Django & Python )

I have a profile page with user posts. People can like/dislike the posts. It works well but it reloads the page, that is why I am implementing AJAX.
The route goes like this.
Inside the profile view is the "like POST" request ending with a
data = {
'likes':post.likes.all().count()
}
return JsonResponse(data,safe=False)"
When clicking on the like button, I can see the data on a blank page if I want to. So I know it is receiving it.
Unfortunately, when using AJAX, instead of returning the data. it returns the profile view's
return render(request, "profile.html", context)
Here is my AJAX code
const post_id = $(this).attr('id')
const likeText = $( `.like_button${post_id} `).attr('name')
const trim = $.trim(likeText)
const url = $(this).attr('action')
let res;
const likes = $(`.like_count${post_id}`).text() || 0
const trimCount = parseInt(likes)
$.ajax({
type: 'POST',
url: url,
data: {
'csrfmiddlewaretoken':$('input[name=csrfmiddlewaretoken]').val(),
'post_id':post_id,
},
success: function(data){
console.log('success', data)
},
error: function(data){
console.log('error', data)
}
})
Any help would be much appreciated. First time using AJAX, so as much details would be appreciated.
Not really surprising it's returning HTML since that's exactly what you're returning in the view: rendered HTML. If you want JSON you need then you want a JSONResponse object.
https://docs.djangoproject.com/en/4.1/ref/request-response/#jsonresponse-objects
So, instead of:
return render(request, "profile.html", context)
which will take the profile.html, inject the values from context and send you that as html, you should do something like:
response = JsonResponse({"mydata": "goes here", "some_more": data})
You can then parse this as JSON in your AJAX code. If it's the case that the context dictionary contains all the data you need and that is what you want, you can just swap out that one line:
response = JsonResponse(context)
Edit: To address the question in the comment. Suppressing the default form response in the frontend is not a Django thing, it's done with JS on the event using something like:
e.preventDefault()
See here for info: https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault

Running django view/function on button click

I have the following button: <a class="btn btn-success">Accept</a>. Like this previous stack overflow question, I want to call my view after the button is clicked, but I can not seem to get it to work.
What I have tried: Using AJAX, treating button like a form, requesting post data, but this does not seem to work.
How can I make it so when my button is clicked, I call the bellow view?
def acceptdonation(request, pk):
Donation.objects.filter(pk=pk).update(views=F('views')+1)
return HttpResponseRedirect(request.GET.get('next')))
In your template link to the view you want:
Accept
Of course you can also pass a pk or other data to the url if you need to.
If you want to post a form to a view you can use this:
function submitToView() {
var formData = new FormData();
formData.append('some_variable', 'abc');
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == XMLHttpRequest.DONE) {
abc = JSON.parse(xhr.responseText);
}
}
xhr.open('POST', '/my_view/', true);
xhr.setRequestHeader("X-CSRFToken", csrftoken);
xhr.send(formData);
}
Please consider adding your javascript with html and your urls.py

How to refresh the page when custom plugin is saved?

I have created a website using Django cms. When I save the custom plugin the template is not rendered. But it is rendered when I refresh the page.
So, how to refresh the page while saving the django cms custom plugin or any other way to render the template when the plugin is saved. But the content is saved in the admin side. I am not able to see the content in the template.
You would want to use ajax here. This is a very vague code on how you should go about it. but hope it helps.
<script type="application/javascript">
$(document).ready(function() {
$('.save-plugin-button-id').click(function (e) {
e.preventDefault();
$.ajax({
url: url_which_saves_plugin,
method: 'GET',
data:{},#add data required if any or leave blank
success: function(data){
#You might want to stylize your data here.
$("#update-content-div-id").append(JSON.stringify(data));
}
})
})
})
</script>

In Django view,How to save array which pass from template via Ajax, to database?

I create array in JavaScript and send it via Ajax to my view and I can get it in view.Now I want to save it to my database(mysql) but I get "internal error" from Ajax.I think Ajax when post data to view and Django want to connect MySQL database, connection by ajax was abroted.
this is my template Ajax:
var postUrl = "http://localhost:8000/student/{{id}}/student_add_course/";
$('form[name="myForm"]').submit(function(){
$.ajax({
url:postUrl,
type: "POST",
// stock is somthing like this.stock=[[1,12],[2,14],...]
data: {'stock': stock, 'counter':i,csrfmiddlewaretoken: '{{ csrf_token }}'},
error:function (xhr, textStatus, thrownError){
alert(thrownError);},
})
});
this is view:
def student_add_course(request,student_id):
if request.method=='GET':
context={'id':student_id , 'form':AddCourseForStudentForm()}
request.session['ListOfCourses']=[]
return render(request, 'student/AddCourseForStudentForm.html',context)
elif request.is_ajax():
listOFcourses=course_passes.objects.order_by('-id')
id =listOFcourses[0].id
counter=int(request.POST.get('counter'))
for i in range(0,counter):
selected_course=request.POST.getlist('stock[%d][]'%i)
//course_passes is my table.
// evrey thing is good until here but when I want to save it,I get error.
#a.save()
return render(request, 'student/add_course.html')
What is my code problem and How should I solve it?
Is there better way to do this?
I'm sorry for my bad English.
Edit:
Finally I understand my problem is in MySQL side. The value which I want to insert is not correct and I change
a=course_passes(id+1,int(selected_course[0]),int(selected_course[1]),int(student_id))
to
find_user=user.objects.get(user_code=student_id,task=2)
a=course_passes(id+1,selected_course[0],selected_course[1],find_user.id)
thanks for your comment.

Django star rating system and AJAX

I am trying to implement a star rating system on a Django site.
Storing the ratings in my models is sorted, as is displaying the score on the page. But I want the user's to be able to rate a page (from 1 to 5 essentially) without a refresh or change of page.
I have found the following, and like the style of the stars here: http://jvance.com/blog/2008/09/22/JQueryRaterPluginNew.xhtml
Currently have a limited understanding of javascript and AJAX. Does anyone know how to use the stars in the above example combined with AJAX and Django, so you are able to update the database (models) without a page refresh when a user selects a rating?
It is also important that users are only able to vote once, i.e. they are not allowed to rate a page twice. It is stored in the models whether they have already voted and what their previous vote was. But how would I be able to modify the stars to show this?
So if you know how to do these things, or a more appropriate star rating graphics solution, or any good tutorials... please do share. Thank you.
AJAX sounds scary and confusing but it doesn't have to be. Essentially what you want to do is post some data to a particular url/view combo. See jQuery.post for more information on using AJAX to send data to the server.
#urls
urlpatterns += patterns('',
url(r'^article/rate/', 'article.rate'),
#views
def rate(request):
if request.method == 'POST':
# use post data to complete the rating..
#javascript
$.post("/article/rate", { rating: 3, article: 2 },
function(data) {
// success! so now set the UI star to 3
});
As far as I know, star-ratings are produced with radio controls and css. So if you want to show the current rating per user on load of the page, just have your template render the associated radio with the checked option.
Jonathan you are welcome to the django world. as Django is a cool framework some djangonauts have written nice sites to help us.
if you go to http://djangopackages.com/categories/apps/ and search "rating" you will find some django pluggables with examples that will help you a lot with your project.
also see those util answers in another question: Best Practices: How to best implement Rating-Stars in Django Templates
Working on this recently, so thought I would provide a solution to the mix. Firstly, I'm using RateIt, which I have found to be very simple to set up and quite intuitve to use (add the RateIt *.js and .*css files to your base.html template):
http://www.radioactivethinking.com/rateit/example/example.htm
Here are the key pieces to my solution:
urls.py
url(r'^object/rate/$', RateMyObjectView.as_view(), name='rate_my_object_view'),
my_template.html
<div class="rateit" data-rateit-resetable="false">Rate it!</div>
ajax.js
$('.rateit').bind('click', function(e) {
e.preventDefault();
var ri = $(this);
var value = ri.rateit('value');
var object_id = ri.data('object_id');
$.ajax({
url: '/object/rate/?xhr',
data: {
object_id: object_id,
value: value
},
type: 'post',
success: function(data, response) {
console.log("ajax call succeeded!");
},
error: function(data, response) {
console.log("ajax call failed!");
}
});
});
Some view bits are from James Bennett (setting xhr, for example):
http://www.b-list.org/weblog/2006/jul/31/django-tips-simple-ajax-example-part-1/
views.py
from django.views.generic.base import View
from .models import MyObject
class RateMyObjectView(View):
def post(self, request):
my_object = MyObject.objects.all().last()
xhr = 'xhr' in request.GET
star_value = request.POST.get('value', '')
my_object.score = star_value
my_object.save()
response_data = {
'message': 'value of star rating:',
'value': star_value
}
if xhr and star_value:
response_data.update({'success': True})
else:
response_data.update({'success': False})
if xhr:
return HttpResponse(json.dumps(response_data), content_type="application/json")
return render_to_response(self.template_name, response_data)
models.py
from django.db import models
class MyObject(models.Model)
score = models.FloatField(max_length=1, default=0)
Keep in mind that this is a naive solution, and simply replaces the current star score in the last item in your object list. It's not ideal, as it would be better to store scores as their own model and link to the object. This was you can store them and do calculations like average, etc. I'm working on this now and will update this answer when I'm finished.

Categories