Building a search form with 4 required choices, which will be inserted as arguments in an URL [warning: long question]

22 views
Skip to first unread message

Jack Zhang

unread,
Oct 23, 2017, 11:59:36 AM10/23/17
to Django users
This is a semi-long question.  Please let me know wherever I make a mistake.

I'm building a search form with 4 required choices, 1 of the choices is a CharField with a max_length of 3.  The other 3 choices are ChoiceField's.  Here is a picture of what the search form looks like:


I've read through the Django docs and other things on the Internet but I'm still very unclear about how to approach this.

1. First I believe I need to create 4 args or kwargs in the url for each of the choices.  If I use args, it would look something like...

url(r'^search?(\w+{3})&(\w+{2})&(\w+{1-2})&(\w+{1-2})', function/class view, name='search')

2. Next, I need to pass the user's input in the html page into the url args.  I have a form set up to get the user's input.  But how would I write this on the HTML page?  Do I simply make a url tag like {% url 'search' args1, args2, args3, args4 %}?

3. Then I need to create the views function.  My first question is, should I use a function-based view or the generic class-based ListView?  The result of the search will be a list of items, so ListView is a good template to use, but I don't know how having 4 args would affect using ListView.  My second question is, what is the most effective way of making this search?  I need to check if any records in the database matches the user's search, so would I do something like 'For record in database' to check over every record in the database?

If I used a function view, would it look something like:

def search(request, args1, args2, args3, args4):
     for record in database:
          if args matches record:
               display record

Thank you for reading through the question

Daniel Roseman

unread,
Oct 29, 2017, 7:59:25 AM10/29/17
to Django users
Your difficulties all stem from the same misunderstanding here.

Forms - at least when using the GET action - put their arguments in the querystring - the bit after the ? in the URL. Django doesn't treat that as part of the URL itself, but as a separate attribute, `request.GET`. So both your first and second questions are irrelevant: you don't need to capture the values in a URL pattern, and nor do you need to insert them in there in the HTML somehow. Just use a basic pattern of `r('^search/$)` and all will be fine.

For your third question, it makes no difference whether you use function or class-based views. If you did use a ListView, though, you could override `get_queryset` to filter by the values in the GET dictionary:

def get_queryset(self):
    qs = super(MyListView, self).get_queryset()
    if 'bedrooms' in request.GET:
        qs = qs.filter(bedrooms=request.GET['bedrooms']
    ... etc ...
    return qs

-- 
DR.

Jack

unread,
Oct 29, 2017, 9:33:51 AM10/29/17
to Django users
That makes much more sense.  It's my fault for not reading the Django docs properly, but I don't seem to soak in the concepts at all by simply reading.  

I went with a ListView + get_queryset override.  I haven't managed to get the filter to work but the search itself is working properly.

Thanks Daniel!
Reply all
Reply to author
Forward
0 new messages