3

I am implementing a search form in Django. I can do a POST or a GET request. Each has their use-cases (POST request, if I want to change data on the server, GET request, if I just want to get data from the server).

  • Via POST request (the search keywords are not visiable in the URL, but rather in a dict in request.POST); cons: I cannot bookmark the search
  • via GET request (the search keywords are visible in the URL, for intance localhost:8000/books/?author=schultz); cons(?): the part ?author=schultz cannot be processed by the URL handler (see [2] below). I need to read the data from request.GET.get("author", None) in my view function.
  • or directly in the URL like so: localhost:8000/books/search/author/schultz ?

The author in [1] says, that Django's preferred way to handle a URL is not via GET (like so: /category_check_view/?item_id=2, but rather like so /category_check_view/2)

If I would like to implement search like this: localhost:8000/books/author/schultz, then I would have to process a GET request, read the params ?author=schultz via request.GET.get("author", None) and in my view do a redirect from this URL localhost:8000/books (in which I have a form and a GET request) to this localhost:8000/books/author/schultz.

Does this approach make sense? Or am I overcomplicating things? Just leave it at a GET request to implement my search form?


[1] Yuval Adam says in this post that

GET params are not processed by the URL handler, but rather passed directly to the GET param dict accessible in a view at request.GET.

The Django (i.e. preferred) way to do handle URLs is the first one.

[2] Django docs: What the URLconf searches against

Ugur
  • 1,914
  • 2
  • 25
  • 46
  • I don't understand how you will modify data while searching. Search in most of the use cases are done using GET request. – Sandeep Balagopal May 30 '17 at 12:00
  • I didn't say that I wanted to modify data. Just that it would be possible to do it via POST request, if I didn't want the search keywords to show up in the URL or in the log files etc – Ugur May 30 '17 at 12:03
  • I can't see the need for the redirect. The point of a search is that it can accept multiple parameters, and displays the result of the combined lookup. There's no need to redirect anywhere. – Daniel Roseman May 30 '17 at 12:03
  • So you'd always use a GET request? – Ugur May 30 '17 at 12:05

2 Answers2

4

First things first, GET is for reading data and POST is for creating. Since search is a form of reading data, you will use GET!

Which takes us to the matter of the urls. There are as you mention 2 distinct ways to pass parameters via a url in Django:

  1. Parameters as part of url:

    Your url regex must look like this:

    url(r'^books/author/(?P<author>\w+)/$', 
        'yourviewname', 
        name='author_search'
    )
    

    Your URLs will have the shape: /books/author/author_name_here

  2. GET Parameters:

    Your url regex can look like this:

    url(r'^books/$', 
        'yourviewname', 
        name='book_search'
    )
    

    Your URLs will have the shape: /books/?author=author_name_here&other=other_param

It is a matter of choice mostly on what you want to use. To quote a great answer:

Don't obsess over the beauty of your URIs, they are a tool not a piece of art.
- @Quentin -


For a short implementation example of both the above mentioned ways, take a look at this link
John Moutafis
  • 22,254
  • 11
  • 68
  • 112
  • Excellent answer! Thanks! Now if I wanted to implement it with parameters as part of the URL (your first example), would the logic be like this? I would have a `books/` page where I have a search form. Now after submitting the search form would I redirect to `books/author/(searchword)` ? Or how else would I connect the two URLs `books/` and `books/author/(searchword)`. - I am not saying that I prefer doing search that way. Just wondered which way is the idiomatic way to go. – Ugur May 30 '17 at 13:23
  • @Ugur You do not need to redirect anywhere! Your view can simply return the query's result and that would be all (That is how I do it in either case!). :) – John Moutafis May 30 '17 at 13:34
  • But the search happens on this page `books/`. And if the view reads the searchword from `request.GET.get("searchword", None)`, how does my URL (suddenly) show `books/author/(searchword)`. Even if the search happened on this page `books/author/`, after submit, how does the URL reflect `books/author/(searchword)`? Am I missing something fundamentally? :) – Ugur May 30 '17 at 13:48
  • 1
    @Ugur have a look here: https://stackoverflow.com/questions/31661044/how-to-redirect-url-pattern-with-variables-from-urls-py-in-django?answertab=votes#tab-top It may help you :) – John Moutafis May 30 '17 at 13:51
1

Also usable is:

from django.urls import path

import <your_view> from views.py

path('news/<str:author>/', <your_view>.as_view())
iknow
  • 8,358
  • 12
  • 41
  • 68