Question

I have a Django Url pattern for my search filter as follows:

url(r'^search/(?P.+)$', views.search, name='search'),

That way, if I call, say /search/1+Timothy, the url goes to my search view, which returns the results of my query - in this case, all entries in 1 Timothy. So far, so good.

In my page, I wanted to add a simple call to this search function. So, I thought, why not a simple form?

    <FORM method='GET' action='/search/'>
        <!-- Note: Calls /search?filter_range=entered_reference is handled in urls.py-->
        <LABEL for="filter_range">Show References</LABEL>
        <INPUT id='filter_range' name='filter_range' type='text' placeholder='search' value='' />
        <INPUT type='submit' />
    </FORM>

Which should be equal to a simple:

http://127.0.0.1:8000/search/?filter_range=1+timothy

Problem is, I can't figure out how to specify that in the urls.py:

url(r'^search/\\?passage=(?P<filter_range>.+)$', views.search, name='search'),
url(r'^search/(?P<filter_range>.+)$', views.search, name='search'),

doesn't work, nor can I seem to figure out a regular expression that does. So, how do I get the output of the form in my template to callback to a url that urls.py can find?

Was it helpful?

Solution

You should not worrry about the GET parameters in the URL.

Try this:

url(r'^search/$', views.search, name='search'),

and in views

def search():
    filter_range = request.GET.get('filter_range', '')
    #rest of the code.

You have the flexibility of sending across any number of GET parameters without having to declare them in the urls.py

Some more context in this documentation here

OTHER TIPS

You cannot retrieve query parameters via urlconfs. They can be accessed via the request object which is always available in django views. Example:

request.GET.get('searchvalue')

For more details please take a look at https://docs.djangoproject.com/en/dev/ref/request-response/.

Just as a small followup, this is exactly how I was able to re-use my function in place:

From views.py

def search(request, filter_range):
    search_ref = BibleReference(filter_range)
    qry_in_range = "SELECT * FROM concordance_reference WHERE ref_book_num=%s AND ref_endchapter_num >= %s AND ref_endverse_num >= %s AND ref_startchapter_num <= %s AND ref_startverse_num <= %s ORDER BY ref_book_num, ref_startchapter_num, ref_startverse_num, ref_endchapter_num, ref_endverse_num"
    params = tuple([search_ref.book_num, search_ref.start_chapter, search_ref.start_verse, search_ref.end_chapter, search_ref.end_verse]) 

    found_references_list = VerseReference.objects.raw(qry_in_range, params)

    template = loader.get_template('concordance/index.html')
    context = RequestContext( request, {
        'filter_range': filter_range,
        'filter_ref': search_ref,
        'found_references_list': found_references_list,
        })
    return HttpResponse(template.render(context))

def empty_search(request):
    filter_range = request.GET.get('filter_range', '')
    return search(request, filter_range)

Urls.py

url(r'^search/$', views.empty_search, name='empty_search'),
url(r'^search/(?P<filter_range>.+)$', views.search, name='search'),

The advantage of this approach is that my restful urls: /search/1+Timothy remain good, and /search/?filter_range=1+Timothy can still be called from my form.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top