Przechwytywanie parametrów adresu URL w request.GET


457

Obecnie definiuję wyrażenia regularne w celu przechwytywania parametrów w adresie URL, jak opisano w samouczku. Jak uzyskać dostęp do parametrów z adresu URL jako części HttpRequestobiektu? Mój HttpRequest.GETobecnie zwraca pusty QueryDictobiekt.

Chciałbym się nauczyć, jak to zrobić bez biblioteki, aby lepiej poznać Django.

Odpowiedzi:


659

Gdy adres URL wygląda następująco:, todomain/search/?q=haha byś użyłrequest.GET.get('q', '') .

qto parametr, który chcesz, i ''jest wartością domyślną, jeśli qnie zostanie znaleziony.

Jeśli jednak zamiast tego konfigurujesz tylkoURLconf , twoje przechwyty z regexsą przekazywane do funkcji jako argumenty (lub nazwane argumenty).

Jak na przykład:

(r'^user/(?P<username>\w{0,50})/$', views.profile_page,),

Wtedy views.pymiałbyś

def profile_page(request, username):
    # Rest of the method

10
Czy „? Param =” to jedyny sposób, w jaki Django rozpoznaje parametry? Czy istnieje sposób na użycie URLconf z HTTP.GET? Chciałbym zrobić / param / 2.
sutee

3
Sprawdź drugą część mojej odpowiedzi dotyczącą twojego URLconf i przechwytywania wyrażeń regularnych.
camflan

2
Nie ma problemu. użyj request.GET, jeśli przesyłasz formularz za pomocą GET, użyj request.POST, jeśli przesyłasz formularz za pomocą POST, a jeśli chcesz tylko skonfigurować adresy URL tak, aby zawierały zmienne sekcje, jest to argument URLconf / view.
camflan

10
Co z widokami opartymi na klasach?
Użytkownik

8
do widoków klasowych możesz użyćself.kwargs['parameter']
Royendgel Silberie

335

Aby wyjaśnić wyjaśnienie camflan, załóżmy, że masz

  • zasada url(regex=r'^user/(?P<username>\w{1,50})/$', view='views.profile_page')
  • przychodzące żądanie dla http://domain/user/thaiyoshi/?message=Hi

Reguła dyspozytora adresów URL przechwytuje części ścieżki adresu URL (tutaj "user/thaiyoshi/") i przekazuje je do funkcji widoku wraz z obiektem żądania.

Ciąg zapytania (tutaj message=Hi) jest analizowany, a parametry są przechowywane jako „ QueryDictin” request.GET. Nie jest wykonywane dalsze dopasowanie ani przetwarzanie parametrów HTTP GET.

Ta funkcja widoku użyłaby zarówno części wyodrębnionych ze ścieżki URL, jak i parametru zapytania:

def profile_page(request, username=None):
    user = User.objects.get(username=username)
    message = request.GET.get('message')

Na marginesie, znajdziesz metodę żądania (w tym przypadku "GET"i zwykle dla przesłanych formularzy "POST") wrequest.method . W niektórych przypadkach warto sprawdzić, czy odpowiada oczekiwaniom.

Aktualizacja: przy podejmowaniu decyzji, czy użyć ścieżki URL, czy parametrów zapytania do przekazania informacji, pomocne mogą być:

  • użyj ścieżki URL do jednoznacznej identyfikacji zasobów, np. /blog/post/15/(nie /blog/posts/?id=15)
  • użyj parametrów zapytania do zmiany sposobu wyświetlania zasobu, np. /blog/post/15/?show_comments=1lub/blog/posts/2008/?sort_by=date&direction=desc
  • aby tworzyć przyjazne dla ludzi adresy URL, unikaj używania numerów identyfikacyjnych i używaj np. dat, kategorii i / lub ślimaków: /blog/post/2008/09/30/django-urls/

17
To jest naprawdę dobrze napisana odpowiedź. Pomogło mi to trochę lepiej zrozumieć Django.
Mark

2
jak możemy uzyskać wszystkie wartości parametrów bez
podawania

@numerah request.GET to słownik Pythona. Możesz np. Iterować poprzez request.GET.items ().
akaihola,

idealna odpowiedź.
Jay Geeth

