Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass <input> value to Django view

Tags:

python

django

Let's say I have the following pointless example view:

def foo(request, input):
    return HttpResponse()

and in a template I have a form:

<form method="get" action="{% url 'foo' ??? %}">
    <input id="myinput" type="text" name="myinput">

    ...

</form>

Finally, I have the following url in my URLconf:

urlpatterns = [
    url(r'^foo/(.+)/', views.foo, name='foo'),
]

What I would like to do, is pass the value entered by the user into the input with the id of #myinput to the foo() view function. To put it another way, you should be able to enter bar in the html input, and when you submit the form it will take you to foo/bar/.

I know that within the foo view I could access the value of the input easily with request.GET['myinput'], but I want it to show up in the url as well.

This seems like it should be a fairly common task, but I have not been able to come up with a solution yet. Any suggestions would be appreciated. My Frankenstein's Monster of a first Django site is almost complete, and this is one of last pieces I am missing.

like image 897
elethan Avatar asked Feb 06 '23 21:02

elethan


1 Answers

The source of my misunderstanding

Although I did not make this clear in an attempt to simplify my example and avoid using app-specific code, my use case is a simple search view. The view was actually one of the first views I wrote in the start of my Django journey, and I mistakenly was POSTing my data instead of GETing it. This was making it so that if I was searching for the item foo, it would take me to the detail page for foo, but the url would be mysite/search/ (i.e., the search query is not included in the url though it is included in the request), and I can't return to those search results by visiting the url mysite/search/.

While I was using a GET request in my toy example in this question, I didn't realize that I had been using a POST in my app, and that with some minor tweaking I can get the functionality I want for free very easily. I know that all of this is extremely obvious to veteran and even intermediate web developers, but for someone starting from scratch without web or cs experience, things like HTTP can be a little confusing. At least for me it is. Thanks so much to @Two-Bit Alchemist for explaining this in a way that I can understand.

Applying all this to my toy example

I would get rid of the passed parameter in my view:

def foo(request):

    # If I want to do something with the search query, I can access it with
    # request.GET['search_query']

    return HttpResponse()

change my form in my template to:

<form method="get" action="{% url 'foo' %}">
    <input id="myinput" type="text" name="search_query">

    ...

</form>

and change my url to:

urlpatterns = [
    url(r'^foo/search/', views.foo, name='foo'),
]

As @Two-Bit Alchemist said: "The rest will happen like magic". If a user enters bar in the input and submits the form, they will be taken to foo/search/?search_query=bar. This is what I was looking for.

like image 136
elethan Avatar answered Feb 15 '23 12:02

elethan