How to get GET request values in Django?
Asked Answered
S

19

629

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.

Sottish answered 29/9, 2008 at 20:29 Comment(0)
B
848

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
Bevbevan answered 29/9, 2008 at 20:31 Comment(10)
Is '?param=' the only way Django recognizes parameters? Is there a way to use URLconf with HTTP.GET? I'd like to do /param/2.Sottish
Check the second part of my response regarding your URLconf and regex captures.Bevbevan
Ok. I am currently using the second method. Seems like they are separate mechanisms, and I'm trying to blend them. Thanks!Sottish
No problem. use request.GET if you submit a form using GET, use request.POST if you submit a form using POST, and if you just want to configure URLs to have variable sections, then it's a URLconf/view argument.Bevbevan
What about class based views?Argueta
for class based views you can use self.kwargs['parameter']Evocation
what if there are more than one parameter? For eg. pagination with two query params limit and skipGorki
how can i detect from the template, the presence of a query parameter? or must I do this in views.pyPich
@Akin {% if request.GET.the_var_you_want %}Hasson
@RoyendgelSilberie Go on...Enroot
C
447

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/
Carpi answered 1/10, 2008 at 12:11 Comment(5)
This is a really well written answer. It sure helped me understand Django a bit better.Zobias
how can we get all parameters values without mentioning namesOverdose
@Overdose request.GET is a Python dictionary. You can e.g. iterate through request.GET.items().Carpi
any reasons why it's preferred to follow the habits written in the update ? (when to use URL path vs GET params)Motta
@Motta genuinely good question. I think you'd have a hard time finding the origin of this concept. From my experience this was something handed down to me in an almost tribal way, i'd be curious to find the origin as well.Tapster
T
87

Using GET

request.GET["id"]

Using POST

request.POST["id"]
Trilbi answered 21/1, 2015 at 8:8 Comment(1)
While this works for existing keys, the answers by camflan and akaihola have used .get() to avoid KeyError exceptions in the case of a missing key. It would be wise to do the same (e.g. request.POST.get('id', '')).California
T
67

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"
Titicaca answered 6/6, 2018 at 7:20 Comment(2)
Hi Eric! I am new to Django. Can you shed more light on "queryset = queryset.filter(state__name=state_name)". What does the double underscore in state__name signify.Rum
Here "state" is a table and "name" is a filed in this table. In the filter of Django, state__name will reference the value of field "name" in "state" table.Titicaca
F
33
def some_view(request, *args, **kwargs):
    if kwargs.get('q', None):
        # Do something here ..
Feliks answered 18/11, 2010 at 18:40 Comment(0)
I
31

For situations where you only have the request object you can use request.parser_context['kwargs']['your_param']

Ioannina answered 5/5, 2017 at 13:54 Comment(0)
P
27

You have two common ways to do that in case your URL looks like that:

https://domain/method/?a=x&b=y

Version 1:

If a specific key is mandatory you can use:

key_a = request.GET['a']

This will return a value of a if the key exists and an exception if not.

Version 2:

If your keys are optional:

request.GET.get('a')

You can try that without any argument and this will not crash. So you can wrap it with try: except: and return HttpResponseBadRequest() in example. This is a simple way to make your code less complex, without using special exceptions handling.

Poultry answered 4/10, 2017 at 12:5 Comment(1)
how can i detect query param from the template?Pich
Y
17

I would like to share a tip that may save you some time.
If you plan to use something like this in your urls.py file:

url(r'^(?P<username>\w+)/$', views.profile_page,),

Which basically means www.example.com/<username>. Be sure to place it at the end of your URL entries, because otherwise, it is prone to cause conflicts with the URL entries that follow below, i.e. accessing one of them will give you the nice error: User matching query does not exist.

I've just experienced it myself; hope it helps!

Yelmene answered 5/2, 2013 at 2:5 Comment(1)
Plus, in this case you may want to check that user names do not collide with other url enrties.Yelmene
A
14

These queries are currently done in two ways. If you want to access the query parameters (GET) you can query the following:

http://myserver:port/resource/?status=1
request.query_params.get('status', None) => 1

If you want to access the parameters passed by POST, you need to access this way:

request.data.get('role', None)

Accessing the dictionary (QueryDict) with 'get()', you can set a default value. In the cases above, if 'status' or 'role' are not informed, the values ​​are None.

Acetyl answered 22/7, 2019 at 14:35 Comment(0)
H
11

If you don't know the name of params and want to work with them all, you can use request.GET.keys() or dict(request.GET) functions

Hodgkin answered 11/1, 2021 at 12:15 Comment(0)
S
9

This is not exactly what you asked for, but this snippet is helpful for managing query_strings in templates.

Safeguard answered 30/9, 2008 at 9:19 Comment(0)
D
9

If you only have access to the view object, then you can get the parameters defined in the URL path this way:

view.kwargs.get('url_param')

If you only have access to the request object, use the following:

request.resolver_match.kwargs.get('url_param')

Tested on Django 3.

Downhearted answered 15/8, 2020 at 5:58 Comment(0)
T
8

views.py

from rest_framework.response import Response

def update_product(request, pk):
    return Response({"pk":pk})

pk means primary_key.

