How to render data in django to AJAX? - javascript

I am trying to send a json value to ajax from django class based view and the data i am sending will be appended in html through ajax. but i am not able to send value from back end to front end successfully.
class DetailView(TemplateView):
template_name = 'list.html'
def get_context_data(self,*args, **kwargs):
context = super(DetailView,self).get_context_data()
list_view = GetList().get_data(self.request)
movie_list = list.json()
context['list']= movie_list
print(movie_list)
return context
So this code is sending only template value to the ajax data, when i do the console.log(data) on success call it shows me whole html code of the 'list.html' in both alert and console.log . But it prints all the values in cmd console.
cclass DetailView(TemplateView):
template_name = 'list.html'
def get(self,request):
list_view = GetList().get_data(self.request)
movie_list = list.json()
return HttpResponse(json.dumps(movie_list))
this code prints all the values on respective html, but doesnt call ajax function.so no values showing in console.log.
this is my ajax call,first i am trying to just see weather i'm successfully getting the values on success call or not.
<script>
$(document).ready(function(){
$.ajax({
method :'GET',
url: '/detail',
success: function(data){
alert(data)
console.log(data)
},
})
})
</script>
So, how can i achieve my desired result? I want to get value in ajax call so i cal show those values in a table which is in a list form

You can use JsonResponse to send json data. (You can see detail in docs here)
like below
from django.http import JsonResponse
class DetailView(TemplateView):
template_name = 'list.html'
def get(self,request):
list_view = GetList().get_data(self.request)
movie_list = list.json()
return JsonResponse(movie_list, status=200)
btw, you have to aware your data type. JsonResponse automatically serialize your data so you don't have to use json() for your data.

Related

How do I send django object list to javascript?

I want to django query to javascript.so I changed queries to list. I sended list to javascript.But list were not displayed by console log.
class Comment_List_TV(ListView):
template_name = 'account/user_comment_list_tv.html'
def get_queryset(self):
Comment_list_query = list(Comment_tv.objects.none())
if self.request.user.is_authenticated:
Comment_list_query = list(Comment_tv.objects.filter(user=self.request.user))
print(Comment_list_query)
return Comment_list_query
Print display object list. But
const mydata = "{{Comment_list_query}}";
console.log(mydata);
Console log does not display django's object list.
why?
How do I send django object list to javascript?
Console log does return nothing because Comment_list_query in django template is called object_list, so you should use...
const mydata = "{{ object_list }}";
console.log(mydata)
But it won't work, because you probably needs parsed values.
So, you should write view like this:
#csrf_exempt
def get_comments(request):
comment_list_query = list(Comment_tv.objects.all())
return JsonResponse({'result': comment_list_query})
And receive it from AJAX call (for example using AJAX method from jQuery package).

How to package plain JSON content in a WSGI response?

