Often one initializes a form with:
def someview(request):
form = MyForm(request.POST or None)
# …
This is often used to construct a form for both the GET and the POST request since it seems to make things shorter.
Why is it a problem?
Although it is common, a POST request does not
per se has content. The or
operator evaluates the truthiness of the
request.POST
operand, and if it is
False
, it will take the right operand (so
None
). This means that even if it is a POST
request, it will take None
, and thus as
result the form is not bounded.
If the form is not bounded, then
form.is_valid()
will return
False
, even if an empty
QueryDict
for request.POST
was
a valid request.
What can be done to resolve the problem?
We can branch based on the request method,
and use request.POST
in case of a POST
request:
def someview(request):
if request.method == 'POST':
form = MyForm(request.POST, request.FILES)
# …
else:
form = MyForm()
# …