Domanda

Ho un modello Django con un gran numero di campi e oltre 20000 righe di tabella. Per facilitare gli URL leggibili dall'uomo e la possibilità di suddividere l'elenco di grandi dimensioni in elenchi arbitrari, vorrei avere un URL simile al seguente:

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

dove "name" è associato a un attributo del modello e "value" sono i criteri di ricerca per quell'attributo. Ogni & Quot; nome & Quot; verrà trattato come una categoria per restituire sottoinsiemi delle istanze del modello in cui le categorie corrispondono.

Ora, questo potrebbe essere gestito con i parametri GET, ma preferisco URL più leggibili sia per il bene dell'utente che per i motori di ricerca. Questi sottoinsiemi di URL verranno incorporati in ogni pagina che mostra questo modello, quindi sembra che valga la pena fare degli URL carini.

Idealmente ogni coppia nome / valore verrà passata alla funzione di visualizzazione come parametro denominato name1, name2, ecc. Tuttavia, non credo che sia possibile definire modelli nominati tramite il testo corrispondente di una regex. Sbaglio lì?

Quindi, sembra che debba fare qualcosa del genere:

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

Sembra che questo dovrebbe corrispondere a qualsiasi set di due coppie nome / valore. Sebbene corrisponda correttamente, passa solo la coppia cognome / valore come parametri alla funzione di visualizzazione. La mia ipotesi è che ogni partita sovrascrive la partita precedente. Con la supposizione che il contenitore (?: ...) + lo stia causando, ho provato invece un semplice schema ripetuto:

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

... e ha riscontrato lo stesso problema, ma questa volta *args include solo l'ultimo modello corrispondente.

È una limitazione del dispatcher di URL di Django e / o del supporto regex di Python? Sembra che uno di questi metodi dovrebbe funzionare. Esiste un modo per raggiungere questo obiettivo senza codificare ogni possibile attributo del modello nell'URL come modello facoltativo (. *)?

È stato utile?

Soluzione

Una possibilità che potresti prendere in considerazione è quella di abbinare l'intera stringa di possibili valori all'interno della porzione del pattern url ed estrarre i pezzi specifici nella tua vista. Ad esempio:

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

Nessuna promessa sulla regexp che ho usato, ma penso che tu capisca cosa intendo.

(Modificato per provare a correggere il regexp.)

Altri suggerimenti

Sono d'accordo con Adam, ma penso che lo schema in urls.py dovrebbe essere:

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

'\ w' corrisponderà solo ai caratteri 'word', ma '.' corrisponderà a qualsiasi cosa.

La stessa risposta mi è arrivata mentre leggevo la domanda.

Credo che la vista model_browse sia il modo migliore per ordinare i parametri della query e usarlo come router generico.

Penso che la risposta di Adam sia più generica della mia soluzione, ma se ti piace usare un numero fisso di argomenti nell'URL, potresti anche fare qualcosa del genere:

L'esempio seguente mostra come ottenere tutte le vendite di un giorno per una posizione inserendo il nome di store e 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'),
)

In alternativa, puoi anche utilizzare l'id del negozio cambiando (?P<store>.+) in (?P<store>[0-9]+). Nota che location e sales non sono parole chiave, ma migliorano semplicemente la leggibilità dell'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

Spero che aiuti chiunque!

Cordiali saluti,

Michael

Ho una soluzione alternativa, che non è molto diversa dalla precedente ma è più raffinata:

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

Ho usato parametri url senza nome e un regexp ripetitivo. Non ottenere il & Quot; non è un'espressione regolare valida: ripetizione multipla & Quot; inserisco una parola all'inizio dell'elenco.

Sto ancora lavorando alla vista che riceve l'elenco. Ma penso che andrò attraverso args o kwargs. Non posso ancora dirlo esattamente.

I miei 2 centesimi

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top