I have a Django WSGI (not my decision) website making a call to fetch dynamically generated JavaScript. I put the function in views.py and it's receiving the request and doing the work, but the return value is being rejected.
The HTML (JavaScript section of web page) that calls this function does it like this:
var jscript = document.createElement('script');
jscript.id = 'generate';
jscript.style.visibility = 'hidden';
jscript.style.display = 'none';
jscript.src = `/generate?callback=catchOptions${query}`; // jsonp https://en.wikipedia.org/wiki/JSONP query is a list of parameters in query string format
if (document.getElementById("generate") == null)
document.body.appendChild(jscript); // javascript needs this to work properly
There's map file that maps /generate to /generate_planet (see below). Getting into the function works great. It's the return value that Djangoff is rejecting.
Here is the function in views.py
from cgitb import reset
from django.shortcuts import render
from . import planetor
from django.http import JsonResponse
def generate_planet(request):
res = planetor.generate(request.content_params, "/app/planetor/", "FRAMES=1")
# res is JSON text, NOT a python dict
return res
# res looks like this:`callback({'camera_location': '-30,-30,-30', 'camera_angle': '30', 'sun_color': '5,5,5', 'sun_position': '10000,0,-10000', 'planet_size': '20.06', 'background': 'background_2.jpg', 'planet': 'surface_1.jpg', 'clouds_size': '1.02', 'clouds': 'clouds_16.jpg', 'clouds_density': '0.80', 'atmosphere': 'iodine', 'atmosphere_density': '0.95', 'atmosphere_size': '1.03', 'moons': '4', 'moon_position': None, 'moon_size': None, 'moon': None, 'random_color': None, 'random_float': None, 'random_trans': None, 'star_system': 'Barnard', 'star_index': 'Zeta', 'planet_index': 'II', 'planet_type': 'Surface ', 'identity': '81654447928', 'designation': 'v_star_index v_star_system v_planet_index', 'clouds_file': 'clouds_16.jpg'})
The function call actually works, and the "planetor.generate()" runs. The problem is, the return JSON (JSONP really) from this, is rejected by Djangoff
Djangoff spits out this:
Internal Server Error: /generate_planet
Traceback (most recent call last):
File "/usr/local/lib/python3.9/dist-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/usr/local/lib/python3.9/dist-packages/django/utils/deprecation.py", line 119, in __call__
response = self.process_response(request, response)
File "/usr/local/lib/python3.9/dist-packages/django/middleware/clickjacking.py", line 33, in process_response
response.headers['X-Frame-Options'] = self.get_xframe_options_value(
AttributeError: 'dict' object has no attribute 'headers'
[05/Jun/2022 16:52:11] "GET /generate_planet? HTTP/1.1" 500 56694
It's looking for the return value to be wrapped in something I'm sure but for the life of my I can't find 1) any API documents for WSGIResponse to I can construct one and 2) examples of anyone doing anything like this with Djangoff
I eventually figured this out.
If you send a request to Django, like this:
/my_request?key1=value1&key2=value2&key3=value3
By whatever means (raw URL, form submit, ajax request, whatever)
To have Django catch that request and return a JSON answer put a function like this in views.py
def my_request(request):
selections = request.GET # <== this gets the query string paramaters as a dictionary
# use the query string parameters as the parameters of the function for creating the answer to the request
res = {"answer1":"value1","answer2":"value2"} # << python dictionary of answer
return JsonResponse(res) # convert dictionary to JSON
If you want to get JSONP back, you'll have to just code the raw javascript:
return 'callback({"answer1":"value1","answer2":"value2"})'

Render template in Django view after AJAX post request

I have managed to send & receive my JSON object in my views.py with a POST request (AJAX), but am unable to return render(request, "pizza/confirmation.html"). I don't want to stay on the same page but rather have my server, do some backend logic on the database and then render a different template confirming that, but I don't see any other way other than AJAX to send across a (large) JSON object. Here is my view:
#login_required
def basket(request):
if request.method == "POST":
selection = json.dumps(request.POST)
print(f"Selection is", selection) # selection comes out OK
context = {"test": "TO DO"}
return render(request, "pizza/confirmation.html", context) # not working
I have tried checking for request.is_ajax() and also tried render_to_string of my html page, but it all looks like my mistake is elsewhere. Also I see in my terminal, that after my POST request, a GET request to my /basket url is called - don't understand why.
Here is my JavaScript snippet:
var jsonStr = JSON.stringify(obj); //obj contains my data
const r = new XMLHttpRequest();
r.open('POST', '/basket');
const data = new FormData();
data.append('selection', jsonStr);
r.onload = () => {
// don't really want any callback and it seems I can only use GET here anyway
};
r.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
r.send(data);
return false;
In your basket view function, you always render the template as response. You can pass the parameters to your js snippet via HttpResponse. After request completed and you have response in your js function, you can use window.location.href to redirect the page you want. You can also look this answer to get more information.

Passing variable between view and JS; Django

I am first passing a JS variable 'confirmed' to my Django view via POST request.
I then run a python script which takes this variable and does some processing.
Finally I want to pass it back to my html/JS so I can display the processed data.
I am currently trying to use Django sessions to achieve my goal but there is a '1 session delay', so the session variable which I update is returning as the value from the previous session.
Is there a better way I can pass the variable from my view to JS/a fix for my current solution?
VIEW:
def crossword(request):
if request.method == 'POST':
Session.objects.all().delete()
str_squares = (request.body).decode('utf-8')
squares = [int(i) for i in str_squares.split(',')]
letters = puzzle_solver.solve_puzzle(3, squares)
# print(letters)
for each_square in letters.keys():
request.session[each_square] = letters[each_square]
request.session.modified = True
return render(request, 'crossword.html')
JS:
// Output a list of active squares
var xhr = new XMLHttpRequest();
var generate = { Generate:function(){
var confirmed = [];
for (i=0; i<active_boxes.length; i++){
confirmed.push(active_boxes[ i ].id_num);
}
console.log(confirmed);
xhr.open("POST", "http://localhost:8000/", true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(c=confirmed);
console.log("{{ request.session.keys }}")
console.log("{{ request.session.values }}")
var tester = parse_session_keys("{{ request.session.keys }}");
console.log(tester);
solve_crossword(tester);
}};
Is there a reason why you are not sending the response directly back to JS? In your views.py, you can do
from django.http import JsonResponse
def crossword(request):
if request.method == 'POST':
str_squares = (request.body).decode('utf-8')
squares = [int(i) for i in str_squares.split(',')]
letters = puzzle_solver.solve_puzzle(3, squares)
return JsonResponse(letters)
return render(request, 'crossword.html')
After sending your request, wait and read the response directly as JSON then play with it in your JS code, as described in this post.
If there is any reason preventing you from doing this (for example there might be a form also makes POST requests to the same page thus you need to eventually land on rendering the crossword template), allocate another url for your api like /api/crossword
Your original idea of using session should not be used in this use case, especially with your Session.objects.all().delete() line (don't delete all session data without checking).

What am I doing Wrong? - Django JSON response and JQuery

I am working on a small website and I need to send thread-post data through JSON.
This is the JSON object django serves:
[{"text":"Some sample text","id":"21","title":"Test Thread"}]
I saved this as a .js file and the following Javascript code works fine:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"> </script>
<script>
$(document).ready(function(){
$("button").click(function(){
$.getJSON("testjson.js",function(result){
$.each(result, function(i, field){
$("div").append(field.text + " ");
});
});
});
});
</script>
However when I change the getJSON url field to:
//localhost/wall/21/ - format: //localhost/wall/thread_id
It displays nothing. The web console of firefox does not display any errors either.
My view code is the following:
def thread_view(request, wall, Id):
if request.method == 'GET':
thread = api.get_thread(wall, Id)
if thread != None:
return HttpResponse(thread, content_type="application/json")
else:
return HttpResponse("No results")
else:
raise Http404
It takes information from the database and formats it into json using a simple serializer, and then sends the data.
What am I missing?
Extra info below...
Serializer:
from bson import json_util
class JSONSerializer(object):
def dumps(self, obj):
return json_util.dumps(obj, separators=(',', ':')).encode('utf-8')
def loads(self, data):
return json_util.loads(data.decode('utf-8'))
I am using Django 1.6, JQuery 1.1, Python 2.7
P.S
When I enter the following url:
//localhost/wall/21/
firefox displays the JSON object just fine and it's exactly the same as the one in the js file.
Any help will be appreciated.

Categories

Resources