Django: send json response from view to a specific template - python

The main requirement is to send a json object from django view to a specific template named output.html (already present in templates directory), as a part of response. Also, the json response contains model and pk attribute, I want to remove them and send only the fields json attribute.
When I try as follows :
def view_personal_details (request):
personal_detail_json = personal_details.objects.all()
personal_detail = serializers.serialize('json', personal_detail_json)
return HttpResponse (serializers.serialize('json', personal_detail_json), content_type='application/json');
I get json in a new page.
And when I try as follows :
def view_personal_details (request):
personal_detail_json = personal_details.objects.all()
personal_detail = serializers.serialize('json', personal_detail_json)
return render (request, "webFiles/output.html", {'personal_detail': personal_detail})
I have to access the data via {{ personal_detail }} in my html, and not from response.
Also, the json response is as follows :
[
{
model: "buglockerApp.personal_details",
pk: "001",
fields: {
name: "Rajiv Gupta",
email: "rajiv#247-inc.com",
doj: "2016-06-22",
dob: "2016-06-22",
address: "Bangalore",
contact: "9909999999"
}
}
]
I don't want the model and pk to be sent as the response. Only fields should be sent as a part of response to webFiles/output.html file.
Thanks in advance!!

you can do the following in python2.7
import json
from django.http import JsonResponse
def view_personal_details (request):
personal_detail = serializers.serialize('json', personal_details.objects.all())
output = [d['fields'] for d in json.loads(personal_detail)]
# return render (request, "webFiles/output.html", {'personal_detail': output})
# for ajax response
return JsonResponse({'personal_detail': output})
or you can read the following for more clarification
https://docs.djangoproject.com/en/1.10/topics/serialization/#serialization-of-natural-keys
https://github.com/django/django/blob/master/django/core/serializers/base.py#L53

The default serializers always add the model and pk so that the data can be deserialized back into objects. Either you can write a custom serializer or can simply remove the unwanted data.
personal_details = [pd['fields'] for pd in personal_details]
This should give you a new list of dicts with personal details

Related

How to I return JsonResponse from Paginator's page? Object of type Page is not JSON serializable

(this is my first stackoverflow question ever)
I want to return JsonResponse from the dictionary "context" (seems to be a paginator Page)
as coded below:
myposts = userposts.all().values()
myfollowers = userfollowers.ffollowers.all()
myfollowings = userfollowers.ffollowings.all()
context = {"posts": page_obj,
"loops": range(1, totalpages + 1),
"user": uprofile.username,
"myposts": list(myposts),
"mypostsnum": len(userposts.all()),
"myfollowers": list(myfollowers),
"myfollowersnum": len(userfollowers.ffollowers.all()),
"myfollowings": list(myfollowings),
"myfollowingsnum": len(userfollowers.ffollowings.all())
}
this is the return I use:
return JsonResponse(context, safe=False)
Result I get:
Object of type Page is not JSON serializable
My question is how do I get JsonResponse from 'context'?
The problem is with "posts": page_obj. page_obj is an instance of a model. Like page_obj = Post.objects.get(pk=1).
JsonResponse will call json.dumps() on your context and is failing because it doesn't know how to handle a object.
I would recommend you to use Django rest framework for this. Serializers is used just for this problem.
You are trying to serialize querysets and django has predefined serializer that does the work.
from django.core.serializers import serialize
data = {
'context': serialize("json", context)
}
return JsonResponse(data)

How to process Ajax Data in Python (Django)

