Django: número arbitrário de parâmetros urls.py sem nome

votos
16

Eu tenho um modelo Django com um grande número de campos e 20000+ linhas da tabela. Para facilitar URLs legíveis humanos e a capacidade de quebrar a lista grande em sublists arbitrárias, eu gostaria de ter uma URL parecida com esta:

/browse/<name1>/<value1>/<name2>/<value2>/ .... etc ....

onde 'nome' mapeia para um atributo de modelo e 'valor' é os critérios de pesquisa para esse atributo. Cada nome será tratado como uma categoria para retornar subconjuntos das instâncias do modelo em que as categorias correspondem.

Agora, isso pode ser tratado com parâmetros GET, mas eu prefiro URLs mais legíveis, tanto para o bem do usuário e os motores de busca. Esses URLs subconjuntos será incorporado em cada página que exibe este modelo, por isso parece vale a pena o esforço para fazer URLs bonitas.

Idealmente, cada par nome / valor será passado para a função de visão como um parâmetro nomeado name1, name2etc. No entanto, eu não acredito que é possível a padrões chamados definidos via texto correspondente de um regex. Estou errado lá?

Assim, parece que eu preciso fazer algo como isto:

urlpatterns = patterns('',
    url(r'^browse/(?:([\w]+)/([\w]+)/)+$', 'app.views.view', name=model_browse),
)

Parece que este deve corresponder quaisquer conjuntos de dois pares de nome / valor. Enquanto ele corresponde com sucesso, ele só passa o último par de nome / valor como parâmetros para a função view. Meu palpite é que cada jogo está substituindo a correspondência anterior. Sob a suposição de que o contendo (?: ...) + está causando isso, eu tentei um padrão de repetição simples em vez disso:

urlpatterns = patterns('',
    url(r'^browse/([\w]+/)+$', 'app.views.view', name=model_browse),
)

... e tenho o mesmo problema, mas desta vez *argsinclui apenas o último padrão correspondido.

Será esta uma limitação do expedidor url do Django, e / ou apoio regex do Python? Parece um desses métodos deve funcionar. padrão Existe uma maneira de conseguir isso sem codificar cada atributo possível modelo na URL como um opcional (*).?

Publicado 30/10/2008 em 03:18
fonte usuário
Em outras línguas...                            


5 respostas

votos
13

A possibilidade de que você pode considerar é combinar toda a cadeia de valores possíveis dentro da porção padrão de URL e retirar as peças específicas dentro de sua visão. Como um exemplo:

urlpatterns = patterns('',
    url(r'^browse/(?P<match>.+)/$', 'app.views.view', name='model_browse'),
)

def view(request, match):
    pieces = match.split('/')
    # even indexed pieces are the names, odd are values
    ...

Sem promessas sobre o regexp que eu usei, mas eu acho que você entende o que quero dizer.

(Editado para tentar corrigir o regexp).

Respondeu 30/10/2008 em 08:52
fonte usuário

votos
3

Concordo com Adam, mas acho que o padrão em urls.py deve ser:

... r'^browse/(?P<match>.+)/$' ...

O '\ w' só irá coincidir com caracteres 'palavra', mas o '. irá corresponder a qualquer coisa.

Respondeu 30/10/2008 em 19:32
fonte usuário

votos
0

Eu tenho uma solução alternativa, que não é muito diferente da anterior, mas é mais refinado:

url(r'^my_app/(((list\/)((\w{1,})\/(\w{1,})\/(\w{1,3})\/){1,10})+)$'

Eu usei parâmetros de URL sem nome e uma expressão regular repetitivo. Não para obter o "não é uma expressão regular válida: múltiplo repeat" i colocar uma palavra no início da lista.

Eu ainda estou trabalhando com a vista de receber a lista. Mas eu acho mal' percorrer os argumentos ou kwargs .. Não é possível ainda dizer exatamente.

Meus 2 centavos

Respondeu 23/02/2016 em 10:37
fonte usuário

votos
0

Acho que a resposta de Adão é mais genérico do que a minha solução, mas se você gosta de usar um número fixo de argumentos no URL, você também poderia fazer algo parecido com isto:

O exemplo a seguir mostra como obter todas as vendas de um dia para um local, digitando o nome do storee year, monthe day.

urls.py :

urlpatterns = patterns('',
    url(r'^baseurl/location/(?P<store>.+)/sales/(?P<year>[0-9][0-9][0-9][0-9])-(?P<month>[0-9][0-9])-(?P<day>[0-9][0-9])/$', views.DailySalesAtLocationListAPIView.as_view(), name='daily-sales-at-location'),
)

Alternativly, você também pode usar o ID da loja mudando (?P<store>.+)para (?P<store>[0-9]+). Note-se que locatione saleshá palavras-chave, eles só melhorar a legibilidade da url.

views.py

class DailySalesAtLocationListAPIView(generics.ListAPIView):
    def get(self, request, store, year, month, day):
        # here you can start using the values from the url
        print store
        print year
        print month
        print date

        # now start filtering your model

Espero que ajude alguém!

Cumprimentos,

Michael

Respondeu 15/10/2013 em 11:15
fonte usuário

votos
0

Mesma resposta me veio ao ler a pergunta.

Acredito vista model_browse é a melhor maneira de classificar os parâmetros de consulta e usá-lo como um roteador genérico.

Respondeu 01/11/2008 em 00:31
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more