request.POST.get() always returning None - django

I am completely new to django , you can I just started it today
when I am making a POST request with parameters using postman , I am always getting None for email,password, name and other variables
#csrf_exempt
def signup(request):
if request.method != 'POST':
raise Http404
email = request.POST.get('email')
password = request.POST.get('password')
name = request.POST.get('name')
os = request.POST.get('os')
device_id = request.POST.get('device_id')
version = request.POST.get('version')
device = request.POST.get('device')
print "email value is = %s", email
user=AppUser.objects.get_or_create(email=password,password=password)
user.save()
return HttpResponse(json.dumps({"result": True}), content_type='application/json')
Please help , Why it is always showing None even though I am passing values from POST request for email and for other parameters
Below is the body request from post man using POST
http://127.0.0.1:8000/v1.0/signup/?email=nagu#nagu.com&password=nagendra&name=nagendra&os=android&device_id=12345678&version=23.0.1&device=samsung
below postman screen shot

The parameters you added to the url are GET parameters not POST parameters. POST parameters are in the request body and not visible through urls. Even you specify your request method is POST with your original url, you are not going to send any data.
If you in your commandline do something like:
curl --data "email=nagu#nagu.com&password=nagendra&name=nagendra&os=android&device_id=12345678&version=23.0.1&device=samsung" http://127.0.0.1:8000/v1.0/signup/
It should send POST data to your view.
Take a look at this SO question and answer on how POST requests are delivered.

I have tried postman in chrome.
Below is the screenshot.
Does this work for you?

please make sure your parameter of body in postman is correct, it
should be "x-www-form-urlencoded".
THKS!

check your header
you probably may have
Content-type set to application/json

Related

Django - RawPostDataException: You cannot access body after reading from request's data stream

I'm really stuck at this problem for a couple of days now.
While I understand, what's happening here, I don't really know the best workaround/solution for this.
Problem:
I'm trying to create a user login endpoint using Django and DRF in general.
My login API needs to support a login via password as well as login via OTP.
My LoginView looks like:
def post(self, request, **kwargs):
"""
post
Method to handle user login
:param request:
:param args:
:param kwargs:
:return:
"""
request_data = request.data
login_using_password = request_data.get('login-with-password') is True
login_using_otp = request_data.get('login-with-otp') is True
if request_data is not None:
if all((login_using_password, login_using_otp)):
raise accounts_exceptions.InvalidLoginRequestError()
if login_using_password:
return Response(self._login_with_password(request))
elif login_using_otp:
return Response(self._login_with_otp(request))
raise accounts_exceptions.InvalidLoginRequestError()
return Response(self._login_with_password(request))
Also my _login_with_password looks like:
def _login_with_password(self, request, **kwargs):
"""
_login_with_password
A utility method to handle login with password
:param request:
:return:
"""
return getattr(ObtainJSONWebToken.as_view()(request=request._request, ), 'data')
When I try to login, Django complains saying RawPostDataException You cannot access body after reading from request's data stream
I'm using JWT to authenticate requests. ObtainJSONWebToken is a view provided by DRF-JWT to obtain access tokens to authenticate requests.
What is the workaround/solution for this?
Is there a better way to support such a login requirement?
Thanks in advance!
Resolved this.
There's no concrete way to solve the problem above.
Django disallows access to request.data multiple times.
It could be done only once for the entire request lifetime.
So, this left me with two solutions:
Move my request payload to query params.
Move my request payload to url context.
I ended up using a mix and match of both.
So, basically I used request.query_params and self.context to fetch data from the request and changed my URL and request structure accordingly.

How to parse request in django

Hi i am making an webserver , In which I have to hit some request from html page and return the response. The URL which is generated using html is
http://192.168.2.253:8080/searchSMS/?KPImsgId=0&circle=&subId=&startDate=DD-MM-YYYY&endDate=DD-MM-YYYY&Username=ashish
but in the server side I am not able to see the request data. I am using
q = QueryDict(request.body) but it is showing <QueryDict: {}>
How to find the all the parameters coming in request.
In your case you send the data in url so access the data through request.GET as follow:
username = request.GET.get('Username')
start_date = request.GET.get('startDate')
# ... the same for all the other parameter after the `?` marque.
In fact there is a difference between request data, request.body, request.GET and request.POST:
If you are sending POST request to django function view or class based view: you access the request data in request.body or request.POST.
If you are sending POST request to Django REST Framework: you access the data in request.data. You may also find in Internet request.DATA that correct but it's deprecated in the newer version of DRF in favor of request.data.
If you send parameter in the url like in you case, you access the data form request.GET as explained above.

Django comments CSRF error

