[Fixed]-Django Views: When is request.data a dict vs a QueryDict?


When your request content_type is “application/x-www-form-urlencoded”, request.Data become QueryDict.

see FormParser class.


QueryDict has get lists method. but it can’t fetch dict value.
convert name str to array.

<input name="items[name]" value="Example">
<input name="items[count]" value="5">  


And define custom form paser.

class CustomFormParser(FormParser):
Parser for form data.
media_type = 'application/x-www-form-urlencoded'

def parse(self, stream, media_type=None, parser_context=None):
    Parses the incoming bytestream as a URL encoded form,
    and returns the resulting QueryDict.
    parser_context = parser_context or {}
    encoding = parser_context.get('encoding', settings.DEFAULT_CHARSET)
    data = QueryDict(stream.read(), encoding=encoding)
    return parse_json_form(data.dict()) # return dict



Your test isn’t a reflection of your actual curl call.

In your test, you post JSON, which is then available as a dict from request.data. But your curl call posts standard form data, which is available as a QueryDict. This behaviour is managed by the parsers attribute of your view or the DEFAULT_PARSER_CLASSES settings – and further note that this is functionality specifically provided by django-rest-framework, not Django itself.

Really you should test the same thing as you are doing; either send JSON from curl or get your test to post form-data.

Leave a comment