Эффективно управлять все более сложными представлениями Django URL? (Urls.py) - PullRequest
2 голосов
/ 02 февраля 2010

Итак, у меня есть это приложение Django, и я продолжаю добавлять новые функции, чтобы обеспечить еще более детальный просмотр данных.Чтобы дать быстрое представление о проблеме, вот подмножество urls.py:

# Simple enough . . .
(r'^$', 'index'),
(r'^date/(?P<year>\d{4})$', 'index'),
(r'^date/(?P<year>\d{4})-(?P<month>\d{2})$', 'index'),
(r'^date/(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})$', 'index'),
(r'^page/(?P<page>\d+)$', 'index'),

Так что, да, представление по умолчанию, представления даты, представление с разбиением на страницы, а затем аналогичные настройки для пользовательских URL-адресов:

# user
(r'^user/(?P<username>\w+)$', 'index_username'),
(r'^user/(?P<username>\w+)/date/(?P<year>\d{4})$', 'index_username'),
(r'^user/(?P<username>\w+)/date/(?P<year>\d{4})-(?P<month>\d{2})$', 'index_username'),
(r'^user/(?P<username>\w+)/date/(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})$', 'index_username'),
(r'^user/(?P<username>\w+)/page/(?P<page>\d+)$', 'index_username'),

Затем, аналогично снова для команд.,.

# Team View
(r'^team/(?P<team>\w+)$', 'index'),
(r'^team/(?P<team>\w+)/date/(?P<year>\d{4})$', 'index'),
(r'^team/(?P<team>\w+)/date/(?P<year>\d{4})-(?P<month>\d{2})$', 'index'),
(r'^team/(?P<team>\w+)/date/(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})$', 'index'),
(r'^team/(?P<team>\w+)/page/(?P<page>\d+)$', 'index'),

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

/search/foo
/user/fred/date/2010-01/search/baz

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

Носкажем, если я хочу применить это к представлениям пользователя, команды и по дате, я получу 12 новых строк, добавленных к urls.py.И каждый раз я добавляю еще один потенциальный вариант просмотра (скажем, постраничные результаты поиска?).,,мне кажется, что должен быть лучший способ.

Из моего исследования мне может показаться, что ответом будет:
1) Более широкое соответствие в пределах urls.py и функция просмотра анализирует строку запроса.
2) Может быть, в urls.py может быть более логичная логика регулярных выражений, которая может сказать «если этот шаблон соответствует, включить параметр при передаче в функцию представления» несколько раз.Но поддерживать это, вероятно, кошмарно.

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

# Date Queries
re_ymd = re.compile('date/(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})')
re_ym = re.compile('date/(?P<year>\d{4})-(?P<month>\d{2})')
re_y = re.compile('date/(?P<year>\d{4})')
if( re_ymd.search(qs) ):
    year = re_ymd.search(qs).group('year')
    month = re_ymd.search(qs).group('month')
    day = re_ymd.search(qs).group('day')
elif( re_ym.search(qs) ):
    year = re_ym.search(qs).group('year')
    month = re_ym.search(qs).group('month')
elif( re_y.search(qs) ):
    year = re_y.search(qs).group('year')

# Pagination queries
re_p = re.compile('page/(?P<page>\d+)')
if( re_p.search(qs) ):
    page = re_p.search(qs).group('page')

# Search queries
re_s = re.compile('search/(?P<search>\w+)')
if( re_s.search(qs) ):
    search = re_s.search(qs).group('search')

Итак, является ли это умным способом уменьшения сложности повторения, который я представлял для urls.py?

Ответы [ 2 ]

3 голосов
/ 02 февраля 2010

Почему бы не использовать параметры GET или django-filter , если все, что вы делаете, это просто фильтруете / группируете результаты по-другому?

Причины, по которым я вижу использование GET, заключаются в том, что его проще реализовать, и он выглядит немного чище: в решении для URL-адресов / search / foo / user / bar / и / user / bar / search / foo / есть 2 имени для точно такой же контент. В решении GET параметров все та же страница.

0 голосов
/ 02 февраля 2010

Давайте сосредоточимся на этом:

    # Simple enough . . .
    (r'^$', 'index'),
    (r'^date/(?P<year>\d{4})$', 'index'),
    (r'^date/(?P<year>\d{4})-(?P<month>\d{2})$', 'index'),
    (r'^date/(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})$', 'index'),
    (r'^page/(?P<page>\d+)$', 'index'),

Я предполагаю, что есть:

    def index(year=2010, month=2, day=2, page=0):
        # whatever

Итак, почему бы вам не объединить свои регулярные выражения, например,

     r'^date/(?P<year>\d{4})(-(?P<month>\d{2})(-(?P<day>\d{2}))?)?$

Я не пробовал, но я уверен, что что-то подобное сработает.

EDIT:

Хотя переписывание регулярных выражений может сработать, взгляните на ответ Офри Равива, потому что здесь может быть какая-то мета-проблема.

...