I'm studying Django Rest Framework. I understand what is Django content negotiation, and the use of the Response function. In an example I've seen a code like:
def func(request):
if request.method == "GET":
queryset_objects = //
serializer = FooSerializer(queryset_objects, many = True)
return Response(serializer.data)
This function will render a JSON. But the only parameter passed to Response is a dictionary like type (serializer.data). How Render decide that the response must be a JSONN instead another type (without header)?
Related
So i have a views which have a Get and Post request that call to another django project API. But i want to also save the information that i get from the api call.
Project 1 has a Appointment table which has these field clinic Id, time, and queueNo. When i do a Post request to Project 2 to make/create an appointment, when successfully created, it will display those 3 field which i want to save into Project 1 Appointment table database. How do i do it ? My Appointment also has a API made so how do i save it there?
Here is the code for my view to call api to another django project
views.py
#csrf_exempt
def my_django_view(request):
if request.method == 'POST':
r = requests.post('http://127.0.0.1:8000/api/test/', data=request.POST)
else:
r = requests.get('http://127.0.0.1:8000/api/test/', data=request.GET)
if r.status_code == 200:
# r.text, r.content, r.url, r.json
return HttpResponse(r.text)
return HttpResponse('Could not save data')
Assuming your endpoint in Project 2 returns a JSON response with the fields that you need:
{
"clinicId": 1,
"time": some-time-string,
"queueNo": 2
}
You can retrieve the response after making the request by calling r.json().
Based on this you can then treat r.json() as a dictionary and create the instance using Appointment.objects.create(**r.json()). Here's how it might look.
#csrf_exempt
def my_django_view(request):
if request.method == 'POST':
r = requests.post('http://127.0.0.1:8000/api/test/', data=request.POST)
else:
r = requests.get('http://127.0.0.1:8000/api/test/', data=request.GET)
if r.status_code == 200 and request.method == 'POST':
# Convert response into dictionary and create Appointment
data = r.json()
# Construct required dictionary
appointment_attrs = {
"clinicId": data["some-key-that-points-to-clinicid"],
"time": data["some-key-that-points-to-time"],
"queueNo": data["some-key-that-points-to-queue-num"]
}
appointment = Appointment.objects.create(**appointment_attrs)
# r.text, r.content, r.url, r.json
return HttpResponse(r.text)
elif r.status_code == 200: # GET response
return HttpResponse(r.text)
return HttpResponse('Could not save data')
You first have to extract the data from the responses.
If you're using the requests library and the API you're calling is responding in JSON, you can do something like data = r.json().
I don't know the structure of your second API's responses, though, but I assume you can then get your fields from the data object.
Then it's a matter of saving what you want with whatever database interface you're using. If it's the django ORM, and you have an Appointement model somewhere, you can do something like
Appointment(
clinic_id=data["clinic_id"],
time=data["time"],
queueNo=data["queueNo"]
).save()
and you're done...
I have created a api which i am sending request by post but didn't get vairable in a view
def login_list(request):
if request.method == 'POST':
data = json.dumps(request.POST)
print(data)
serializer = LoginSerializer(data=request.data)
#print(serializer)
return JsonResponse({"message":'fdsafdsa'})
when i print data print(data) then out put is coming like this
{"{\"login\":122122,\"abvc\":\"544545\"}": ""}
and i calling this api like this in postman
Post http://localhost:8000/login/login/
{"login":122122,"abvc":"544545"}
I am not geting value with this
print(request.POST['login']);
how can i get value
Try request.data instead of request.POST. JSON Content is sent in body, which is parsed by Django Rest Framework at runtime.
login_variable = request.data['login']
And ensure you have added 'JSONParser' in REST_FRAMEWORK settings.
I'm new in web dev and I'm trying for a project to develop a Restful web api and a website. I'm using Django framework and following tutos, I always see html files as static and the different views rendering an html template. This way of doing seems to me as backend and frontend are not much separated. Is it possible to have backend only developed in Django ?
edit:
I have actually a problem more specific. I having this app (records) with a view having "patient_list" using Response class from REST framework that renders some data and an html template like this:
def patient_list(request):
"""
List all records, or create a new .
"""
if request.method == 'GET':
#data = Patient.objects.all()
data= Patient.objects.all()
#serializer = PatientSerializer(data, many=True)
#return JSONResponse(serializer.data)
return Response({'patients': data}, template_name='records.html')
in my urls.py I have:
url(r'^records/$', views.patient_list),
and here I'm a little confused. Suppose one called this /records, so patient_list is called and will response with an html page. From what I understood (maybe wrong), a restful API should renders data in a standard view so that it can be used from any "frontend" (html pages or mobile app). Is this statement correct ? am I doing it wrong using Response with an html template ?
With Vanilla Django
Of course it's possible, and without any additional libraries to Django.
E.g. You can define a Django view that returns JSON data instead of rendering it into a HTML template server-side. Effectively making an API instead of a "website".
Here's an example with a class-based view that accepts GET requests and returns some JSON data with JsonResponse
from django.views.generic import View
from django.http import JsonResponse
class MyView(View):
def get(self, request):
my_data = {'something': 'some value'}
return JsonResponse(my_data, mimetype='application/json')
As you can see, you don't have to use the HTML rendering facilities in Django, they're there only if you want to use them.
With REST libraries
And of course there is a host of libraries to build RESTful APIs with Django, like Django REST Framework and Tastypie
Multiple representations and content negotiation
Content negotiation is the process of selecting one of multiple possible representations to return to a client, based on client or server preferences.
You can support more than one format in your REST API. E.g. you can support both HTML and JSON formats. There are various ways to do this:
You may use a GET param ?format=JSON (and have it default to HTML e.g.)
You may use Accept headers
You may have two URLs /records.html and /records.json (the format suffix method)
More on this topic in DRF's documentation
E.g. if you were to implement the first method with the GET params you could modify your code this way:
if request.method == 'GET':
data = Patient.objects.all()
format = request.GET.get('format', None)
if format == 'JSON':
serializer = PatientSerializer(data, many=True)
return JSONResponse(serializer.data)
else:
# Return HTML format by default
return Response({'patients': data}, template_name='records.html')
I have a translation engine api made using Django Python and it has a function that I want to be made into a class based view:
def i18n_newkey(rin):
request = Request(rin, JSONParser())
if request.method == 'POST':
data = json.loads(rin.body)
.... # Parsing and other code here and finally,
return JSONResponse(kdata)
Where the JSONResponse is an HttpResponse that renders it's content into JSON.
My url: url(r'^savekey', 'i18n_newkey'),
I'm new to django and I wanted to convert my function based view to class view, I've read the Django Documentation but I cannot seemed to dig it in this particular code.
Thanks!
Seems like JsonRequestResponseMixin will do exactly what you want.
How to pass django restframework response for any request to html.
Example: A list which contains objects, and html be articles.html.
I tried by using rest framework Response :
data= {'articles': Article.objects.all() }
return Response(data, template_name='articles.html')
I am getting this error :
""" AssertionError at /articles/
.accepted_renderer not set on Response """
Where i went wrong, please suggest me.
If it's a function based view, you made need to use an #api_view decorator to display properly. I've seen this particular error happen for this exact reason (missing API View declaration in function based views).
from rest_framework.decorators import api_view
# ....
#api_view(['GET', 'POST', ])
def articles(request, format=None):
data= {'articles': Article.objects.all() }
return Response(data, template_name='articles.html')
In my case just forgot to set #api_view(['PUT']) on view function.
So,
.accepted_renderer The renderer instance that will be used to render the response not set for view.
Set automatically by the APIView or #api_view immediately before the response is returned from the view.
Have you added TemplateHTMLRenderer in your settings?
http://www.django-rest-framework.org/api-guide/renderers/#setting-the-renderers
You missed TemplateHTMLRenderer decorator:
#api_view(('GET',))
#renderer_classes((TemplateHTMLRenderer,))
def articles(request, format=None):
data= {'articles': Article.objects.all() }
return Response(data, template_name='articles.html')