Как заставить URL-шаблон Django принимать только слаги из модели

Я делаю сайт блога в Django. У меня есть такая модель блога:

class Blog(models.Model):
    name = models.CharField(max_length=255)
    slug = models.SlugField(max_length=255)
    ...

И я хочу, чтобы главные страницы каждого блога имели такие URL-адреса: www.example.com/blog-slug/

Однако я также использую Flatpages и хочу, чтобы они соответствовали URL-адресам, подобным этому: www.example.com/flat-page/

Таким образом, такие URL-шаблоны не будут работать:

urlpatterns = patterns('',
    (r'^(?P<blog_slug>[-\w]+)/$', 'weblog_index', {}),
    ...
    (r'^', include('django.contrib.flatpages.urls')),
)

потому что все URL-адреса Flatpages попадут в ловушку первого шаблона. Думаю, я хочу, чтобы первый шаблон соответствовал только действительным слагам из модели Blog, но я не уверен, как это сделать.


person Phil Gyford    schedule 16.09.2010    source источник


Ответы (2)


Вы не можете сделать это:

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

Поскольку да, Django пробует только первое представление, соответствующее вашему регулярному выражению. Если это представление вызывает ошибку 404, оно не пытается использовать другие URL-адреса.

Однако вы можете делать то, что пытаетесь сделать, ничего не добавляя в свой urls.py:

Из документов по Django:

Чтобы установить приложение flatpages, выполните следующие действия:

  1. Установите фреймворк сайтов, добавив 'django.contrib.sites' в параметр INSTALLED_APPS, если его там еще нет.

  2. Также убедитесь, что вы правильно установили SITE_ID в идентификатор сайта, который представляет файл настроек. Обычно это будет 1 (то есть SITE_ID = 1, но если вы используете платформу сайтов для управления несколькими сайтами, это может быть идентификатор другого сайта.

  3. Добавьте 'django.contrib.flatpages' к настройке INSTALLED_APPS.

  4. Добавьте 'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware' к настройке MIDDLEWARE_CLASSES.

  5. Запустите команду manage.py syncdb.

По сути, пока ваши приложения для блогов вызывают Http404 при обнаружении слага, для которого не существует записи в блоге, все должно быть в порядке.

Размещение 'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware' в вашем MIDDLEWARE_CLASSES означает, что непосредственно перед тем, как Django отобразит страницу с ошибкой, он проверяет FlatPage с путем, совпадающим с URL-адресом, который сгенерировал 404 (т. е. если есть 404, он возвращается к проверке FlatPage). Если он есть, он его отображает.

person Dominic Rodger    schedule 16.09.2010
comment
Я не уверен, что следую... Теперь я попытался настроить представление «weblog_index», которое выполняет get_object_or_404(), используя соответствующий blog_slug. Это работает, поскольку отображается правильная страница, но если это не удается, он не переходит к попытке сопоставить URL-адрес Flatpages. - person Phil Gyford; 16.09.2010
comment
(Чего я на самом деле не ожидал - как только Django сопоставил URL-адрес и перешел к представлению, он не собирается возвращаться и пробовать другие URL-адреса после этого...?) - person Phil Gyford; 16.09.2010
comment
Я думаю, что ОП просит сопоставить просмотры плоских страниц со значениями полей слагов. - person Ankit Jaiswal; 16.09.2010
comment
@anand - извините, я не понимаю, что вы говорите. Я на 99% уверен, что понимаю вопрос @Phil... - person Dominic Rodger; 16.09.2010
comment
Что я могу понять из вопроса, так это то, что Фил хочет создать некоторые шаблоны URL-адресов на основе полей слагов в своей модели, а затем сделать URL-адреса плоской страницы для работы с этими URL-адресами. Пожалуйста, поправьте меня, если я ошибаюсь. - person Ankit Jaiswal; 16.09.2010
comment
Это неправильно @anand. Если URL-адрес соответствует blog_slug, я хочу, чтобы отображалась главная страница этого блога. Если URL-адрес не соответствует blog_slug, я хочу, чтобы Flatpages обрабатывал запрос (и отображал либо соответствующую Flatpage, либо 404, в зависимости от ситуации). - person Phil Gyford; 16.09.2010
comment
хм, с первого раза не понял. Я прошу прощения за это. - person Ankit Jaiswal; 16.09.2010
comment
И да, я тоже должен поблагодарить вас, Доминик - я полагал, что правильно настроил плоские страницы, когда не добавил промежуточное программное обеспечение. Так что ура. - person Phil Gyford; 16.09.2010

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

Таким образом, даже если вы не можете ограничить свое представление weblog_index только действительными слагами, вы можете выполнить простое get_object_or_404 в этом представлении, чтобы оно вызывало ошибку 404, когда не было найдено соответствующего слага блога, и что 404 немедленно перехватывается приложением Flatpages, и все работает так, как вы хотите.

person Daniel Roseman    schedule 16.09.2010
comment
Должно быть, я делаю что-то не так, потому что, если я использую URL-адрес известной Flatpage, тогда представление weblog_index генерирует 404, потому что URL-адрес не содержит действительного blog_slug, и браузер отображает 404 (No Blog соответствует заданному запрос.). Оно не перехватывается приложением Flatpages. - person Phil Gyford; 16.09.2010
comment
И да, я делал что-то не так! Я забыл добавить «django.contrib.flatpages.middleware.FlatpageFallbackMiddleware» в настройку MIDDLEWARE_CLASSES. Таким образом, он не искал Flatpages после 404-х, а полагался только на то, что все совпадения URL-адресов потерпят неудачу. Спасибо за ваш ответ, Дэниел, который побудил меня задаться вопросом, что я делаю, и перечитать документы! - person Phil Gyford; 16.09.2010