Post data in djangon api and unable to get variable value - python

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.

Related

Enabling CSRF for Django

I have the following python code in my Django views.py, the code takes in a JSON body and send the extracted DATA to another API endpoint, I have simplified the code here.
How do I enable csrf such that it will send the token back to the caller for this method? I am calling this from postman.
#csrf_protect
def validate_booking(request):
if request.method != "POST":
return HttpResponseServerError("Invalid HTTP method")
body = json.loads(request.body)
booking_details = body["booking_details"]
DATA = {
"name": booking_details["name"],
"nric": booking_details["nric"],
"booking_id": booking_details["booking_id"]
}
return HttpResponse(status="200")
This site directs to put this piece of code in my method. But what is "a_template.html"?
https://docs.djangoproject.com/en/4.1/ref/csrf/
#csrf_protect
def my_view(request):
c = {}
# ...
return render(request, "a_template.html", c)
This isn't an easy thing to do as CSRF is 2 steps thing
There is a value that is passed to the client and it is saved to the session on the server.
When a POST request is received, the client shall send this as csrfmiddlewaretoken in the body and the server will check the value against the stored one in the server's session.
So this isn't feasible to be done in APIs as you require session Management which is not of REST API implementations.
Thanks for your reply. I managed to find a solution by doing the following:
Create a new GET method that will generate the session CSRF token using python
Instead of using render which expects a HTML template file, I used JsonResponse(data) to return in JSON format directly
In my postman app which I am making the POST request with the X-CSRFToken in the header, I will first make a GET request to the new method I created in step 1 to retrieve the token and store it as an environment variable
The following is the GET method sample:
from django.http import JsonResponse
def get_csrf_token(request):
csrf_token = csrf(request)['csrf_token']
data = {'csrf_token': csrf_token}
return JsonResponse(data)

Receiving POST data in Django from Vue

I am doing post request from vue and trying to collect the data in Django views But the part that receiving data in views isn't quite working.
here is views.py
from ..models import project
def insertProjects(request):
projectModel = project.Project()
if request.method == "POST":
#projectModel.project_id = request.POST.get("project_id")
#projectModel.project_name = request.POST.get("project_name")
#projectModel.company_name = request.POST.get("company_name")
#projectModel.save()
name = request.POST.get("project_name")
print(name)
return HttpResponse(True)
After vue POST request called. The print() is returns None? But request payload is not empty. And endpoint returns 200
Any idea about this problem? How can I solve this issue.
If your issue is because you are passing many elements in each key of your request and the view.py is handling only the last element of each key, you should try to use getlist:
project_name_list = request.POST.getlist("project_name")
for name in project_name_list:
projectModel.project_name = name

Django save data from calling api in views

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...

Twilio django send SMS and get answer using SMS as parameter

In the twilio example made in flask, I can send an SMS and receive an answer using text and the SMS as the search parameter in the database. I need make this but in a django project, my first option that I thought make a django view with a parameter using a url with for send the parameter, but I see that is bad idea because not is possible can use the text of SMS as parameter
This is a part of flask example
#app.route('/directory/search', methods=['POST'])
def search():
query = request.form['Body']
I need make some similar to that view in django using django restframework but how I can get the Body (I think that the body is the text send in the SMS)
for use this as parameter
Use request.POST to access the form data:
from django.shortcuts import render
def my_view(request):
if request.method == "POST":
data = request.POST
# all posted data
data['body']
# the rest of your view logic
return render(request, 'template.html', context)

Angular resource posts data but not receiving by django view

I have created an angular resource as
var services = angular.module('Services', ['ngResource']).
// SEND_REPLY_SMS
factory('SendSMS', ['$resource', function($resource){
return $resource('/bulk-sms/reply/', null,
{
send: {method: 'POST'},
}
);
}]);
I used it as
var data = $scope.data;
SendSMS.send({},data,
function(data){
console.log(data);
},function(error){
console.log(error);
}
);
I have checked with console.log(data), data contains the data and the browser shows that the post request has submitted the data.
But When I receive it in django view, I can not get the data in django view and my django view is
class ReplySMSView(View):
def post(self, request):
data = request.POST.copy()
print 'post data', request.POST # here data is not printed
data = dict(data.items())
return self.process(request, data)
def get(self, request):
data = request.GET.copy()
print 'get data', request.GET # here data is not printed
data = dict(data.items())
return self.process(request, data)
def process(self, request, data):
dct = {}
print data
model = IncomingMessage
account = request.user.account
contacts = data.get('contacts', '')
contacts = contacts if contacts else get_contacts_by_filter(model, data)
# TODO: get_contacts_by_filter is not working here for IncomingMessage
message = data.get('message', '')
identity = data.get('identity', '')
if not contacts:
dct['contacts'] = 'No contacts found.'
if not message:
dct['message'] = 'Message is required.'
if not identity:
dct['identity'] = 'Identity is required.'
if dct:
return HttpResponse(json.dumps(dct), content_type='application/json')
response = send_bulk_sms(contacts, message, identity, account, module='bulk')
return HttpResponse(response)
I am not getting where is problem in this code ?
AngularJS will post that data serialized into JSON, but django is expecting to receive form data. If you want to receive that data, you can change default behavior of AngularJS, fetch data not using POST, but rather request.body or you can use some third-party package, like Django REST framework to do job for you.
When calling ajax, you recieve encoded json string in request body, so you need to decode it using python's json module to get python dict.
As django is a web framweork, it expect data from a form.
I really reccomend using this framework http://www.django-rest-framework.org/
Anyway, to get post data will be like this in your view:
(Pdb) request.POST
<QueryDict: {}>
(Pdb) import json
(Pdb) json.loads(request.body)
{u'operator': u'pepe', u'password': u'1234', u'transport': u'LUUAAA'}
import json
class ReplySMSView(View):
def post(self, request):
data = json.loads(request.body)
print 'post data', request.POST # here data is not printed
data = dict(data.items())
return self.process(request, data)

Categories