Erfassen von URL-Parametern in request.GET

457

Ich definiere derzeit reguläre Ausdrücke, um Parameter in einer URL zu erfassen, wie im Tutorial beschrieben. Wie greife ich über die URL als Teil des HttpRequestObjekts auf Parameter zu ? Mein gibt HttpRequest.GETderzeit ein leeres QueryDictObjekt zurück.

Ich würde gerne lernen, wie man das ohne Bibliothek macht, damit ich Django besser kennenlernen kann.

sutee
quelle

Antworten:

660

Wenn URL wie folgt lautet:domain/search/?q=haha Dann würden Sie verwenden request.GET.get('q', '').

qist der gewünschte Parameter und ''der Standardwert, wenn er qnicht gefunden wird.

Wenn Sie jedoch stattdessen nur Ihre konfigurierenURLconf , werden Ihre Captures von regexder Funktion als Argumente (oder benannte Argumente) an die Funktion übergeben.

Sowie:

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

Dann views.pyhättest du in deinem

def profile_page(request, username):
    # Rest of the method
Camflan
quelle
10
Ist '? Param =' die einzige Möglichkeit, wie Django Parameter erkennt? Gibt es eine Möglichkeit, URLconf mit HTTP.GET zu verwenden? Ich würde gerne / param / 2 machen.
Sutee
3
Überprüfen Sie den zweiten Teil meiner Antwort bezüglich Ihrer URLconf- und Regex-Erfassungen.
Camflan
2
Kein Problem. Verwenden Sie request.GET, wenn Sie ein Formular mit GET senden. Verwenden Sie request.POST, wenn Sie ein Formular mit POST senden. Wenn Sie URLs nur so konfigurieren möchten, dass sie variable Abschnitte enthalten, handelt es sich um ein URLconf / view-Argument.
Camflan
10
Was ist mit klassenbasierten Ansichten?
Benutzer
8
für klassenbasierte Ansichten können Sie verwendenself.kwargs['parameter']
Royendgel Silberie
336

Nehmen wir an, Sie haben Camflans Erklärung

  • die Regel url(regex=r'^user/(?P<username>\w{1,50})/$', view='views.profile_page')
  • eine eingehende Anfrage für http://domain/user/thaiyoshi/?message=Hi

Die URL-Dispatcher-Regel fängt Teile des URL- Pfads (hier "user/thaiyoshi/") ab und übergibt sie zusammen mit dem Anforderungsobjekt an die Ansichtsfunktion.

Die Abfragezeichenfolge (hier message=Hi) wird analysiert und die Parameter werden als QueryDictin gespeichert request.GET. Es wird keine weitere Übereinstimmung oder Verarbeitung für HTTP-GET-Parameter durchgeführt.

Diese Ansichtsfunktion würde sowohl aus dem URL-Pfad extrahierte Teile als auch einen Abfrageparameter verwenden:

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

Als Randnotiz finden Sie die Anforderungsmethode (in diesem Fall "GET"und normalerweise für eingereichte Formulare "POST") in request.method. In einigen Fällen ist es hilfreich zu überprüfen, ob es Ihren Erwartungen entspricht.

Update: Bei der Entscheidung, ob der URL-Pfad oder die Abfrageparameter zum Übergeben von Informationen verwendet werden sollen, kann Folgendes hilfreich sein:

  • Verwenden Sie den URL-Pfad, um Ressourcen eindeutig zu identifizieren, z. B. /blog/post/15/(nicht /blog/posts/?id=15)
  • Verwenden Sie Abfrageparameter, um die Art und Weise zu ändern, in der die Ressource angezeigt wird, z. B. /blog/post/15/?show_comments=1oder/blog/posts/2008/?sort_by=date&direction=desc
  • Um menschenfreundliche URLs zu erstellen, vermeiden Sie die Verwendung von ID-Nummern und verwenden Sie z. B. Datumsangaben, Kategorien und / oder Slugs: /blog/post/2008/09/30/django-urls/
Akaihola
quelle
17
Dies ist eine wirklich gut geschriebene Antwort. Es hat mir sicher geholfen, Django ein bisschen besser zu verstehen.
Mark
2
Wie können wir alle Parameterwerte erhalten, ohne Namen zu erwähnen
Numerah
@numerah request.GET ist ein Python-Wörterbuch. Sie können zB durch request.GET.items () iterieren.
Akaihola
perfekte Antwort.
Jay Geeth
1
Gibt es Gründe, warum es vorzuziehen ist, die im Update beschriebenen Gewohnheiten zu befolgen? (Wann wird der URL-Pfad gegen die GET-Parameter verwendet?)
m0etaz
55

Verwenden von GET

request.GET["id"]

POST verwenden

