Pergunta

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 subconjuntos de retorno das instâncias do modelo em que as categorias correspondem.

Agora, isso poderia ser manuseados 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, name2, etc. 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 teste 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 *args inclui apenas o último padrão correspondido.

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

Foi útil?

Solução

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).

Outras dicas

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

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

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

A mesma resposta me veio ao ler a pergunta.

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

Eu 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 store eo year, month e 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 alterando (?P<store>.+) para (?P<store>[0-9]+). Note-se que location e sales há palavras-chave, eles só melhorar a legibilidade do 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

Hope isso ajuda ninguém!

Com os melhores cumprimentos,

Michael

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 não identificadas e uma regexp 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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top