Coming from Flask, request.args[key]
and request.form[key]
responds with 400 if the key doesn't exist. This has a nice property of failing fast.
In Django, request.GET[key]
and request.FORM[key]
raises HttpResponseBadRequest
if the key doesn't exist, which causes your API to respond with a 500 status if unhandled. I've seen other answers recommending request.GET.get(key)
, but that inadvertently loosens the API contract that could allow client-side bugs to slip by (e.g. a query parameter typo, forgetting to include a param, etc).
I could manually check for required query params:
arg1 = request.POST.get('arg1')
if not arg1:
raise HttpBadRequest('"arg1" was not provided.')
arg2 = request.POST.get('arg2')
if not arg2:
raise HttpBadRequest('"arg1" was not provided.')
arg3 = request.POST.get('arg3')
if not arg3:
raise HttpBadRequest('"arg3" was not provided.')
But that leaves a lot of room for error. (Did you notice the typo?)
I could manually handle HttpResponseBadRequest
:
def my_view(request):
try:
arg1 = request.POST['arg1']
arg2 = request.POST['arg2']
arg3 = request.POST['arg3']
except MultiValueDictKeyError as ex:
raise HttpBadRequest('"{}" was not provided.'.format(ex))
But now you have an extra thing to remember when writing views.
Compare the above examples to Flask's equivalent:
arg1 = request.form['arg1']
arg2 = request.form['arg2']
arg3 = request.form['arg3']
How can I write the same thing in Django without extra boilerplate in my views and have it respond with 400
when a param is missing?