Django Views not getting POST Data from api call - python

I am not using django rest frame work
but in normal views.py I have a simple views
#views.py
def api_post_operations(request):
pdb.set_trace()
if request.POST:
print(request.POST["name"])
print(request.POST["address"])
now I call it
import requests
url = "http://localhost:8000/api_post_operations"
payload = {"name":"raj", "address": "asasass" }
rees = requests.post(url, data=payload, headers={})
it is comming
(Pdb) request.POST
<QueryDict: {}>
Any reason why it is comming {} balnk
request.body also comming blank

Related

Django testing post request with multipart/form data and a dictionary

My client uses the requests library to make this call to my Django server
import requests
response = requests.post(url, files=dict({
'value': 'key',
}))
This will create a requests that inserts the dictionary into the field request.FILES as a <MultiValueDict: {}>
I am trying to recreate this with django.test.
I keep seeing to try something like
from django.test import TestCase, Client
client = Client()
response = client.post('/sign', dict(request_data))
but the request.FILES object is empty
edit ----
I have also tried with the same result ( request.FILES -> <MultiValueDict: {}>)
client.post('/sign', {'file': dict({
'key' : 'value'
})})
Edit 2---
A look at the midldleware where I am checking the value
class ApiAuthenticationMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request: HttpRequest):
print(request.FILES)
Solution
fake_file.name = 'data.json'
post_data = {
'data.json': fake_file,
}
return self.client.post('/sign', post_data, content_type=MULTIPART_CONTENT)

Djoser user activation email POST example

I am using the Django rest framework and Djoser for Authentication and User Registration.
When a new user registers, Djoser sends an activation email with a link that does a GET request. In order to activate, I need to extract the uid and token from the activation URL and make a POST request for Djoser to be able to activate the user.
My environment is Python 3 and Django 1.11, Djoser 1.0.1.
What I would like to do is to handle the get request in Django, extract the uid and token, and then make a POST request. I have extracted the uid and token and would like to make a POST (within this GET request).
I do not know how to make this POST request in the background.
My URL is like this:
http://127.0.0.1:8000/auth/users/activate/MQ/4qu-584cc6772dd62a3757ee
When I click on this in an email it does a GET request.
I handle this in a Django view.
The view needs to make a POST request like this:
http://127.0.0.1:8000/auth/users/activate/
data= [(‘uid’=‘MQ’), (‘token’=‘4qu-584cc6772dd62a3757ee’),]
My view to handle GET is:
from rest_framework.views import APIView
from rest_framework.response import Response
import os.path, urllib
class UserActivationView(APIView):
def get (self, request):
urlpathrelative=request.get_full_path()
ABSOLUTE_ROOT= request.build_absolute_uri('/')[:-1].strip("/")
spliturl=os.path.split(urlpathrelative)
relpath=os.path.split(spliturl[0])
uid=spliturl[0]
uid=os.path.split(uid)[1]
token=spliturl[1]
postpath=ABSOLUTE_ROOT+relpath[0]+'/'
post_data = [('uid', uid), ('token', token),]
result = urllib.request.urlopen(postpath, urllib.parse.urlencode(post_data).encode("utf-8"))
content = result.read()
return Response(content)
views.py
from rest_framework.views import APIView
from rest_framework.response import Response
import requests
class UserActivationView(APIView):
def get (self, request, uid, token):
protocol = 'https://' if request.is_secure() else 'http://'
web_url = protocol + request.get_host()
post_url = web_url + "/auth/users/activate/"
post_data = {'uid': uid, 'token': token}
result = requests.post(post_url, data = post_data)
content = result.text
return Response(content)
urls.py
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^auth/users/activate/(?P<uid>[\w-]+)/(?P<token>[\w-]+)/$', UserActivationView.as_view()),
]

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.

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