On Fri, Dec 30, 2016 at 01:50:51PM -0800, Flávio Cardoso wrote:
> Hello! I'm getting crazy, PLEASE someone, give me some light!!!
> 
> I'm using Django 1.10.4, Python 3.5 on Windows using Visual Studio 
> Community 2015.
> 
> I have some class-based views to response some json.
> 
> from django.views.generic import View
> from json import loads
> from bson.json_util import dumps
> from django.http import HttpResponse, HttpRequest
> 
> class Topicos(View):
>    def post(self, request):
>        req = request.read().decode(self.request.encoding)
> 
> Have the following setting on urls.py:
> 
> url(r'^api/Topicos', Topicos.Topicos.as_view(), name='Topicos'),
> 
> The request.read() is empty, the request is: 
> 
> POST /api/Topicos HTTP/1.1
> Host: localhost:55020
> Connection: keep-alive
> Content-Length: 93
> Accept: application/json, text/plain, */*
> Origin: http://localhost:55020
> User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 
> (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36
> X-CSRFToken: 
> VRiCt3Lz1EIdKGWt3lknpcgdFpD8XbrwSxdPT4P9dd1tbrGYmgE8uHdEIH2dzP5h
> Content-Type: application/json;charset=UTF-8
> Referer: http://localhost:55020/
> Accept-Encoding: gzip, deflate, br
> Accept-Language: pt-BR,pt;q=0.8,en-US;q=0.6,en;q=0.4
> Cookie: 
> csrftoken=VRiCt3Lz1EIdKGWt3lknpcgdFpD8XbrwSxdPT4P9dd1tbrGYmgE8uHdEIH2dzP5h
> 
> {"titulo":"Título 1","mensagem":"mensagem","email":"fla...@email.test
> .br","usuario":"Flávio"}
> 
> 
> I really don't know what else I can do. I have the same code (except na 
> class name) running correctly to another posts.

Hi Flávio,

The behavior of request.read() is somewhat icky, and there are some
caveats when trying to use it. Let me give you a lengthy answer
starting from the basics down to the nasty corner cases that you're
likely encountering.

Basically, there are several interfaces that make it possible to
access the request body:

1. request.POST, and request.FILES – these two are the most high-level
   easy-to-use dict-like objects that automatically attempt to parse
   the request body, but they only support multipart/form-data and
   application/x-www-form-urlencoded requests, otherwise they will be
   empty.

2. request.body loads the entire request body into memory on first
   access, and stores it as a bytestring in an attribute. This is good
   for relatively short requests that fit into memory, if they aren't
   URL-encoded or multipart (most commonly JSON or XML).

3. Finally, there's request.read(), request.readline(), iteration, and
   some other file-like methods intended for requests that are too
   large to fit into memory, which means you need to process them in a
   streaming fashion. This means that once you start using this
   interface, it is no longer possible to access the part of the
   request body that has already been consumed.

Now, an obvious, but not very helpful answer to your question would be
that the request body has already been consumed through request.read
or another file-like access before your call, which means any
subsequent calls to read() or attempts to iterate will return an empty
result.

How could this happen? There are many possibilities, but the most
likely ones are that it's a middleware triggering a read, that your
view is decorated by a decorator that triggers a read, or that one of
the superclasses is responsible. I'd recommend that you consider these
three possibilities first, and look through all applicable
middlewares, decorators and superclasses.

Now, what do you have to look for? Any iteration of the request, calls
to read, readline, readlines, or xreadlines. However, that's not all,
because even just accessing request.POST or request.FILES might under
certain circumstances also have the same effect, although that should
only apply to multipart requests.

It's hard to give you any more specific advice, because the issue is
not in the piece of code that you have posted (which is also probably
the reason why you didn't get any responses to the original question).

However, when dealing with JSON requests, it's usually a better idea
to just use request.body, rather than request.read(), specifically to
avoid this kind of problems. If trying to read request.body is raising
a RawPostDataException on you, complaining that you cannot access body
after reading from request's data stream, that means you need to look
at any code that's executed before that line and track down what is
performing that read earlier.

Good luck...

Michal

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/20170104205348.GF1628%40koniiiik.org.
For more options, visit https://groups.google.com/d/optout.

Attachment: signature.asc
Description: Digital signature

Reply via email to