Capturing URL parameters in request.GET
I am currently defining regular expressions in order to capture parameters in a URL, as described in the tutorial. How do I access parameters from the URL as part the HttpRequest
object?
My HttpRequest.GET
currently returns an empty QueryDict
object.
I'd like to learn how to do this without a library, so I can get to know Django better.
When a URL is like domain/search/?q=haha
, you would use request.GET.get('q', '')
.
q
is the parameter you want, and ''
is the default value if q
isn't found.
However, if you are instead just configuring your URLconf
**, then your captures from the regex
are passed to the function as arguments (or named arguments).
Such as:
(r'^user/(?P<username>\w{0,50})/$', views.profile_page,),
Then in your views.py
you would have
def profile_page(request, username):
# Rest of the method
To clarify camflan's explanation, let's suppose you have
- the rule
url(regex=r'^user/(?P<username>\w{1,50})/$', view='views.profile_page')
- an incoming request for
http://domain/user/thaiyoshi/?message=Hi
The URL dispatcher rule will catch parts of the URL path (here "user/thaiyoshi/"
) and pass them to the view function along with the request object.
The query string (here message=Hi
) is parsed and parameters are stored as a QueryDict
in request.GET
. No further matching or processing for HTTP GET parameters is done.
This view function would use both parts extracted from the URL path and a query parameter:
def profile_page(request, username=None):
user = User.objects.get(username=username)
message = request.GET.get('message')
As a side note, you'll find the request method (in this case "GET"
, and for submitted forms usually "POST"
) in request.method
. In some cases, it's useful to check that it matches what you're expecting.
Update: When deciding whether to use the URL path or the query parameters for passing information, the following may help:
- use the URL path for uniquely identifying resources, e.g.
/blog/post/15/
(not/blog/posts/?id=15
) - use query parameters for changing the way the resource is displayed, e.g.
/blog/post/15/?show_comments=1
or/blog/posts/2008/?sort_by=date&direction=desc
- to make human-friendly URLs, avoid using ID numbers and use e.g. dates, categories, and/or slugs:
/blog/post/2008/09/30/django-urls/
Using GET
request.GET["id"]
Using POST
request.POST["id"]
Someone would wonder how to set path in file urls.py, such as
domain/search/?q=CA
so that we could invoke query.
The fact is that it is not necessary to set such a route in file urls.py. You need to set just the route in urls.py:
urlpatterns = [
path('domain/search/', views.CityListView.as_view()),
]
And when you input http://servername:port/domain/search/?q=CA. The query part '?q=CA' will be automatically reserved in the hash table which you can reference though
request.GET.get('q', None).
Here is an example (file views.py)
class CityListView(generics.ListAPIView):
serializer_class = CityNameSerializer
def get_queryset(self):
if self.request.method == 'GET':
queryset = City.objects.all()
state_name = self.request.GET.get('q', None)
if state_name is not None:
queryset = queryset.filter(state__name=state_name)
return queryset
In addition, when you write query string in the URL:
http://servername:port/domain/search/?q=CA
Do not wrap query string in quotes. For example,
http://servername:port/domain/search/?q="CA"