1
jakieś powody, dla których lepiej jest przestrzegać nawyków opisanych w aktualizacji? (kiedy używać ścieżki URL a parametry GET)
m0etaz

55

Korzystanie z GET

request.GET["id"]

Korzystanie z POST

request.POST["id"]

27
Chociaż działa to na istniejące klucze, odpowiedzi camflan i akaihola wykorzystały .get (), aby uniknąć KeyErrorwyjątków w przypadku braku klucza. Mądrze byłoby zrobić to samo (np request.POST.get('id', '').).
vastlysuperiorman

25
def some_view(request, *args, **kwargs):
    if kwargs.get('q', None):
        # Do something here ..


20

Chciałbym tutaj dodać opcję siebie. Ktoś mógłby się zastanawiać, jak ustawić ścieżkę w urls.py, na przykład

domain/search/?q=CA

abyśmy mogli wywołać zapytanie.

Faktem jest, że NIE jest konieczne ustawianie takiej trasy w urls.py. Musisz tylko ustawić trasę w urls.py

urlpatterns = [
    path('domain/search/', views.CityListView.as_view()),
]

a kiedy wejście http: // nazwa_serwera: port / domena / search / q = Kalifornia . Część zapytania „? Q = CA” zostanie automatycznie zarezerwowana w tabeli skrótów, do której można się jednak odwoływać

request.GET.get('q', None).

Oto przykład (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

Ponadto podczas pisania ciągu zapytania w adresie URL

http://servername:port/domain/search/?q=CA

Nie zawijaj ciągu zapytania w cudzysłów, np

http://servername:port/domain/search/?q="CA"

Cześć Eric! Jestem nowy w Django. Czy możesz rzucić więcej światła na „queryset = queryset.filter (state__name = nazwa_stanu)”. Co oznacza podwójny znak podkreślenia w state__name.
Subbu

1
Tutaj „stan” jest tabelą, a „nazwa” jest zapisana w tej tabeli. W filtrze Django parametr state__name będzie odwoływał się do wartości pola „name” w tabeli „state”.
Eric Andrews,

ten działał w porównaniu do innych.
Sibish

17

Chciałbym podzielić się wskazówkami, które mogą zaoszczędzić trochę czasu.
Jeśli planujesz użyć czegoś takiego w swoim urls.pypliku:

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

Co w zasadzie oznacza www.example.com/<username>. Pamiętaj, aby umieścić go na końcu swoich wpisów URL, ponieważ w przeciwnym razie może powodować konflikty z poniższymi wpisami URL, tj. Uzyskanie dostępu do jednego z nich spowoduje ładny błąd: User matching query does not exist.

sam tego doświadczyłem; mam nadzieję, że to pomoże!


2
Ponadto w tym przypadku możesz sprawdzić, czy nazwy użytkowników nie kolidują z innymi adresami URL.
DrKaoliN

13

Możesz to zrobić na dwa sposoby, jeśli Twój URL wygląda tak:

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

v1:

Jeśli określony klucz jest obowiązkowy, możesz użyć:

key_a = request.GET['a']

Zwróci to wartość a if, jeśli klucz istnieje i wyjątek, jeśli nie.

v2:

Jeśli twoje klucze są opcjonalne:

request.GET.get('a')

Możesz spróbować tego bez żadnego argumentu, to się nie zawiesi. Możesz więc owinąć go try: except:i powrócić HttpResponseBadRequest()w przykładzie. Jest to prosty sposób na zmniejszenie złożoności kodu bez konieczności korzystania ze specjalnej obsługi wyjątków.


jak mogę wykryć parametry zapytania z szablonu?
Akin Hwan


5

Te zapytania są obecnie wykonywane na dwa sposoby. Jeśli chcesz uzyskać dostęp do parametrów zapytania (GET), możesz przesłać zapytanie:

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

Jeśli chcesz uzyskać dostęp do parametrów przekazywanych przez POST, musisz uzyskać dostęp w ten sposób:

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

Uzyskując dostęp do słownika (QueryDict) za pomocą „get ()”, możesz ustawić wartość domyślną. W powyższych przypadkach, jeżeli „status” lub „rola” nie są poinformowane, wartościami są Brak.


0

To kolejne alternatywne rozwiązanie, które można wdrożyć:

w konfiguracji adresu URL. :

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

w widokach:

list2 = queryparams.split("&")
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.