I want to push front end data (Form inputs) to the server via Ajax. For this, I created an Ajax post request but I'm very unsteady...
At my first attemps, I constantly receive errors by python
Ajax call:
//Get journey time for the stated address
jQuery.ajax({
type: 'post',
url: 'http://127.0.0.1:8000/termin/get-journey-time/',
data: {
'method': 'get_journey_time',
'mandant_id': 1,
'customer_address': customer_address,
'staff_group': staff_group_id
},
error: function (jqXHR, textStatus, errorThrown) {
console.log("Error")
},
timeout: 120000,
});
I've created a view in Python, in which I want to do something (views.py)
class get_journey_time(generics.ListAPIView):
"""
Handle Ajax Post to calculate the journey time to customer for the selected staff group
"""
permission_classes = (AllowAny,)
def post(self, request, *args, **kwargs):
print(request)
In my url route file I have this code lines (urls.py)
urlpatterns = [
XXXXXXXXXXXXXXXXXXXXXXXXX,
path('termin/get-journey-time/', views.get_journey_time.as_view()),
XXXXXXXXXXXXXXXXXXXXXXXXX,
XXXXXXXXXXXXXXXXXXXXXXXXX,
]
I got the Error code 500:
Expected a `Response`, `HttpResponse` or `HttpStreamingResponse` to be returned from the view, but received a `<class 'NoneType'>`
Is there a mistake in my approach, did I miss anything or is it completely crap?
Define renderer classes and parser classes in settings.py.
Note: You can define many of these (based on requirements and needs) but here we only need JSON related.
As a reference, you can check my repo's this file https://github.com/hygull/p-host/blob/master/src/pmt_hostel_app/views.py. I have used function based views, just ignore the code inside it and focus on request.data and also check related HTML files.
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES': (
'rest_framework.parsers.JSONParser',
),
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
)
}
In this way you will be able to access the posted data in the form of dictionary which can be obtained using request.data in views.
Finally, return Response from the post() method. By default return type of function/method is None and you are just printing the request.
Check the below mentioned links, it will help you a lot.
https://www.django-rest-framework.org/api-guide/renderers/
https://www.django-rest-framework.org/api-guide/parsers/
In client code, I mean in JavaScript code, define a success callback as well (you have just defined error callback).
Please comment, if you are stuck.
you can do it like this
from rest_framework.response import Response
from rest_framework.views import APIView
class get_journey_time(APIView):
# ListAPIView is used for read-only endpoints
#
"""
Handle Ajax Post to calculate the journey time to customer for the selected staff group
"""
permission_classes = (AllowAny,)
def post(self, request, *args, **kwargs):
# you can get the posted data by request.data
posted_data = request.data
data = {"test": "test"}
return Response(data)
you can get the posted data and use serializers. you can start learning playing with serializers from here
Example serializer code can be like this
from rest_framework import serializers
class DummySerializer(serializers.Serializer):
name = serializers.CharField()
mobile_number = serializers.CharField(required=False)
and then use it in post method of your get_journey_time class

Rendering django cms page as json

I have a django CMS page, I want the rendered html to be made into a json object(dump the CMS html into JSON), is this possible? I'd like it to look something like this:
How would I go about this?
So after some digging , this is what I managed.
CMS has a views.py which has a function "details(request, slug)"
I used this method to render the required page, by passing the slug of the page I need rendered , got the response and put it into a JSON object and returned this.
from cms.views import details
def index(request, topic):
if topic == 'home':
template = details(request, '')
else:
template = details(request, topic)
content = ''
if hasattr(template, 'render'):
# TemplateResponse must call render() before we can get the content
content = template.render().content
else:
# HttpResponse does not have a render() method
content = template.content
# Send JSON response
return JsonResponse({
'createdAt': datetime.datetime.now(),
'content': content
})
Any better way of doing the same?
I think this should be fairly easy. Instead of returning the rendered output from the template, put it in a dictionary. Then just from json import dumps or dump and dump(dictionary) / dumps(dictionary) depending on your purpose. dumps gives you a string. dump gives you something fancier.

How to send two variables with html as a JSON in Django?

