Capturando parâmetros de URL em request.GET

458

Atualmente, estou definindo expressões regulares para capturar parâmetros em um URL, conforme descrito no tutorial. Como acesso parâmetros da URL como parte do HttpRequestobjeto? Meu HttpRequest.GETatualmente retorna um QueryDictobjeto vazio .

Eu gostaria de aprender como fazer isso sem uma biblioteca para que eu possa conhecer melhor o Django.

sutee
fonte

Respostas:

662

Quando url é como:,domain/search/?q=haha então você usaria request.GET.get('q', '').

qé o parâmetro que você deseja e ''é o valor padrão se qnão for encontrado.

No entanto, se você estiver apenas configurando seuURLconf , suas capturas regexserão passadas para a função como argumentos (ou argumentos nomeados).

Tal como:

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

Então no seu views.pyvocê teria

def profile_page(request, username):
    # Rest of the method
camflan
fonte
10
'? Param =' é a única maneira de o Django reconhecer parâmetros? Existe uma maneira de usar URLconf com HTTP.GET? Eu gostaria de fazer / param / 2.
sutee 29/09/08
3
Verifique a segunda parte da minha resposta sobre suas capturas de URLconf e regex.
camflan 29/09/08
2
Sem problemas. use request.GET se você enviar um formulário usando GET, use request.POST se você enviar um formulário usando POST e se desejar apenas configurar URLs para ter seções variáveis, será um argumento URLconf / view.
camflan 29/09/08
10
E as visualizações baseadas em classe?
Utilizador
8
para vistas de classe base você pode usarself.kwargs['parameter']
Royendgel Silberie
336

Para esclarecer a explicação do camflan, vamos supor que você tenha

  • a regra url(regex=r'^user/(?P<username>\w{1,50})/$', view='views.profile_page')
  • um pedido de entrada para http://domain/user/thaiyoshi/?message=Hi

A regra do expedidor de URL captura as partes do caminho da URL (aqui "user/thaiyoshi/") e as passa para a função de visualização junto com o objeto de solicitação.

A string de consulta (aqui message=Hi) é analisada e os parâmetros são armazenados como um QueryDictin request.GET. Nenhuma correspondência ou processamento adicional para os parâmetros HTTP GET é feito.

Essa função de exibição usaria as duas partes extraídas do caminho da URL e um parâmetro de consulta:

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

Como observação, você encontrará o método de solicitação (neste caso "GET", e para os formulários enviados normalmente "POST") em request.method. Em alguns casos, é útil verificar se corresponde ao que você está esperando.

Atualização: Ao decidir se deseja usar o caminho da URL ou os parâmetros de consulta para transmitir informações, o seguinte pode ajudar:

  • use o caminho da URL para identificar recursos exclusivamente, por exemplo /blog/post/15/(não /blog/posts/?id=15)
  • use parâmetros de consulta para alterar a maneira como o recurso é exibido, por exemplo, /blog/post/15/?show_comments=1ou/blog/posts/2008/?sort_by=date&direction=desc
  • para criar URLs amigáveis ​​para o ser humano, evite usar números de identificação e use, por exemplo, datas, categorias e / ou lesmas: /blog/post/2008/09/30/django-urls/
akaihola
fonte
17
Esta é uma resposta muito bem escrita. Com certeza me ajudou a entender o Django um pouco melhor.
Mark
2
como podemos obter valores de todos os parâmetros, sem mencionar nomes
numerah
@numerah request.GET é um dicionário Python. Você pode, por exemplo, iterar através de request.GET.items ().
akaihola
resposta perfeita.
Jay Geeth 27/02
1
Por que é preferível seguir os hábitos escritos na atualização? (quando usar caminho URL vs GET params)
m0etaz
55

Usando GET

request.GET["id"]

Usando POST

request.POST["id"]
Dadaso Zanzane
fonte
27
Enquanto isso funciona para as chaves existentes, as respostas de camflan e akaihola usaram .get () para evitar KeyErrorexceções no caso de falta de uma chave. Seria sensato fazer o mesmo (por exemplo request.POST.get('id', '')).
vastlysuperiorman
25
def some_view(request, *args, **kwargs):
    if kwargs.get('q', None):
        # Do something here ..
Kevin
fonte
21

Para situações em que você só tem o requestobjeto, pode usarrequest.parser_context['kwargs']['your_param']

Ole Henrik Skogstrøm
fonte
2
Exatamente o que eu precisava. Obrigado.
user4052054
20

Eu gostaria de adicionar uma opção minha aqui. Alguém gostaria de saber como definir o caminho em urls.py, como

domain/search/?q=CA

para que pudéssemos chamar a consulta.

O fato é que NÃO é necessário definir essa rota em urls.py. O que você precisa definir é apenas a rota em urls.py

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

e quando introduzir http: // servername: port / domínio / pesquisa / q = CA . A parte da consulta '? Q = CA' será automaticamente reservada na tabela de hash que você pode referenciar

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

Aqui está um exemplo (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

Além disso, quando você escreve uma string de consulta no URL

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

Não coloque a string de consulta entre aspas, por exemplo

http://servername:port/domain/search/?q="CA"
Eric Andrews
fonte
Oi Eric! Eu sou novo no Django. Você pode esclarecer mais sobre "queryset = queryset.filter (state__name = state_name)". O que o sublinhado duplo em state__name significa.
subbu
1
Aqui "state" é uma tabela e "name" é arquivado nesta tabela. No filtro do Django, state__name fará referência ao valor do campo "name" na tabela "state".
Eric Andrews
este funcionou em comparação com os outros.
Sibish 15/04
17

Gostaria de compartilhar uma dica que pode economizar algum tempo.
Se você planeja usar algo parecido com isto em seu urls.pyarquivo:

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

O que basicamente significa www.example.com/<username>. Não se esqueça de colocá-lo no final de suas entradas de URL, pois, caso contrário, é provável que cause conflitos com as entradas de URL a seguir, ou seja, acessar uma delas causará o erro de erro: User matching query does not exist.

acabei de experimentar; espero que ajude!

DrKaoliN
fonte
2
Além disso, nesse caso, convém verificar se os nomes de usuário não colidem com outros URLs.
DrKaoliN
13

Você tem duas maneiras comuns de fazer isso, caso seu URL seja assim:

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

v1:

Se chave específica é obrigatória, você pode usar:

key_a = request.GET['a']

Isso retornará um valor de aif key e uma exceção, se não existir.

v2:

Se suas chaves são opcionais:

request.GET.get('a')

Você pode tentar que, sem qualquer argumento, isso não trava. Então você pode envolvê-lo try: except:e retornar HttpResponseBadRequest()no exemplo. Essa é uma maneira simples de tornar seu código menos complexo, sem usar o tratamento de exceções especiais.

Bartłomiej
fonte
como posso detectar parâmetros de consulta do modelo?
Akin Hwan
8

Isso não é exatamente o que você pediu, mas esse trecho é útil para a gestão query_stringsem templates.

interferência
fonte
5

Atualmente, essas consultas são feitas de duas maneiras. Se você deseja acessar os parâmetros de consulta (GET), pode consultar o seguinte:

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

Se você deseja acessar os parâmetros passados ​​pelo POST, é necessário acessar desta maneira:

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

Acessando o dicionário (QueryDict) com 'get ()', você pode definir um valor padrão. Nos casos acima, se 'status' ou 'role' não forem informados, os valores serão Nenhum.

mdcg
fonte
0

Esta é outra solução alternativa que pode ser implementada:

na configuração do URL. :

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

nas visualizações:

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