2008-10-30 10 views
16

Mam model Django z dużą liczbą pól i 20000 wierszami tabeli. Aby ułatwić czytelne dla człowieka adresy i zdolność do rozbicia dużą listę do arbitralnych podlist chciałbym mieć adres URL, który wygląda tak:Django: dowolna liczba nienazwanych parametrów urls.py

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

gdzie mapy „name” do atrybutu modelu i „wartość” to kryteria wyszukiwania dla tego atrybutu. Każda "nazwa" będzie traktowana jak kategoria, która zwróci podzestawy instancji modelu, w których kategorie się zgadzają.

Teraz można to obsłużyć za pomocą parametrów GET, ale wolę bardziej czytelne adresy URL zarówno dla użytkownika, jak i dla wyszukiwarek. Te podzbiory adresów URL będą osadzone na każdej stronie wyświetlającej ten model, więc warto wykonać ładny URL.

Idealnie każda para nazwa/wartość zostanie przekazana do funkcji widoku jako parametr o nazwie name1, name2 itp. Jednak nie sądzę, że możliwe jest zdefiniowanie nazwanych wzorców za pomocą dopasowanego tekstu wyrażeń regularnych. Czy jestem w błędzie?

Więc wydaje się, że trzeba zrobić coś takiego:

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

Wydaje powinno to dało żadnych zestawów dwóch par nazwa/wartość. Mimo że pasuje do niego pomyślnie, przekazuje on tylko ostatnią parę nazwa/wartość jako parametry do funkcji widoku. Domyślam się, że każdy mecz nadpisuje poprzedni mecz. Zgodnie z przypuszczeniem, że zawiera (?: ...) + powoduje to, próbowałem prosty powtarzający się wzór Zamiast:

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

... i mam ten sam problem, ale tym razem *args obejmuje tylko ostatnie dopasowany wzór.

Czy jest to ograniczenie dla modułu Django do wywoływania adresów URL i/lub obsługi regex w języku Python? Wygląda na to, że jedna z tych metod powinna działać. Czy istnieje sposób, aby to osiągnąć bez zakodowania na sztywno każdego możliwego atrybutu modelu w adresie URL jako opcjonalnego wzorca (. *)?

+0

myślę, że wdrożenie „GET zapytania jak” params klucz-wartość używając url sam w sobie jest nieco brzydki, a nie „true”. –

+0

@alex - oprócz tego, że URL nie jest czytelny, wyszukiwarki prawdopodobnie nie będą indeksować całej zawartości, jeśli masz więcej niż kilka parametrów get (jeśli tak). –

Odpowiedz

11

Możliwość, którą możesz rozważyć, dopasowuje cały łańcuch możliwych wartości w części wzorcowej adresu URL i wyciąga określone elementy w widoku. Na przykład:

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

Brak obietnic dotyczących regexp, którego używałem, ale myślę, że rozumiesz o co mi chodzi.

(Zmieniano aby spróbować naprawić regexp).

+0

Dzięki, zgadzam się, że jest to prawdopodobnie najłatwiejszy sposób na rozwiązanie tego problemu. –

+1

Aby umieścić tutaj tekst dla innych osób w mojej sytuacji, jest to jedyne rozwiązanie, które znalazłem do analizowania dowolnej liczby elementów macierzy w [URI macierzy] (http://www.w3.org/DesignIssues/MatrixURIs .html). Dopasuj wszystkie elementy macierzy, a następnie przeanalizuj w widoku. – KobeJohn

+1

to samo tutaj, a to jest 2016 – benzkji

3

zgadzam się z Adamem, ale myślę, że wzór w urls.py powinno być:

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

The '\ W' tylko mecz znaki "słowo", ale "." dopasuje wszystko.

+0

Jestem okropny w wyrażeniach regularnych i po prostu odgadłem, heh. – Adam

0

Ta sama odpowiedź przyszła mi podczas czytania pytania.

Uważam, że widok model_browse jest najlepszym sposobem sortowania parametrów zapytania i używania go jako ogólnego routera.

0

Myślę, że odpowiedź Adama jest bardziej ogólne niż moje rozwiązanie, ale jeśli chcesz używać stałą liczbę argumentów w adresie URL, można też zrobić coś takiego:

Poniższy przykład pokazuje, jak uzyskać całą sprzedaż dnia dla lokalizacji, wprowadzając nazwę store i year, month i .

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, można również użyć id sklepu zmieniając (?P<store>.+) do (?P<store>[0-9]+). Pamiętaj, że location i sales nie są słowami kluczowymi, tylko poprawiają czytelność adresu 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 

Nadzieja pomaga nikomu!

poważaniem,

Michael

0

Mam alternatywne rozwiązanie, które nie jest zupełnie inny od poprzedniego, ale to bardziej wyrafinowane:

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

ja używałem unnamed url parameters i powtarzające się wyrażenie regularne. Aby nie uzyskać "nie jest prawidłowym wyrażeniem regularnym: wielokrotne powtórzenie", umieszczam słowo na początku listy.

Nadal pracuję w widoku, otrzymując listę. Ale myślę, że źle "przejść przez args lub kwargs ... Nie mogę jeszcze powiedzieć dokładnie.

Moje 2 centów

Powiązane problemy