28

The Django Rest Frameworks has this to say about POST, quoting a Django dev

Requests

If you're doing REST-based web service stuff ... you should ignore request.POST.

— Malcom Tredinnick, Django developers group

As not-so experienced web-developer, why is request.POST (standard) discouraged over request.DATA (non-standard)? Is one more flexible?

Community
  • 1
  • 1
AncientSwordRage
  • 7,086
  • 19
  • 90
  • 173

2 Answers2

33

The docs cover this:

request.data returns the parsed content of the request body. This is similar to the standard request.POST and request.FILES attributes except that:

  • It includes all parsed content, including file and non-file inputs.
  • It supports parsing the content of HTTP methods other than POST, meaning that you can access the content of PUT and PATCH requests.
  • It supports REST framework's flexible request parsing, rather than just supporting form data. For example you can handle incoming JSON data in the same way that you handle incoming form data.

The last two are the important ones. By using request.data throughout instead of request.POST, you're supporting both JSON and Form-encoded inputs (or whatever set of parsers you have configured), and you'll be accepting request content on PUT and PATCH requests, as well as for POST.

Is one more flexible?

Yes. request.data is more flexible.

Tom Christie
  • 33,394
  • 7
  • 101
  • 86
  • And are those ( Form-encoded inputs ) important? Why do I need the *content* of PUT and PATCH ? Doesn't DRF handle that? – AncientSwordRage Feb 16 '15 at 16:21
  • 4
    Django's `request.POST` *only* gives you support for POST requests with form encoded data. *If* you want to handle JSON, or *if* you want to make PUT and PATCH requests, then REST framework's `request.data` is what you want, yes. – Tom Christie Feb 16 '15 at 17:00
9

I think some users get redirected here when trying to get data from the POST body in vanilla Django (when they aren't using the Django REST framework). In case you're using a basic Django endpoint you use request.body to get data from the body of the request so long as it isn't form data that's being sent to the server (in that case use request.POST). This is different from the request.data attribute that is needed for accessing data with Django REST framework.

from json import loads
def login(request):
    json = loads(request.body)
    print(json['username']) # Prints the value associated with 

loads(request.body) is needed because request.body returns a byte string. loads will convert that byte string into a dictionary.

request.BODY, request.data, and request.DATA are all undefined for Django's default request object.

https://docs.djangoproject.com/en/3.1/ref/request-response/

Notice there is no .data attribute under HttpRequest which differs from the Django REST framework request.

(This doesn't answer the original question but might help users that end up here who aren't using the REST framework)

ICW
  • 4,875
  • 5
  • 27
  • 33
  • 1
    I appreciate this answer, but you don't link to a source. Is this now in the docs? – AncientSwordRage Oct 02 '19 at 18:15
  • Sorry, I just tested it on Django 2.2 and found that none of the properties other than `request.body` work. Went and found the docs just now, they're here: https://docs.djangoproject.com/en/2.2/ref/request-response/ – ICW Oct 02 '19 at 18:29
  • 1
    the question remains whether this change is reflected in the Django Rest Framework API. – AncientSwordRage Oct 02 '19 at 18:41
  • I am quite sure the accepted answer is still correct - since this is about Django Rest Framework? `request.data` is still the correct way in DRF. – Asmo Soinio Jan 25 '21 at 12:18
  • 1
    @AsmoSoinio Yep you are correct I'll change the answer thanks, sorry about that. – ICW Jan 25 '21 at 14:29