Чистая, элегантная схема URL-ов – это важная часть качественного приложения. Django позволяет проектировать URL-адреса как вы пожелаете, без ограничений “фреймверка”.
В URL-ах не нужны ни .php, ни .cgi, ни всякая ерунда вроде 0,2097,1-1-1928,00.
Читайте Cool URIs don’t change, создателя World Wide Web, Тима Бернерса-Ли, что бы узнать почему URL-ы должны быть красивыми и практичными.
Для определения URL-ов приложения, создайте модуль Python, неофициально названный URLconf (конфигурация URL-ов). Этот модуль содержит код Python, который отображает URL-шаблоны (регулярные выражения) и связанные функции Python (ваши представления).
Эта конфигурация может быть короткой или длинной настолько, насколько это нужно. Она может ссылаться на другие конфигурации. И, так как это код Python, может создаваться динамически.
При запросе к странице вашего Django-сайта, используется такой алгоритм для определения какой код выполнить:
Django определяет какой корневой модуль URLconf использовать. Обычно, это значение настройки ROOT_URLCONF, но, если объект запроса HttpRequest содержит атрибут urlconf (установленный request middleware), его значение будет использоваться вместо ROOT_URLCONF.
Django загружает модуль конфигурации URL и ищет переменную urlpatterns. Это должен быть список Python, в формате возвращаемом функцией django.conf.urls.patterns().
Django перебирает каждый URL-шаблон по порядку, и останавливается при первом совпадении с запрошенным URL-ом.
Если одно из регулярных выражений соответствует URL-у, Django импортирует и вызывает соответствующее представление, которое является просто функцией Python. При вызове первым аргументом передается HttpRequest а так же все значения найденные регулярным выражением.
Если ни одно регулярное выражение не соответствует, или возникла ошибка на любом из этапов, Django вызывает соответствующий обработчик ошибок. Смотрите `Error handling`_ ниже.
Вот пример простого URLconf:
from django.conf.urls import patterns, url, include
urlpatterns = patterns('',
(r'^articles/2003/$', 'news.views.special_case_2003'),
(r'^articles/(\d{4})/$', 'news.views.year_archive'),
(r'^articles/(\d{4})/(\d{2})/$', 'news.views.month_archive'),
(r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'news.views.article_detail'),
)
Заметим:
Для получения совпадающего значения из URL, просто добавьте скобки вокруг него.
Не нужно добавлять слэш в начале, потому что каждый URL содержит его. Например, используйте ^articles, вместо ^/articles.
Символ 'r' перед каждым регулярным выражением не обязателен, но рекомендуется. Он указывает Python что строка “сырая(raw)” и ничего в строке не должно быть экранировано. Смотрите Dive Into Python’s explanation.
Примеры запросов:
Запрос к``/articles/2005/03/`` будет обработан третьим элементом списка. Django вызовет функцию news.views.month_archive(request, '2005', '03').
/articles/2005/3/ не соответствует ни одному URL-шаблону, потому что третья запись требует две цифры в номере месяца.
/articles/2003/ соответствует первому выражению, не второму, потому что шаблоны проверяются по порядку. Не стесняйтесь использовать порядок для обработки различных ситуация, таких как эта.
/articles/2003 не соответствует ни одному регулярному выражению, потому что каждое ожидает, что URL оканчивается на слэш.
/articles/2003/03/03/ соответствует последнему выражению. Django вызовет функцию news.views.article_detail(request, '2003', '03', '03').
Пример выше использует простые, не именованные группы совпадений в регулярных выражениях (то, что в скобках) что бы получить значения из URL и передать в представление как позиционные аргументы. Но вы можете использовать имена для групп и значения будут передаваться как именованные аргументы.
Для регулярных выражений в Python синтаксис для именованных совпадений выглядит таким образом (?P<name>pattern), где name это название группы, а pattern – шаблон.
Вот пример конфигурации URL, переписанный с использованием именованных групп:
urlpatterns = patterns('',
(r'^articles/2003/$', 'news.views.special_case_2003'),
(r'^articles/(?P<year>\d{4})/$', 'news.views.year_archive'),
(r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/$', 'news.views.month_archive'),
(r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/$', 'news.views.article_detail'),
)
Он выполняет то же самое, что и предыдущий пример, с одним небольшим отличием: полученные значения передаются в представление как именованные аргументы, а не позиционные. Например:
Запрос к /articles/2005/03/ вызовет функцию news.views.month_archive(request, year='2005', month='03'), вместо news.views.month_archive(request, '2005', '03').
Запрос к /articles/2003/03/03/ вызовет news.views.article_detail(request, year='2003', month='03', day='03').
На практике это означает, что ваша конфигурация URL более понятна и меньше зависит от ошибки в порядке аргументов, так же вы можете изменять порядок аргументов в представлении. Конечно, эти преимущества достигаются за счет краткости, некоторые разработчики считают именованные группы уродливыми и слишком многословными.
Вот алгоритм, которому следует синтаксический анализатор конфигурации URL, для определения использовать значения именованных или не именованных совпадений:
Если существует именованный аргумент, он будет использован вместо позиционного аргумента. В противном случае, все аргументы будет переданы как позиционные.
В любом случае дополнительные именованные аргументы будут переданы как именованные. Смотрите `Passing extra options to view functions`_ ниже.
URLconf использует запрашиваемый URL как обычную строку Python. Он не учитывает параметры GET, POST и имя домена.
Например, при запросе к http://www.example.com/myapp/, URLconf возьмет myapp/.
При запросе к http://www.example.com/myapp/?page=3 – myapp/.
URLconf не учитывает тип запроса. Другими словами, все типы запросов – POST, GET, HEAD, и др. – будут обработаны одним представлением при одинаковом URL.
urlpatterns должен быть списком Python, в формате, возвращаемом функцией django.conf.urls.patterns(). Всегда используйте patterns() для определения переменной urlpatterns.
Не рекомендуется, начиная с версии 1.4: Starting with Django 1.4 functions patterns, url, include plus the handler* symbols described below live in the django.conf.urls module.
До Django 1.3 они находились в django.conf.urls.defaults. Вы можете использовать этот модуль до Django 1.6.
Функция, которая принимает префикс и произвольное количество URL-шаблонов, и возвращает список URL-шаблонов в необходимом формате.
Первый аргумент patterns() это строка prefix. Смотрите `The view prefix`_ ниже.
Остальные аргументы должны быть кортежами в таком формате:
(regular expression, Python callback function [, optional dictionary [, optional name]])
...где optional dictionary и optional name не обязательны. (Смотрите `Passing extra options to view functions`_ ниже.)
Примечание
Так как patterns() это вызов функции, максимальное количество аргументов равно 255 (URL-шаблонов в этом случае). Это ограничение функций в Python. Вряд ли это будет проблемой, так как лучше использовать модульную структуру, разбивая их на группы с помощью функции include(). Если вам все таки удалось достичь предела в 255 аргументов, помните, что patterns() возвращает список, который вы можете объединить с другим списком.
urlpatterns = patterns('',
...
)
urlpatterns += patterns('',
...
)
Список не имеет ограничения на количество элементов и вы можете создать любое количество URL-шаблонов. Единственное ограничение – вы можете создать только 254 за один вызов функции (255-ый аргумент это префикс).
Вы можете использовать функцию url() вместо кортежа в качестве аргумента patterns(). Это удобно, если вы хотите указать название без словаря дополнительных аргументов. Например:
urlpatterns = patterns('',
url(r'^index/$', index_view, name="main-view"),
...
)
Эта функция принимает пять аргументов большинство из которых не обязательны:
url(regex, view, kwargs=None, name=None, prefix='')
Почему параметр name полезен читайте в разделе о Именованных шаблонах URL.
Параметр prefix аналогичен первому аргументу patterns() и уместен только, если параметр view определяется строкой.
Функция, которая принимает полный путь к другому модулю URLconf для импорта, этот модуль должен быть “включен” в месте вызова функции.
include() так же может принимаьб в качестве параметра итератор, который возвращает шаблоны URL.
Смотрите `Including other URLconfs`_ ниже.
Если Django не может найти подходящий шаблон URL, или было вызвано исключение в процессе обработки запроса, Django вызовет соответствующее представление обрабатывающее ошибку. Эти представления определяются переменными в корневом URLconf. Определение этих переменных в любом другом URLconf не будут иметь никакого эффекта.
Подробности в разделе о переопределении обработчика ошибок.
Функция, или полный путь для импорта, которая будет вызвана, если у пользователя нет доступа к ресурсу.
По-умолчанию, это 'django.views.defaults.permission_denied'. Этого обработчика будет достаточно в большинстве случаев.
Смотрите раздел о представлении обрабатывающем 403 (HTTP Forbidden).
Каждый найденный аргумент передается в представление как строка, независимо от того, какое “совпадение” определено в регулярном выражении. Например, URLconf содержит такую строку:
(r'^articles/(?P<year>\d{4})/$', 'news.views.year_archive'),
...аргумент year для news.views.year_archive() будет строкой, несмотря на \d{4}.
Принято указывать значения по-умолчанию для аргументов представления. Пример URLconf и представления:
# URLconf
urlpatterns = patterns('',
(r'^blog/$', 'blog.views.page'),
(r'^blog/page(?P<num>\d+)/$', 'blog.views.page'),
)
# View (in blog/views.py)
def page(request, num="1"):
# Output the appropriate page of blog entries, according to num.
В примере выше, оба URL-шаблона указывают на одно представление – blog.views.page – но первый шаблон не принимает аргументы в URL. Если первый шаблон будет выбран, функция page() будет использовать значение по-умолчанию аргумента num равное "1". Если будет выбран другой шаблон, page() будет использовать значение num из URL, которое найдет регулярное выражение.
Каждое регулярное выражение в urlpatterns будет скомпилировано при первом использовании. Это делает систему невероятно быстрой.
Вы можете указать общий префикс при вызове patterns() что бы сократить дублирование кода.
Вот пример URLconf из обзора Django:
from django.conf.urls import patterns, url, include
urlpatterns = patterns('',
(r'^articles/(\d{4})/$', 'news.views.year_archive'),
(r'^articles/(\d{4})/(\d{2})/$', 'news.views.month_archive'),
(r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'news.views.article_detail'),
)
В этом пример, каждое представление содержит общий префикс – 'news.views'. Вместо того, что бы писать его для каждой записи urlpatterns, вы можете указать его первым аргументом функции patterns().
Теперь можно переписать пример выше:
from django.conf.urls import patterns, url, include
urlpatterns = patterns('news.views',
(r'^articles/(\d{4})/$', 'year_archive'),
(r'^articles/(\d{4})/(\d{2})/$', 'month_archive'),
(r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'article_detail'),
)
Заметим что в конце префикса отсутствует точка ("."). Django самостоятельно добавит ее.
На практике, скорее всего представления в urlpatterns не буду содержать общий префикс. Однако, вы все равно можете использовать общий префикс что бы сократить дублирование кода. Просто используете несколько результатов вызова patterns() вместе:
Раньше:
from django.conf.urls import patterns, url, include
urlpatterns = patterns('',
(r'^$', 'django.views.generic.date_based.archive_index'),
(r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$', 'django.views.generic.date_based.archive_month'),
(r'^tag/(?P<tag>\w+)/$', 'weblog.views.tag'),
)
Теперь:
from django.conf.urls import patterns, url, include
urlpatterns = patterns('django.views.generic.date_based',
(r'^$', 'archive_index'),
(r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$','archive_month'),
)
urlpatterns += patterns('weblog.views',
(r'^tag/(?P<tag>\w+)/$', 'tag'),
)
В любой момент, ваш urlpatterns может “включать” другие модули URLconf.
Вот пример URLconf для сайта Django. Он включает множество других конфигураций URL:
from django.conf.urls import patterns, url, include
urlpatterns = patterns('',
# ... snip ...
(r'^comments/', include('django.contrib.comments.urls')),
(r'^community/', include('django_website.aggregator.urls')),
(r'^contact/', include('django_website.contact.urls')),
(r'^r/', include('django.conf.urls.shortcut')),
# ... snip ...
)
Заметим, что регулярные выражения не содержат $ (определитель конца строки), но содержит слэш в конце. Каждый раз, когда Django встречает include(), из URL обрезается уже совпавшая часть, остальное передается во включенный URLconf для дальнейшей обработки.
Другой способ – передать результат выполнения patterns вместо модуля Python. Например:
from django.conf.urls import patterns, url, include
extra_patterns = patterns('',
url(r'^reports/(?P<id>\d+)/$', 'credit.views.report', name='credit-reports'),
url(r'^charge/$', 'credit.views.charge', name='credit-charge'),
)
urlpatterns = patterns('',
url(r'^$', 'apps.main.views.homepage', name='site-homepage'),
(r'^help/', include('apps.help.urls')),
(r'^credit/', include(extra_patterns)),
)
Такой подход используется при подключении приложения интерфейса администратора(admin) Django. Для подключения используется экземпляр AdminSite, каждый из которых содержит свойство urls. Оно возвращает URL-шаблоны, которые доступные для этого экземпляра. Это то свойство, которое вы добавляете, используя include(), в urlpatterns вашего проекта при установке приложения администратора.
Включенный URLconf получает все аргументы найденные родительским URLconfs, по этому этот пример работает:
# In settings/urls/main.py
urlpatterns = patterns('',
(r'^(?P<username>\w+)/blog/', include('foo.urls.blog')),
)
# In foo/urls/blog.py
urlpatterns = patterns('foo.views',
(r'^$', 'blog.index'),
(r'^archive/$', 'blog.archive'),
)
В примере выше, найденный аргумент "username" передается во включенный URLconf, как и ожидалось.
Если необходимо использовать несколько экземпляров одного приложения, было бы удобно иметь возможность различать их. Это особенно важно при использовании именованных шаблонов URL, так как несколько экземпляров используют одинаковые названия для URL-ов. Пространства имен позволяют сделать эти названия уникальными.
Пространство имен состоит из двух частей, каждая из которых это строка:
Название(пространство имен) приложения. Указывает название установленного приложения. Все экземпляры одного приложения будет иметь одно название. Например, название приложения администратора Django – admin.
Название(пространство имен) экземпляра. Идентифицирует конкретный экземпляр приложения. Должно быть уникальным для проекта. Однако, название экземпляра может быть равным названию приложения. Оно используется по-умолчанию при создании приложения. Например, пространство имен приложения администратора Django – admin.
Пространство имен URL можно определить двумя путями.
Первый, передав в качестве аргументов при вызове include(). Например:
(r'^help/', include('apps.help.urls', namespace='foo', app_name='bar')),
Этот код добавляет URL-шаблоны определенные в apps.help.urls, используя название приложения bar и название экземпляра foo.
Второй, вы можете добавить объект, который содержит все необходимые данные. Если использовать результат patterns() при вызове функции include(), он будет добавлен в глобальное пространство имен. Однако, в include() можно передать 3-элементный кортеж, который содержит:
(<patterns object>, <application namespace>, <instance namespace>)
Например, свойство urls экземпляра AdminSite возвращает 3-элементный кортеж, который содержит URL-шаблоны, название экземпляра и название(пространство имен) приложения admin.
После определения пространства имен, вы можете использовать его для нахождения URL-ов. Подробности смотрите в разделе о нахождение URL-ов с пространством имен.
Конфигурация URL-ов позволяет определить дополнительные аргументы для функции представления, используя словарь Python.
Каждый кортеж в URLconf может содержать третий необязательный элемент. Этот элемент определяет дополнительные именованные аргументы для функции представления.
Например:
urlpatterns = patterns('blog.views',
(r'^blog/(?P<year>\d{4})/$', 'year_archive', {'foo': 'bar'}),
)
Например, при запросе к /blog/2005/, Django вызовет blog.views.year_archive(), передавая эти именованные аргументы:
year='2005', foo='bar'
Такой подход используется общими представлениями и syndication framework для передачи параметров и дополнительных данных в представление.
Dealing with conflicts
Если регулярное выражение URL-шаблона выделяет из URL-а аргумент с названием, которое уже используется в дополнительных именованных аргументах, будет использован аргумент из словаря дополнительных аргументов, вместо значения из URL.
Аналогично вы можете передать дополнительные аргументы в include(). При этом, каждый URL-шаблон включенного URLconf будет дополнен этими дополнительными аргументами.
Например, эти два URLconf работают идентично:
Первый:
# main.py
urlpatterns = patterns('',
(r'^blog/', include('inner'), {'blogid': 3}),
)
# inner.py
urlpatterns = patterns('',
(r'^archive/$', 'mysite.views.archive'),
(r'^about/$', 'mysite.views.about'),
)
Второй:
# main.py
urlpatterns = patterns('',
(r'^blog/', include('inner')),
)
# inner.py
urlpatterns = patterns('',
(r'^archive/$', 'mysite.views.archive', {'blogid': 3}),
(r'^about/$', 'mysite.views.about', {'blogid': 3}),
)
Дополнительные аргументы всегда передаются каждому представлению во включенном URLconf, независимо от того, принимает оно эти аргументы или нет. По этому, такой подход полезен только если вы уверенны, что каждое представление принимает передаваемые аргументы.
Некоторые разработчики предпочитают передавать функции вместо строк, содержащих путь для импорта. Такой способ так же работает – вы можете передать любой вызываемый объект в качестве представлений.
Например, у нас есть такой URLconf:
urlpatterns = patterns('',
(r'^archive/$', 'mysite.views.archive'),
(r'^about/$', 'mysite.views.about'),
(r'^contact/$', 'mysite.views.contact'),
)
Вы можете сделать то же самое, передавая объекты вместо строк. Просто импортируйте эти объекты:
from mysite.views import archive, about, contact
urlpatterns = patterns('',
(r'^archive/$', archive),
(r'^about/$', about),
(r'^contact/$', contact),
)
Следующий пример работает аналогично. Он немного короче, потому что мы импортируем модуль содержащий представления, а не каждое представление по отдельности:
from mysite import views
urlpatterns = patterns('',
(r'^archive/$', views.archive),
(r'^about/$', views.about),
(r'^contact/$', views.contact),
)
Стиль, который вы используете, зависит от вас.
Стоит заметить, что при передаче объекта вместо строки, префикс для представлений (описанный выше `The view prefix`_) не будет иметь никакого эффекта.
Обычная практика использовать одно представление для нескольких URL-шаблонов в URLconf. Например, эти два URL-шаблона указывают на представление archive:
urlpatterns = patterns('',
(r'^archive/(\d{4})/$', archive),
(r'^archive-summary/(\d{4})/$', archive, {'summary': True}),
)
Этот пример работает, но, если вы захотите найти URL (используя декоратор permalink() или тег шаблона url), это приведет к проблемам. Если вы захотите получить URL для представления archive, Django запутается так как два URL-шаблона соответствуют одному представлению.
Для решения этой проблемы, Django предоставляет именованные URL-шаблоны. То есть, вы можете дать название для URL-шаблонов что бы отличать их и использовать эти названия при поиске нужного вам URL-а.
Перепишем пример выше с использованием именованных URL-шаблонов:
urlpatterns = patterns('',
url(r'^archive/(\d{4})/$', archive, name="full-archive"),
url(r'^archive-summary/(\d{4})/$', archive, {'summary': True}, "arch-summary"),
)
Используя эти названия (full-archive и arch-summary), вы можете обратиться к каждому URL-шаблону отдельно:
{% url arch-summary 1945 %}
{% url full-archive 2007 %}
Хоть оба URL-шаблона ссылаются на одно представление archive, использование параметра name в теге url() позволит вам различить их в шаблоне.
Вы можете использовать любые символы в названии.
Примечание
При выборе названия для URL-шаблона, убедитесь что оно достаточно уникально. Если вы назовете URL-шаблон comment, и другое приложение сделает аналогичное, нет гарантии что в шаблон будет вставлен правильный URL.
Добавление префикса к названию URL-шаблона, возможного состоящего из названия приложения, уменьшит шанс конфликта. Мы советуем использовать myapp-comment вместо comment.
Пространство имен определяется с помощью оператора :. Например, главная страница интерфейса администратора определяется как admin:index. Мы видим пространство имен admin, и название URL-шаблона index.
Пространства имен могут быть вложенными. Название URL-а foo:bar:whiz означает именованный URL-шаблон с названием whiz в пространстве имен bar, которое было определенно в другом пространстве имен - foo.
Если необходимо найти URL по названию (например, myapp:index), Django разбивает название на части и следует такому алгоритму:
Первым делом, Django ищет список экземпляров приложения по указанному пространству имен (например, myapp). (То есть ищет все вложенные URLconf с аналогичным названием(пространством имен) приложения - прим. переводчика.)
Если указан текущий экземпляр приложения, Django вернет “URL resolver” для этого экземпляра. Текущий экземпляр приложения можно указать используя атрибут current_app контекста шаблона. Приложения, которые будут использоваться в нескольких экземплярах в одном проекте, должны всегда определять атрибут current_app для Context или RequestContext, который используется для выполнения шаблона.
Текущей экземпляр приложения можно так же определить используя аргумент при вызове функции reverse().
Если текущий экземпляр приложения не найден, Django попытается использовать экземпляр по-умолчанию. Экземпляр по-умолчанию – это экземпляр, у которого название приложения и название экземпляра приложения совпадают (в нашем примере это экземпляр myapp с названием myapp).
Если экземпляр по-умолчанию не найден, Django возьмет последний установленный экземпляр приложения, не обращая внимание на его название.
Если на первом шаге не было найдено приложение по указанному пространству имен, Django попытается найти экземпляр приложения по его названию, используя пространство имен как название экземпляра.
Если пространство имен вложенное, этот процесс будет повторен, пока неопределенным не останется только название представления. URL для названия представления будет искаться среди URL-шаблонов определенных в приложении, найденном через пространство имен.
Разберем небольшой пример. У нас есть два экземпляра приложения myapp: один назван foo, другой - bar. myapp содержит главную страницу с названием URL-а index. Возможны такие ситуации:
Если один из экземпляров указан как текущий - например, мы выполняем шаблон в экземпляре bar - поиск URL-а по myapp:index вернет URL на главную страницу экземпляра приложения bar.
Если текущий экземпляр приложения не указан - например, мы ищем URL в другом приложении - поиск по myapp:index вернет URL для последнего добавленного экземпляра myapp. Это может быть foo или bar, в зависимости от того, в коком порядке они были добавлены в URL-шаблоны проекта.
Поиск по foo:index``всегда вернет ссылку на главную страницу экземпляра приложения ``foo.
Если бы был определен экземпляр по-умолчанию - то есть, экземпляр с названием myapp:
Если один из экземпляров указан как текущий - например, мы выполняем шаблон в экземпляре bar - поиск URL-а по myapp:index вернет URL на главную страницу экземпляра приложения bar.
Если текущий экземпляр приложения не указан - например, мы ищем URL в другом приложении - поиск по myapp:index вернет URL на главную страницу экземпляра по-умолчанию.
Поиск по foo:index``все так же вернет ссылку на главную страницу экземпляра приложения ``foo.
Если вам нужно использовать в коде функционал тега url, Django предоставляет ряд функций (в модуле django.core.urlresolvers):
viewname – это название функции (либо определение функции, либо путь путь для импорта, зависит что вы использовали в urlpatterns) или название URL-шаблона. Скорее всего вам не придется использовать аргумент urlconf и все что вам нужно, это добавить позиционные и именованные аргументы что бы найти определенный URL. Например:
from django.core.urlresolvers import reverse
def myview(request):
return HttpResponseRedirect(reverse('arch-summary', args=[1945]))
Функция reverse() может обработать много видов регулярных выражений, но не все. Главным ограничением на данный момент это использование альтернативных вариантов с помощью "|". Вы можете использовать такое регулярное выражения в URL-шаблонах, но не сможете найти URL по нему.
Аргумент current_app позволяет указать экземпляр приложения на которое должен указывать URL. Этот экземпляр приложения будет использоваться при анализе пространства имен.
Вы можете использовать kwargs вметос args. Например:
>>> reverse('admin:app_list', kwargs={'app_label': 'auth'})
'/admin/auth/'
Нельзя использовать args и kwargs вместе.
Make sure your views are all correct.
При поиске необходимого URL-шаблона функция reverse() импортирует все файлы конфигурации URL и анализирует название каждого представления. В результате чего выполняется импорт всех функций представления. Если при импорте произойдет какая-либо ошибка, функция reverse() вызовет исключение, даже если это представление не относится к URL-y который вы ищете.
Убедитесь что любое использованное в URLconf представление существует и может быть импортировано без ошибок. Не указывайте еще не созданные представления, потому что DJango не сможет их импортировать.
Примечание
Строка, которую возвращает reverse(), уже обработана функцией urlquoted. Например:
>>> reverse('cities', args=[u'Orléans'])
'.../Orl%C3%A9ans/'
Повторное применение кодирования (функций urlquote() или urllib.quote) к результату reverse() может привести к неожиданным результатам.
“Ленивая” версия reverse().
Эта функция полезна если необходимо определить поиск URL-а до загрузки URLConf. Например:
указать определенный URL как атрибут url класса общего представления(a generic class-based view).
передать URL в декоратор (например, аргумент login_url для декоратора django.contrib.auth.decorators.permission_required()).
использование URL-а как значения по-умолчанию для аргумента при определении функции.
Функция django.core.urlresolvers.resolve() может быть использована для поиска представления соответствующего переданному URL. Определяется она таким образом:
path это URL для которого ищем представление. Как и для reverse(), вы не должны волноваться про аргумент urlconf. Функция возвращает объект ResolverMatch, который позволяет получить различную информацию про переданный URL.
Если соответствующее представление не найдено, функция вызовет исключение Http404.
Функция представления, которая будет использована для обработки переданного URL-а
Аргументы, которые были получены из URL-а и будут переданы в функцию представления.
Именованные аргументы, которые были получены из URL-а и будут переданы в функцию представления.
Название URL-шаблона , который соответствует переданному URL-у.
Название приложения найденного URL-шаблона.
Название экземпляра приложения найденного URL-шаблона.
Список пространств имен найденного URL-шаблона. Например, если пространство имени определяется как foo:bar, атрибут будет равен ['foo', 'bar'].
Объект :class:`ResolverMatch`может использоваться для получения информации о URL-шаблоне, который соответствует переданному URL-у:
# Resolve a URL
match = resolve('/some/path/')
# Print the URL pattern that matches the URL
print match.url_name
Объект ResolverMatch можно присвоит трем переменным:
func, args, kwargs = resolve('/some/path/')
resolve() можно использовать для проверки перед перенаправлением на представление, вызовет ли оно ошибку Http404:
from urlparse import urlparse
from django.core.urlresolvers import resolve
from django.http import HttpResponseRedirect, Http404
def myview(request):
next = request.META.get('HTTP_REFERER', None) or '/'
response = HttpResponseRedirect(next)
# modify the request and response as required, e.g. change locale
# and set corresponding locale cookie
view, args, kwargs = resolve(urlparse(next)[2])
kwargs['request'] = request
try:
view(*args, **kwargs)
except Http404:
return HttpResponseRedirect('/')
return response
Декоратор django.db.models.permalink() полезен для написания коротких методов, которые возвращают полный URL. Например, метод модели get_absolute_url() method. Подробности смотрите в описании django.db.models.permalink().
Обычно вы будет использовать функции reverse() или permalink() для поиска URL-а для вашего приложения. Однако, если вашему приложению необходимо создать URL самостоятельно, вам может понадобиться основа URL-а для проекта, которая определенна в настройках Web-сервера (reverse() самостоятельно заботиться об этом). В этом случае вы можете использовать get_script_prefix(), которая вернет префикс скрипта URL-а для вашего проекта. Если ваш проект находиться в корне сервера, это будет "/", но может быть и изменен через django.root (смотрите Как использовать Django с Apache и mod_python).
Mar 30, 2016