Specifying the request method in the `url` tag.

I would like to know if it is possible to specify whether a request method can be specified in the url tag {% url 'some_view' %}

My use case is after submitting a form, I have a button that takes the user to another view that displays the data in a processed manner and then have a button on that page to go back to the forms page. With the above url tag, it just makes a GET request and the form data is lost.

Ideally, I’d like to retain the already present data in the form.

Any pointers would be appreciated. Thanks !

Three options that I can think of are:

  • Serialize the form into the querystring and attach it at the end of the {% url %} tag with something like {% url ... %}?{{ form_querystring }} You could do it all in the template, but it might be cleaner and easier to test if you serialize the submission in the view. Keep in mind that this will expose all of the data in the url when they go back.
  • Make the button submit a hidden form. Here you’d render all of the values as hidden inputs, change the button to submit the form and set the action attribute for the form to the previous url. That way, the user makes a POST to get back to the previous page and avoids exposing the data in the URL.
  • Store the data in the session, database or some other server side persistent store.

If the data has some sensitive information that you don’t want leaked via the URL, go with the POST. If it’s filtering and search values, similar to what the Django Admin does I’d choose the GET and querystring approach.

The reason I’m not a fan of storing it in the session is that session logic can be hard to debug. If the request has all the data you need to render the response, bugs are easier to track down and fix.

Any reading material on this ? I am not new to Django but I don’t know how to serialize a form (or rather what serializing a form means)

I just wanted to add the clarification here that the URL tag has nothing to do with the request method. It just renders as a string. The request method is dependent upon the HTML element / JavaScript that invokes the URL. For example, an a tag is going to create a GET, while the submit button of a form would generate a POST. With JavaScript you can invoke a URL using any verb you choose.

Serialization is taking data or an object and translating it into a format that can be stored or transmitted. In this case, I am suggesting taking the data you want apply when going “back” and translating it into a query string. For example:

{
    "foo": "bar",
    "spam": 1,
}

When crafted into a query string becomes foo=bar&spam=1. Django parses the querystring automatically and makes it accessible via request.GET which is an instance of QueryDict.

One way of crafting a query string would be to use QueryDict.urlencode. There is also a way to do this without using Django or a QueryDict: see this SO answer.

I understand the solution but what if there are multiple forms in a view ? How would I know how to pass the request.GET data to the right form among others in a view ?

Does the data needed change between forms? I’ve realized that you’re submitting the form, then attempting to go somewhere else. When the initial form is submitted, does the server store that data in the database?

It’s probably time for more details of your use case.

Yeah. Apologies for not being specific enough.

Yes. Each form is independent (I have multiple forms in a view, each independent of the other) and has it’s own functionality but all in a single view.

Yes. Each form has a submit button that takes it to a different page and the data is shown. Each of those different pages has a “Go back” sort of a button that brings it back to the main page (where all the forms are rendered). However since this actions is essentially a GET request, I loose the form data for all forms (main issue I want to solve)

No, I am not using any database of any kind. (Plus I don’t want to actually)

One option would be to convert the page into a Single Page Application with some JavaScript and make the form submissions via AJAX so that the browser maintains the state.

Another option would be to use some JavaScript that would store the data into the browser’s Local Storage so it can be loaded up when the page loads.