Capture des paramètres d'URL dans la demande.

458

Je définis actuellement des expressions régulières afin de capturer des paramètres dans une URL, comme décrit dans le tutoriel. Comment accéder aux paramètres depuis l'URL en tant que partie de l' HttpRequestobjet? Mon HttpRequest.GETretourne actuellement un QueryDictobjet vide .

J'aimerais apprendre à faire cela sans bibliothèque pour mieux connaître Django.

sutee
la source

Réponses:

662

Lorsque l'url est comme:,domain/search/?q=haha alors vous utiliseriez request.GET.get('q', '').

qest le paramètre que vous voulez, et ''est la valeur par défaut s'il qn'est pas trouvé.

Cependant, si vous configurez simplement votreURLconf , alors vos captures de la regexsont transmises à la fonction en tant qu'arguments (ou arguments nommés).

Tel que:

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

Ensuite, dans votre views.pyvous auriez

def profile_page(request, username):
    # Rest of the method
camflan
la source
10
'? Param =' est-il la seule façon dont Django reconnaît les paramètres? Existe-t-il un moyen d'utiliser URLconf avec HTTP.GET? Je voudrais faire / param / 2.
sutee
3
Consultez la deuxième partie de ma réponse concernant vos captures URLconf et regex.
camflan
2
Aucun problème. utilisez request.GET si vous soumettez un formulaire en utilisant GET, utilisez request.POST si vous soumettez un formulaire en utilisant POST, et si vous voulez simplement configurer les URL pour avoir des sections variables, alors c'est un argument URLconf / view.
camflan
10
Qu'en est-il des vues basées sur les classes?
Utilisateur
8
pour des vues basées sur la classe que vous pouvez utiliserself.kwargs['parameter']
Royendgel Silberie
336

Pour clarifier l'explication de camflan, supposons que vous ayez

  • la règle url(regex=r'^user/(?P<username>\w{1,50})/$', view='views.profile_page')
  • une demande entrante de http://domain/user/thaiyoshi/?message=Hi

La règle de répartiteur d'URL interceptera des parties du chemin URL (ici "user/thaiyoshi/") et les transmettra à la fonction d'affichage avec l'objet de demande.

La chaîne de requête (ici message=Hi) est analysée et les paramètres sont stockés sous la forme d'un QueryDictin request.GET. Aucune autre correspondance ou traitement des paramètres HTTP GET n'est effectué.

Cette fonction d'affichage utiliserait les deux parties extraites du chemin URL et un paramètre de requête:

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

En remarque, vous trouverez la méthode de demande (dans ce cas "GET", et pour les formulaires soumis généralement "POST") dans request.method. Dans certains cas, il est utile de vérifier qu'il correspond à ce que vous attendez.

Mise à jour: lorsque vous décidez d'utiliser le chemin URL ou les paramètres de requête pour transmettre des informations, les éléments suivants peuvent être utiles:

  • utiliser le chemin URL pour identifier de manière unique les ressources, par exemple /blog/post/15/(pas /blog/posts/?id=15)
  • utiliser des paramètres de requête pour changer la façon dont la ressource est affichée, par exemple /blog/post/15/?show_comments=1ou/blog/posts/2008/?sort_by=date&direction=desc
  • pour créer des URL conviviales, évitez d'utiliser des numéros d'identification et utilisez par exemple des dates, des catégories et / ou des limaces: /blog/post/2008/09/30/django-urls/
akaihola
la source
17
Ceci est une réponse très bien écrite. Cela m'a certainement aidé à mieux comprendre Django.
Mark
2
comment pouvons-nous obtenir toutes les valeurs des paramètres sans mentionner de noms
numerah
@numerah request.GET est un dictionnaire Python. Vous pouvez par exemple itérer via request.GET.items ().
akaihola
réponse parfaite.
Jay Geeth
1
des raisons pour lesquelles il est préférable de suivre les habitudes écrites dans la mise à jour? (quand utiliser le chemin URL par rapport aux paramètres GET)
m0etaz
55

Utiliser GET

request.GET["id"]

Utilisation de POST

