Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Forms - Processing GET Requests

We have an existing Django form that accepts GET requests to allow users to bookmark their resulting query parameters. The form contains many fields, most of which are required. The form uses semi-standard boilerplate for handling the request, substituting GET for POST:

if request.method == 'GET':
   form = myForm(request.GET)
   if form.isValid()
      # Gather fields together into query.
else
   form = myForm()

The problem is that the first time the form is loaded, there's nothing in the GET request to populate the required fields with, so most of the form lights up with 'missing field' errors.

Setting initial values doesn't work; apparently, the non-existent values in the GET request override them.

How can we avoid this? I'm pretty certain we're simply not processing things correctly, but I can't find an example of a form that handles GET requests. We want errors to show up if the user hits the "Submit" button while fields are blank or otherwise invalid, but don't want these errors showing up when the form is initially displayed.

like image 442
SixDegrees Avatar asked Feb 23 '23 22:02

SixDegrees


1 Answers

The positional argument to the forms.Form subclass informs Django that you intend to process a form rather than just display a blank/default form. Your if request.method == 'GET' isn't making the distinction that you want because regular old web requests by typing a URL in a web browser or clicking a link are also GET requests, so request.method is equal to GET either way.

You need some differentiating mechanism such that you can tell the difference between a form display and a form process.

Ideas:

If your processing is done via. AJAX, you could use if request.is_ajax() as your conditional.

Alternatively, you could include a GET token that signifies that the request is processing. Under this example, first you'd need something in your form:

<input type="hidden" name="action" value="process_form" />

And then you can look for that value in your view:

if 'action' in request.GET and request.GET['action'] == 'process_form':
    form = myForm(request.GET)
    if form.is_valid():
        # form processing code
else:
    form = myForm()

I'll also give you the standard, boilerplate point that it's generally preferable not to use GET for form processing if you can help it (precisely because you run into difficulties like this since you're using an anomalous pattern), but if you have a use case where you really need it, then you really need it. You know your needs better than I do. :-)

like image 68
Luke Sneeringer Avatar answered Feb 25 '23 11:02

Luke Sneeringer