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

StackOverflow https://stackoverflow.com/questions/249110

  •  05-07-2019
  •  | 
  •  

Вопрос

У меня есть модель 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 в качестве необязательного шаблона (.*)?

Это было полезно?

Решение

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

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

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

Другие советы

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

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

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

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

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

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

Надеюсь, это кому-нибудь поможет!

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

Майкл

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

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

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

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

Мои 2 цента

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top