urls.py

from products.views import update_product
from django.urls import path

urlpatterns = [
    ...,
    path('update/products/<int:pk>', update_product)
]
Teddie answered 18/8, 2021 at 9:35 Comment(5)
I think this is the most clean way to write a path, you can extend more about the answer like explaining a little bit about optional parameteres an document and explain a little the pieces of code added, just to pleople who are new in the framework.Fortune
Thank you for your comment. I really appreciate it so much. :) .URL Parameters can not be optional (As far as I think). because they specify which function will be executed. what can be optional is Query Parameters and data in request body. this can be controlled via a serializer (In Django REST Framework). @FortuneTeddie
Of course they can, you have to use: def update_product(request, pk=None): the pk is gona be optional...Fortune
You are correct. :) :) But, I am afraid this may create an endpoint like this: update/products//, with double slash in the end, because it is empty. Then path should be like this: path('update/products/<int:pk>', update_product), not like this: path('update/products/<int:pk>/', update_product), I have updated it. I removed the last slash in the answer of the question. The differrenece is the last slash. :) :)Teddie
I am so glad you made me realize this. :) :) I didn't realize it before. :) :)Teddie
L
6

You might as well check request.META dictionary to access many useful things like PATH_INFO, QUERY_STRING

# for example
request.META['QUERY_STRING']

# or to avoid any exceptions provide a fallback

request.META.get('QUERY_STRING', False)

you said that it returns empty query dict

I think you need to tune your url to accept required or optional args or kwargs Django got you all the power you need with regrex like:

url(r'^project_config/(?P<product>\w+)/$', views.foo),

more about this at django-optional-url-parameters

Lastminute answered 4/10, 2020 at 22:3 Comment(0)
A
5

This is another alternate solution that can be implemented:

In the URL configuration:

urlpatterns = [path('runreport/<str:queryparams>', views.get)]

In the views:

list2 = queryparams.split("&")
Antrorse answered 27/3, 2020 at 18:38 Comment(1)
Helped me to understand, I can pass int by "<int:some_number>"Nolan
J
2

It seems more recommended to use request.query_params. For example,

When a URL is like domain/search/?q=haha, you would use request.query_params.get('q', None)

https://www.django-rest-framework.org/api-guide/requests/

"request.query_params is a more correctly named synonym for request.GET.

For clarity inside your code, we recommend using request.query_params instead of the Django's standard request.GET. Doing so will help keep your codebase more correct and obvious - any HTTP method type may include query parameters, not just GET requests."

Jankell answered 5/12, 2022 at 1:40 Comment(0)
S
1

url parameters may be captured by request.query_params

Smoothtongued answered 3/3, 2022 at 3:42 Comment(1)
Please, consider a better elaboration for your anwsers...A little context of something. ThxGainor
I
1

For example, if you access the url below:

https://example.com/?fruits=apple&meat=beef

Then, you can get the parameters in views.py as shown below. *My answer explains how to get a GET request values' list in Django and my answer explains how to get POST request values in Django:

# "views.py"

from django.shortcuts import render

def index(request):

    print(request.GET['fruits']) # apple
    print(request.GET.get('meat')) # beef
    print(request.GET.get('fish')) # None
    print(request.GET.get('fish', "Doesn't exist")) # Doesn't exist
    print(request.GET.getlist('fruits')) # ['apple']
    print(request.GET.getlist('fish')) # []
    print(request.GET.getlist('fish', "Doesn't exist")) # Doesn't exist
    print(request.GET._getlist('meat')) # ['beef']
    print(request.GET._getlist('fish')) # []
    print(request.GET._getlist('fish', "Doesn't exist")) # Doesn't exist
    print(list(request.GET.keys())) # ['fruits', 'meat']
    print(list(request.GET.values())) # ['apple', 'beef']
    print(list(request.GET.items())) # [('fruits', 'apple'), ('meat', 'beef')]
    print(list(request.GET.lists())) # [('fruits', ['apple']), ('meat', ['beef'])]
    print(request.GET.dict()) # {'fruits': 'apple', 'meat': 'beef'}
    print(dict(request.GET)) # {'fruits': ['apple'], 'meat': ['beef']}
    print(request.META['QUERY_STRING']) # fruits=apple&meat=beef
    print(request.META.get('QUERY_STRING')) # fruits=apple&meat=beef

    return render(request, 'index.html')

Then, you can get the parameters in index.html as shown below:

{# "index.html" #}

{{ request.GET.fruits }} {# apple #}
{{ request.GET.meat }} {# beef #}
{{ request.GET.dict }} {# {'fruits': 'apple', 'meat': 'beef'} #}
{{ request.META.QUERY_STRING }} {# fruits=apple&meat=beef #}
Indefinable answered 18/9, 2023 at 17:15 Comment(0)
T
0

In Django, views gets the path resolved for you.

But other than that if you need to resolve the path you can use the resolve module

Ex - the requestedPath is - domain/search/?userName=myUserName or domain/search/<userName>/product/<productName>

from django.urls import resolve
resolveMatcher = resolve(request.path)
userName = resolveMatcher.kwargs.get('userName', None)
Tatty answered 11/5, 2023 at 11:20 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.