request.POST["id"]
Dadaso Zanzane
quelle
27
Während dies für vorhandene Schlüssel funktioniert, haben die Antworten von camflan und akaihola .get () verwendet, um KeyErrorAusnahmen bei einem fehlenden Schlüssel zu vermeiden . Es wäre ratsam, dasselbe zu tun (z request.POST.get('id', ''). B. ).
Vastlysuperiorman
25
def some_view(request, *args, **kwargs):
    if kwargs.get('q', None):
        # Do something here ..
Kevin
quelle
21

Für Situationen, in denen Sie nur das requestObjekt haben, das Sie verwenden könnenrequest.parser_context['kwargs']['your_param']

Ole Henrik Skogstrøm
quelle
2
Genau das, was ich brauchte. Vielen Dank.
user4052054
20

Ich möchte hier eine Option von mir hinzufügen. Jemand würde sich fragen, wie man einen Pfad in urls.py einstellt, wie z

domain/search/?q=CA

damit wir die Abfrage aufrufen können.

Tatsache ist, dass es NICHT notwendig ist, eine solche Route in urls.py festzulegen. Was Sie einstellen müssen, ist nur die Route in urls.py

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

und wenn Sie http: // Servername: port / domain / search /? q = CA eingeben . Der Abfrageteil '? Q = CA' wird automatisch in der Hash-Tabelle reserviert, auf die Sie jedoch verweisen können

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

Hier ist ein Beispiel (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

Darüber hinaus, wenn Sie eine Abfragezeichenfolge in der URL schreiben

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

Brechen Sie die Abfragezeichenfolge nicht in Anführungszeichen, z

http://servername:port/domain/search/?q="CA"
Eric Andrews
quelle
Hallo Eric! Ich bin neu in Django. Können Sie mehr Licht auf "queryset = queryset.filter (state__name = state_name)" werfen? Was bedeutet der doppelte Unterstrich in state__name?
Subbu
1
Hier ist "state" eine Tabelle und "name" ist ein in dieser Tabelle abgelegtes Feld. Im Filter von Django verweist state__name auf den Wert des Felds "name" in der Tabelle "state".
Eric Andrews
Dieser funktionierte im Vergleich zu anderen.
Sibish
17

Ich möchte einen Tipp teilen, der Ihnen Zeit sparen kann.
Wenn Sie vorhaben, so etwas in Ihrer urls.pyDatei zu verwenden:

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

Was im Grunde bedeutet www.example.com/<username>. Achten Sie darauf , es zu platzieren am Ende Ihrer URL - Einträge, denn sonst, es zu Konflikten mit den URL - Einträgen anfällig ist , die unten folgen, das heißt zugreifenden einer von ihnen werden Sie den schönen Fehler: User matching query does not exist.

Ich habe es einfach selbst erlebt; ich hoffe es hilft!

DrKaoliN
quelle
2
In diesem Fall möchten Sie möglicherweise überprüfen, ob Benutzernamen nicht mit anderen URL-Eigenschaften kollidieren.
DrKaoliN
13

Sie haben zwei Möglichkeiten, dies zu tun, falls Ihre URL so aussieht:

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

v1:

Wenn ein bestimmter Schlüssel obligatorisch ist, können Sie Folgendes verwenden:

key_a = request.GET['a']

Dies gibt den Wert zurück, awenn der Schlüssel vorhanden ist, und eine Ausnahme, wenn nicht.

v2:

Wenn Ihre Schlüssel optional sind:

request.GET.get('a')

Sie können versuchen, dass dies ohne Argument nicht abstürzt. Sie können es also mit einem Beispiel umhüllen try: except:und zurückgeben HttpResponseBadRequest(). Dies ist eine einfache Möglichkeit, Ihren Code weniger komplex zu gestalten, ohne eine spezielle Ausnahmebehandlung zu verwenden.

Bartłomiej
quelle
Wie kann ich Abfrageparameter aus der Vorlage erkennen?
Akin Hwan
8

Dies ist nicht genau das, wonach Sie gefragt haben, aber dieses Snippet ist hilfreich für die Verwaltung query_stringsin templates.

jammen
quelle
5

Diese Abfragen werden derzeit auf zwei Arten durchgeführt. Wenn Sie auf die Abfrageparameter (GET) zugreifen möchten, können Sie Folgendes abfragen:

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

Wenn Sie auf die vom POST übergebenen Parameter zugreifen möchten, müssen Sie auf folgende Weise zugreifen:

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

Wenn Sie mit 'get ()' auf das Wörterbuch (QueryDict) zugreifen, können Sie einen Standardwert festlegen. In den oben genannten Fällen sind die Werte Keine, wenn 'Status' oder 'Rolle' nicht informiert werden.

mdcg
quelle
0

Dies ist eine weitere alternative Lösung, die implementiert werden kann:

in der URL-Konfiguration. ::

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

in den Ansichten:

list2 = queryparams.split("&")
sachi
quelle