request.POST["id"]
Dadaso Zanzane
la source
27
Bien que cela fonctionne pour les clés existantes, les réponses de camflan et akaihola ont utilisé .get () pour éviter les KeyErrorexceptions dans le cas d'une clé manquante. Il serait sage de faire de même (par exemple request.POST.get('id', '')).
vastlysuperiorman
25
def some_view(request, *args, **kwargs):
    if kwargs.get('q', None):
        # Do something here ..
Kevin
la source
21

Pour les situations où vous n'avez que l' requestobjet que vous pouvez utiliserrequest.parser_context['kwargs']['your_param']

Ole Henrik Skogstrøm
la source
2
Exactement ce dont j'avais besoin. Merci.
user4052054
20

Je voudrais ajouter une option de moi-même, ici. Quelqu'un se demanderait comment définir le chemin dans urls.py, tel que

domain/search/?q=CA

afin que nous puissions invoquer la requête.

Le fait est qu'il n'est PAS nécessaire de définir une telle route dans urls.py. Ce que vous devez définir est simplement l'itinéraire dans urls.py

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

et quand vous entrez http: // nomserveur: port / domaine / Recherche / q = CA . La partie de requête '? Q = CA' sera automatiquement réservée dans la table de hachage que vous pouvez référencer

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

Voici un exemple (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

En outre, lorsque vous écrivez une chaîne de requête en URL

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

N'encapsulez pas la chaîne de requête entre guillemets, par exemple

http://servername:port/domain/search/?q="CA"
Eric Andrews
la source
Salut Eric! Je suis nouveau à Django. Pouvez-vous faire plus de lumière sur "queryset = queryset.filter (state__name = state_name)". Que signifie le double soulignement dans state__name?
Subbu
1
Ici, "état" est un tableau et "nom" est un fichier dans ce tableau. Dans le filtre de Django, state__name fera référence à la valeur du champ "nom" dans la table "state".
Eric Andrews
celui-ci a fonctionné par rapport aux autres.
Sibish
17

Je voudrais partager un conseil qui pourrait vous faire gagner du temps.
Si vous prévoyez d'utiliser quelque chose comme ça dans votre urls.pyfichier:

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

Ce qui signifie essentiellement www.example.com/<username>. Assurez-vous de le placer à la fin de vos entrées URL, car sinon, il est susceptible de provoquer des conflits avec les entrées URL qui suivent ci-dessous, c'est-à-dire que l'accès à l'une d'entre elles vous donnera la bonne erreur: User matching query does not exist.

je viens de la vivre moi-même; J'espère que cela aide!

DrKaoliN
la source
2
De plus, dans ce cas, vous voudrez peut-être vérifier que les noms d'utilisateur ne se heurtent pas à d'autres entrées d'URL.
DrKaoliN
13

Vous avez deux façons courantes de le faire au cas où votre URL ressemble à ça:

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

v1:

Si une clé spécifique est obligatoire, vous pouvez utiliser:

key_a = request.GET['a']

Cela renverra une valeur de asi la clé existe et une exception dans le cas contraire.

v2:

Si vos clés sont facultatives:

request.GET.get('a')

Vous pouvez essayer cela sans argument, cela ne plantera pas. Vous pouvez donc envelopper avec try: except:et revenir HttpResponseBadRequest()en exemple. C'est un moyen simple de rendre votre code moins complexe, sans utiliser de gestion d'exceptions spéciale.

Bartłomiej
la source
comment puis-je détecter les paramètres de requête dans le modèle?
Akin Hwan
8

Ce n'est pas exactement ce que vous avez demandé, mais cet extrait est utile pour la gestion query_stringsdans templates.

brouillage
la source
5

Ces requêtes sont actuellement effectuées de deux manières. Si vous souhaitez accéder aux paramètres de requête (GET), vous pouvez interroger les éléments suivants:

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

Si vous souhaitez accéder aux paramètres passés par POST, vous devez accéder de cette façon:

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

En accédant au dictionnaire (QueryDict) avec 'get ()', vous pouvez définir une valeur par défaut. Dans les cas ci-dessus, si 'status' ou 'role' ne sont pas informés, les valeurs sont None.

mdcg
la source
0

Ceci est une autre solution alternative qui peut être mise en œuvre:

dans la configuration url. :

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

dans les vues:

list2 = queryparams.split("&")
sachi
la source