Acquisizione dei parametri dell'URL in request.GET


458

Attualmente sto definendo espressioni regolari per acquisire parametri in un URL, come descritto nel tutorial. Come accedo ai parametri dall'URL come parte HttpRequestdell'oggetto? Il mio HttpRequest.GETattualmente restituisce un QueryDictoggetto vuoto .

Mi piacerebbe imparare come farlo senza una biblioteca in modo da poter conoscere meglio Django.

Risposte:


662

Quando url è come:,domain/search/?q=haha allora useresti request.GET.get('q', '').

qè il parametro che desideri, ed ''è il valore predefinito se qnon viene trovato.

Tuttavia, se invece stai semplicemente configurando il tuoURLconf , le tue acquisizioni da regexvengono passate alla funzione come argomenti (o argomenti denominati).

Ad esempio:

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

Allora nel tuo views.pyavresti

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

10
'? Param =' è l'unico modo in cui Django riconosce i parametri? C'è un modo per usare URLconf con HTTP.GET? Mi piacerebbe fare / param / 2.
sutee,

3
Controlla la seconda parte della mia risposta per quanto riguarda le tue acquisizioni URLconf e regex.
camflan,

2
Nessun problema. usa request.GET se invii un modulo usando GET, usa request.POST se invii un modulo usando POST e se vuoi solo configurare gli URL per avere sezioni variabili, allora è un argomento URLconf / view.
camflan,

10
Che dire delle viste basate sulla classe?
Utente

8
per le visualizzazioni di classe puoi usareself.kwargs['parameter']
Royendgel Silberie,

336

Per chiarire la spiegazione di Camflan, supponiamo che tu abbia

  • la regola url(regex=r'^user/(?P<username>\w{1,50})/$', view='views.profile_page')
  • a nella richiesta in arrivo per http://domain/user/thaiyoshi/?message=Hi

La regola del dispatcher di URL cattura parti del percorso dell'URL (qui "user/thaiyoshi/") e le passa alla funzione di visualizzazione insieme all'oggetto richiesta.

La stringa di query (qui message=Hi) viene analizzata e i parametri vengono archiviati come QueryDictin request.GET. Non viene eseguita alcuna ulteriore corrispondenza o elaborazione per i parametri HTTP GET.

Questa funzione di visualizzazione utilizzerà entrambe le parti estratte dal percorso URL e un parametro di query:

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

Come nota a margine, troverai il metodo di richiesta (in questo caso "GET"e per i moduli inviati di solito "POST") in request.method. In alcuni casi è utile verificare che corrisponda a ciò che ti aspetti.

Aggiornamento: quando si decide se utilizzare il percorso URL o i parametri della query per il passaggio di informazioni, potrebbe essere utile quanto segue:

  • utilizzare il percorso URL per identificare in modo univoco le risorse, ad es. /blog/post/15/(no /blog/posts/?id=15)
  • utilizzare i parametri di query per modificare la modalità di visualizzazione della risorsa, ad es. /blog/post/15/?show_comments=1o/blog/posts/2008/?sort_by=date&direction=desc
  • per creare URL umani, evitare l'uso di numeri ID e utilizzare, ad esempio, date, categorie e / o lumache: /blog/post/2008/09/30/django-urls/

17
Questa è una risposta davvero ben scritta. Mi ha sicuramente aiutato a capire un po 'meglio Django.
Mark

2
come possiamo ottenere tutti i valori dei parametri senza menzionare i nomi
numerah

@numerah request.GET è un dizionario Python. Puoi ad esempio iterare attraverso request.GET.items ().
Akaihola,

risposta perfetta
Jay Geeth,

1
qualche motivo per cui si preferisce seguire le abitudini scritte nell'aggiornamento? (quando utilizzare il percorso URL vs parametri GET)
m0etaz

55

Utilizzando GET

request.GET["id"]

Utilizzando POST

request.POST["id"]

27
Mentre questo funziona per chiavi esistenti, le risposte di camflan e akaihola hanno usato .get () per evitare KeyErroreccezioni nel caso di una chiave mancante. Sarebbe saggio fare lo stesso (ad es request.POST.get('id', '').).
vastlysuperiorman,

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

21

Per situazioni in cui hai solo l' requestoggetto che puoi usarerequest.parser_context['kwargs']['your_param']


2
Esattamente quello di cui avevo bisogno. Grazie.
user4052054

20

Vorrei aggiungere qualche opzione di me stesso, qui. Qualcuno si chiederebbe come impostare il percorso in urls.py, come ad esempio

domain/search/?q=CA

in modo da poter invocare la query.

Il fatto è che NON è necessario impostare tale percorso in urls.py. Quello che devi impostare è solo il percorso in urls.py

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

e quando si immette http: // servername: port / dominio / ricerca / q = CA . La parte della query '? Q = CA' verrà automaticamente prenotata nella tabella hash a cui puoi fare riferimento

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

Ecco un esempio (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

Inoltre, quando si scrive una stringa di query in URL

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

Non racchiudere la stringa di query tra virgolette, ad es

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

Ciao Eric! Sono nuovo di Django. Puoi far luce su "queryset = queryset.filter (state__name = state_name)". Cosa significa il doppio trattino di sottolineatura in state__name.
Subbu,

1
Qui "state" è una tabella e "name" è archiviato in questa tabella. Nel filtro di Django, state__name farà riferimento al valore del campo "name" nella tabella "state".
Eric Andrews

questo ha funzionato rispetto ad altri.
Sibish,

17

Vorrei condividere un suggerimento che potrebbe farti risparmiare un po 'di tempo.
Se prevedi di utilizzare qualcosa di simile nel tuo urls.pyfile:

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

Il che significa sostanzialmente www.example.com/<username>. Assicurati di posizionarlo alla fine delle voci dell'URL, perché altrimenti è incline a causare conflitti con le voci dell'URL che seguono di seguito, vale a dire l'accesso a una di esse ti darà il bel errore: l' User matching query does not exist.

ho appena sperimentato da solo; spero che sia d'aiuto!


2
Inoltre, in questo caso potresti voler verificare che i nomi utente non si scontrino con altri URL.
DrKaoliN,

13

Hai due modi comuni per farlo nel caso in cui il tuo URL assomigli a quello:

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

v1:

Se la chiave specifica è obbligatoria è possibile utilizzare:

key_a = request.GET['a']

Ciò restituirà un valore di aif chiave esiste e un'eccezione in caso contrario.

v2:

Se le tue chiavi sono opzionali:

request.GET.get('a')

Puoi provare che senza alcun argomento questo non andrà in crash. Quindi puoi avvolgerlo try: except:e tornare HttpResponseBadRequest()nell'esempio. Questo è un modo semplice per rendere il codice meno complesso, senza utilizzare la gestione delle eccezioni speciale.


come posso rilevare i parametri di query dal modello?
Akin Hwan,


5

Queste query sono attualmente eseguite in due modi. Se si desidera accedere ai parametri di query (GET), è possibile eseguire una query su quanto segue:

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

Se si desidera accedere ai parametri passati da POST, è necessario accedere in questo modo:

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

Accedendo al dizionario (QueryDict) con 'get ()', è possibile impostare un valore predefinito. Nei casi precedenti, se "stato" o "ruolo" non vengono informati, i valori sono Nessuno.


0

Questa è un'altra soluzione alternativa che può essere implementata:

nella configurazione dell'URL. :

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

nelle viste:

list2 = queryparams.split("&")
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.