Angular resource posts data but not receiving by django view - python

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)

Related

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

Post data in djangon api and unable to get variable value

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.

Test Django Forms submitted through Ajax view

I I'm trying to test a view that is used by Ajax. While with the server (manual testing) everything works, when I ran my unit test an error I can't explain appears.
If you take a look at the following lines, where I present my code the most simplified as possible, you will see that although I add a variable to the json dict named something (just as I do in ajax) the field appears as missing in the form.
My Test (tests.py):
def test_edit_profile_user(self):
self.user = User.objects.create_user(
username='user', email='test#awesome.org', password='top_secret')
self.client.login(username=self.user.username, password='top_secret')
data = {'something': 'data'}
response = self.client.post(reverse('edit_something'),
json.dumps(data),
content_type='application/json',
HTTP_X_REQUESTED_WITH='XMLHttpRequest')
print(response.content)
self.assertEqual(response.status_code, 200)
While my Ajax view works, my test gives the following traceback:
b'{"something": ["This field is mandatory."]}'
Failure
Traceback (most recent call last):
File "***\tests.py", line 81, in ***
self.assertEqual(response.status_code, 200)
AssertionError: 400 != 200
What am I doing wrong in the test?
The rest of the code:
My view (views.py):
def edit_something(request):
if request.method == 'POST':
form = CustomForm(request.POST)
if form.is_valid():
form.save()
response_code = 200
response_data = {'something':'updated')
else:
response_code = 400
response_data = form.errors
return JsonResponse(
response_data,
status=response_code,
)
My JS (something.js):
$.ajax({
url : form_endpoint, // the endpoint
type : "POST", // http method
data : {
something: 'data',
},// data sent with the post request
And code to handle the response
I hope I get a better solution, but for now, my solution was to remove content_type and post a dictionary.
In tests.py the code for the var response is:
response = self.client.post(reverse('edit_something'), data)
This makes the view receive the appropriate values, while when I add content_type='application/json' the view request.POST is empty.

Serializer.is_valid() is always False

I have the following Serializer to handle a user:
class FriendSerializer(serializers.Serializer):
login = serializers.CharField(max_length=15, required=True)
password = serializers.CharField(max_length=15, required=True)
mail = serializers.CharField(max_length=50, required=True)
Currently, my view which processes the POST request to register a new user is, based on the Django REST tutorial:
#api_view(['POST'])
def register_new_user(request):
if request.method == 'POST':
print('POST request !')
stream = BytesIO(request.body)
data = JSONParser().parse(stream)
print(data)
serializer = FriendSerializer(data=data)
print(serializer.is_valid())
else:
print('Not a POST request!')
return HttpResponse('Nothing')
Thus, to simulate a client with a POST request, I use the following lines:
import requests
import json
json_data = json.dumps({'login': 'mylogin', 'password': 'mypassword', 'mail': 'mymail'})
r = requests.post('http://127.0.0.1:8000/register_new_user', json=json_data)
However, although the print(data) retrieves, as expected,
{"login": "mylogin", "mail": "mymail", "password": "mypassword"}
The serializer.is_valid() always returns False.
Am I missing any processing of my request?
EDIT:
I got the following info with serializer.errors:
{'non_field_errors': ['Invalid data. Expected a dictionary, but got str.']}
You dont have to convert a dictionary to string when using requests library's json option. This should work:
import requests
data = {'login': 'mylogin', 'password': 'mypassword', 'mail': 'mymail'}
r = requests.post('http://127.0.0.1:8000/register_new_user', json=data)
The solution is to use ast.literal_eval(request.data) to convert the string to a dictionary. I use request.data instead of manually parsing request.body.
However, v1k45's answer is the best solution, as I do not need to convert my dict to a string before sending my request.

Django: send json response from view to a specific template

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

Categories