Getting a csrf error I cant figure out how to fix, i have rest auth working, user is able to update their details like so:
but with Django Comments i get this csrf error using the same csrf token Error:
I would like to get rid of this error on the /comments/post/ endpoint, such that this endpoint behaves similar to /rest-auth/user/ view which accepts an "Authorization: Token 792b5fb27b4fe805e895c91274f26b6ab13cb654" header field to relevant provide data to the authenticated user.
The following is an exert of the csrf related decotaros on the respective views shown in the screen shots:
From the /comments/post/ endpoint
#csrf_protect
#require_POST
def post_comment(request, next=None, using=None):
# Fill out some initial data fields from an authenticated user, if present
data = request.POST.copy()
if request.user.is_authenticated():
if not data.get('name', ''):
data["name"] = request.user.get_full_name() or request.user.get_username()
if not data.get('email', ''):
data["email"] = request.user.email
From the /rest-auth/user/ endpoint
#api_view(['GET'])
#permission_classes((IsAuthenticated, ))
def get_user(request, **kwargs):
pk = request.data['pk']
user = MyUser.objects.get(pk=pk)
serializers = UsersSerializer(user)
return Response(serializers.data)
You're using the wrong content type. Please change it into application/json and try again.
The decorators for your endpoints are different, thus you need to adjust the headers accordingly.
For your /rest-auth/ view the WWW-Authenticate header is required as mentioned here.
The comments view /comments/ endpoint has the csrf_protect decorators which means that the header must match the csrf-token returned in the cookie,as Fede mentions in your header you only require 'X-CSRFToken' with the matching value from the cookie.
I think you are using django-rest-framework which comes with the csfr token exempt by default, but postman is sending a csfr token that is why you are getting that error.
cleaning the cookies might solve the problem.

How can I change the http request from Post to Get in Django?

Suppose I have a view which will take a POST request. After the validation check pass, I need to redirect the request to another HTML/view with a request with GET method:
def view1(request):
if request.POST:
form = TempForm(request.POST)
if form.is_valid():
return redirect(request, 'view2')
def view2(request):
if request.POST:
#POST stuff here
else:
#GET stuff here
My problem is that after the form.is_valid(), the redirect request will be passed as a POST method. My ultimate goal is to redirect the view2 with GET method.
Can I do such thing in Django?
You can use an HttpResponseRedirect class to redirect to any URL you like. Since it's a redirect, the request will be a GET request (POST isn't possible with http redirect - that's a restriction of the http protocol).
If you need to add GET parameters you could simply create the GET string yourself -
get_string = "?"
get_strint += "my_param=" + my_variable + "&"
get_string += "my_other_param=" + my_other_variable
return HttpResponseRedirect('/my_url/' + get_string)
The user agent (the browser) decides if it gets redirected with POST or GET. Most browsers will switch from POST to GET if they get redirected. The only way I know you can get redirected and stay in POST is if you do it explicitly, such as with curl -X POST.
http://en.wikipedia.org/wiki/Post/Redirect/Get

How to receive POST data in django

I've been trying to integrate a payment gateway into my site in django.
I'm having trouble getting the response data from the payment gateway.
The payment gateway has sample docs for php which looks like this :
$ErrorTx = isset($_POST['Error']) ? $_POST['Error'] : ''; //Error Number
$ErrorResult = isset($_POST['ErrorText']) ? $_POST['ErrorText'] : ''; //Error message
$payID = isset($_POST['paymentid']) ? $_POST['paymentid'] : ''; //Payment Id
In the view for the url that the payment gateway is redirecting to after entering card details etc, I'm checking if it's a GET if request.method == "GET" and then passing the request to a function. When I debug the request, I can see an empty query dict. and if I try something like res = request.GET['paymentid'] I get an error that says there's no key called paymentid.
Am I missing something obvious? I'm still pretty new to django, so I'm sure I'm doing something wrong.
res = request.GET['paymentid'] will raise a KeyError if paymentid is not in the GET data.
Your sample php code checks to see if paymentid is in the POST data, and sets $payID to '' otherwise:
$payID = isset($_POST['paymentid']) ? $_POST['paymentid'] : ''
The equivalent in python is to use the get() method with a default argument:
payment_id = request.POST.get('payment_id', '')
while debugging, this is what I see in the response.GET: <QueryDict: {}>, request.POST: <QueryDict: {}>
It looks as if the problem is not accessing the POST data, but that there is no POST data. How are you are debugging? Are you using your browser, or is it the payment gateway accessing your page? It would be helpful if you shared your view.
Once you are managing to submit some post data to your page, it shouldn't be too tricky to convert the sample php to python.
You should have access to the POST dictionary on the request object.
for class based views, try this:
class YourApiView(generics.ListAPIView):
"""
API endpoint
"""
def post(self, request, *args, **kwargs):
print("request data")
print(request.data)