I want to render two different HTML samples and send it back as response to ajax request.
I have something like this in my view:
def getClasses(request):
User = request.user
aircomcode = request.POST.get('aircompany_choice', False)
working_row = Pr_Aircompany.objects.get(user=User, aircomcode=aircomcode)
economy_classes = working_row.economy_class
business_classes = working_row.business_class
economy = render_to_response('dbmanager/classes.html', {"classes": economy_classes}, content_type="text/html")
business = render_to_response('dbmanager/classes.html', {"classes": business_classes}, content_type="text/html")
return JsonResponse({"economy": economy,
"business": business})
With this I get the error:
django.http.response.HttpResponse object at 0x7f501dc56588 is not JSON serializable"
How can I do my task?
In js when I get the response I would like to insert received HTML into corespoding blocks. Like this:
$.ajax({ # ajax-sending user's data to get user's classes
url: url,
type: 'post',
data: {"aircompany_choice": aircompany_choice}, # send selected aircompanies for which to retrieving classes required
headers: {"X-CSRFToken":csrftoken}, # prevent CSRF attack
}).done (result) ->
add_booking_classes.find(".economy-classes").children(":nth-child(2)").html(result["economy"])
add_booking_classes.find(".business-classes").children(":nth-child(2)").html(result["business"])
Try Django's render_to_string :
economy = render_to_string('dbmanager/classes.html', {"classes": economy_classes})
business = render_to_string('dbmanager/classes.html', {"classes": business_classes})
render_to_string() loads a template, renders it and then returns the resulting string. You can then send these resulting strings as JSON.
Your final code now becomes:
from django.template.loader import render_to_string
def getClasses(request):
User = request.user
aircomcode = request.POST.get('aircompany_choice', False)
working_row = Pr_Aircompany.objects.get(user=User, aircomcode=aircomcode)
economy_classes = working_row.economy_class
business_classes = working_row.business_class
economy = render_to_string('dbmanager/classes.html', {"classes": economy_classes})
business = render_to_string('dbmanager/classes.html', {"classes": business_classes})
return JsonResponse({"economy": economy,
"business": business})
render_to_response is, as the name implies, for rendering a response. You don't want to do that; you want to render two templates, and put them into a JSON response. So use render_to_string.
You can send one in your context and one as where you want to render.

How to get POST data from request?

I just set up an apache server with django, and to test it, made a very simple function in views.py
channel = rabbit_connection()
#csrf_protect
#csrf_exempt
def index(request):
data={'text': 'Food truck is awesome! ', 'email': 'bob#yahoo.com', 'name': 'Bob'}
callback(json.dumps(data))
context = RequestContext(request)
return render_to_response('index.html', context_instance=context)
This function works fine if I send a GET or POST request to the server. However I would like to get this data from POST request. Assuming I send request like this:
import pycurl
import simplejson as json
data = json.dumps({'name':'Bob', 'email':'bob#yahoo.com', 'text': u"Food truck is awesome!"})
c = pycurl.Curl()
c.setopt(c.URL, 'http://ec2-54-......compute-1.amazonaws.com/index.html')
c.setopt(c.POSTFIELDS, data)
c.setopt(c.VERBOSE, True)
for i in range(100):
c.perform()
What I would like to have in the view is something like this:
if request.method == 'POST':
data = ?????? # Something that will return me my dictionary
Just in case:
It is always will be in JSON format and the fields are unknown.
data= request.POST.get('data','')
Will return you a single value (key=data) from your dictionary. If you want the entire dictionary, you simply use request.POST. You are using the QueryDict class here:
In an HttpRequest object, the GET and POST attributes are instances of django.http.QueryDict. QueryDict is a dictionary-like class customized to deal with multiple values for the same key. This is necessary because some HTML form elements, notably , pass multiple values for the same key.
QueryDict instances are immutable, unless you create a copy() of them. That means you can’t change attributes of request.POST and request.GET directly.
-Django Docs
If the data posted is in JSON format, you need to deserialize it:
import simplejson
myDict = simplejson.loads(request.POST.get('data'))

Categories