It was one of the issues in DRF(django-rest-framework) you can check on GitHub of Tom Christie. Issue was closed with the solution given below. You can also find same solution on issues page of djang-rest-framework repository
For various reasons, Django only allows reading POST body once. Since the body is exposed with a file-like API, you can't easily read the file again. Also, you won't be able to change upload file handlers if you have already read the data. Failing to read POST data only once will fail, and it is tricky to debug for two reasons.
- Django only reports its error the second time you access the body, so
it can be difficult to track the first time it was accessed.
- A myriad of different issues may cause this. One way is to print the
full traceback (with
traceback.print_stack())
whenever the data gets
read (in django/http/request.py
: HttpRequest.read
and
HttpRequest.readline
). This is how I did it, maybe there are other
ways.
So, did you access request.method somewhere in your code? Are you using Django test client? If so, it's possible that HTTP header based method overriding kicked in. This feature allows browsers to simulate requests other than GET/POST. To do so, django-rest-framework looks at hidden form fields such as <input type="hidden" name="_method" value="DELETE">
. With POST requests, this information is in the request body, so django-rest-framework will have to read the request body.
This feature is enabled by default, but django-rest-framework ensures that the
request is indeed POST and is indeed using a Content-Type that would
be sent on a form submission.
But that's exactly the behavior of Django test client! Two possible fixes exist:
Disable browser overrides
REST_FRAMEWORK = {
'FORM_METHOD_OVERRIDE': None,
'FORM_CONTENT_OVERRIDE': None,
'FORM_CONTENTTYPE_OVERRIDE': None
}
Change the Content-Type in Django test client
from django.test import Client
client = Client()
response = client.post(url, content_type='application/json')