2008-10-30 4 views
16

У меня есть модель Django с большим количеством полей и 20000 + строк таблицы. Для облегчения читаемой URL-адресов человека и способности расщеплять большой список в произвольные подсписки, я хотел бы иметь URL, который выглядит следующим образом:Django: произвольное количество неизвестных параметров urls.py

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

где «имя» карта к атрибуту модели и «значения» это критерии поиска для этого атрибута. Каждое «имя» будет рассматриваться как категория для возврата подмножеств экземпляров модели, в которых соответствуют категории.

Теперь это можно обрабатывать с помощью параметров GET, но я предпочитаю более читаемые URL-адреса как для пользователя, так и для поисковых систем. Эти подмножества URL-адресов будут встроены на каждую страницу, отображающую эту модель, поэтому, похоже, стоит сделать красивые URL-адреса.

В идеале каждое имя/значение пара будет передана функции просмотра в качестве параметра с именем name1, name2 и т.д. Тем не менее, я не считаю, что это возможно, определенными именованными шаблоны с помощью согласованного текста регулярных выражений в. Я там не прав?

Таким образом, кажется, что мне нужно сделать что-то вроде этого:

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

Кажется, это должно соответствовать любые наборы из двух пар имя/значение. Хотя он успешно совпадает с ним, он передает только пару последних имен/значений в качестве параметров функции просмотра. Я предполагаю, что каждый матч переписывает предыдущий матч. Под предположение, что содержащий (?: ...) + вызывает это, я попытался простой повторяющийся узор вместо:

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

... и получил ту же проблему, но на этот раз *args включает в себя только последний согласованный шаблон.

Является ли это ограничителем диспетчера сообщений Django и/или поддержкой регулярного выражения Python? Кажется, что любой из этих методов должен работать. Есть ли способ достичь этого без жесткого кодирования каждого возможного атрибута модели в URL как дополнительный (. *) Шаблон?

+0

Я думаю, что реализовать «GET запрос типа» ключ-значение Params с помощью URL само по себе является немного некрасиво и не «истинный». – 2008-11-03 17:01:26

+0

@alex - кроме того, что URL-адрес не читается, поисковые системы, вероятно, не будут индексировать весь ваш контент, если у вас есть пара, получающая параметры (если это). – 2009-03-23 16:37:33

ответ

11

Возможность, которую вы можете рассмотреть, соответствует всей строке возможных значений в части шаблона url и вытаскивать конкретные фрагменты в вашем представлении. В качестве примера:

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

Никаких обещаний о регулярном выражении, которое я использовал, но я думаю, вы понимаете, что я имею в виду.

(под редакцией, чтобы попытаться исправить регулярное выражение.)

+0

Спасибо, я согласен, что это, наверное, самый простой способ справиться с этой проблемой. – 2008-10-30 23:53:52

3

Я согласен с Адамом, но я думаю, что картина в urls.py должна быть:

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

В «\ W» соответствует только «слова», но «.» будет соответствовать чему угодно.

0

Тот же ответ пришел ко мне, читая вопрос.

Я считаю, что model_browse view является наилучшим способом сортировки параметров запроса и использования его в качестве родового маршрутизатора.

0

Я думаю, что ответ Адама является более общим, чем мое решение, но если вы хотите использовать фиксированное количество аргументов в URL, вы также можете сделать что-то вроде этого:

В следующем примере показано, как получить все продажи за день за место, введя имя store и year, month и 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, вы можете также использовать идентификатор магазина, изменяя (?P<store>.+) в (?P<store>[0-9]+). Обратите внимание, что location и sales не являются ключевыми словами, они просто улучшают читаемость 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 

Надеется, что это помогает кто-нибудь!

С наилучшими пожеланиями,

Майкл

0

Я альтернативное решение, которое не сильно отличается от предыдущего, но это более изощренными:

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

Я использовал unnamed url parameters и повторяющееся регулярное выражение. Не получить «не является правильным регулярным выражением: множественное повторение». Я помещаю слово в начале списка.

Я все еще работаю над тем, чтобы получить список. Но я думаю, что плохо «пройти через арги или кварты». Не могу сказать это точно.

Мои 2 цента