Подтвердить что ты не робот

Django: произвольное количество неназванных параметров urls.py

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

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

где 'name' сопоставляется с атрибутом модели, а 'value' - критерием поиска для этого атрибута. Каждое "имя" будет рассматриваться как категория для возврата подмножеств экземпляров модели, в которых соответствуют категории.

Теперь это можно обрабатывать с помощью параметров 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 включен только последний сопоставленный шаблон.

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

4b9b3361

Ответ 1

Возможность, которую вы можете рассмотреть, соответствует всей строке возможных значений в части шаблона 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
    ...

No promises о регулярном выражении, которое я использовал, но я думаю, вы понимаете, что я имею в виду.

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

Ответ 2

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

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

"\ w" будет соответствовать только символам "word", но "." будет соответствовать чему-либо.

Ответ 3

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

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

Ответ 4

Я думаю, что ответ Адама более общий, чем мое решение, но если вам нравится использовать фиксированное количество аргументов в 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'),
)

Альтернативно, вы также можете использовать идентификатор магазина, изменив (?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

Надеюсь, это поможет любому!

С уважением,

Майкл

Ответ 5

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

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

Я использовал неназванные параметры URL и повторяющееся регулярное выражение. Не получить "не является допустимым регулярным выражением: множественное повторение". Я помещаю слово в начало списка.

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

Мои 2 цента