что обратное () в Джанго

128

Когда я иногда читаю код django, я вижу в некоторых шаблонах reverse(). Я не совсем уверен, что это такое, но он используется вместе с HttpResponseRedirect. Как и когда этот reverse() должен использоваться?

Было бы неплохо, если бы кто-нибудь дал ответ с некоторыми примерами...

  • 11
    Учитывая шаблон URL, Django использует url (), чтобы выбрать правильное представление и создать страницу. То есть url--> view name . Но иногда, как при перенаправлении, вам нужно пойти в обратном направлении и дать Django имя представления, и Django генерирует соответствующий URL. Другими словами, view name --> url . То есть reverse() (обратная функция url). Может показаться более прозрачным просто назвать его generateUrlFromViewName но это слишком долго и, вероятно, недостаточно широко : docs.djangoproject.com/en/dev/topics/http/urls/…
  • 1
    @neuronet Отличное объяснение, спасибо. Это имя казалось (и кажется) особенно не интуитивным для меня, что я считаю тяжким грехом. Кто не ненавидит ненужную путаницу?
Теги:

5 ответов

198
Лучший ответ

https://docs.djangoproject.com/en/stable/ref/urlresolvers/#reverse

в вашем urls.py определить это:

url(r'^foo$', some_view, name='url_name'),

в шаблоне, вы можете ссылаться на этот URL как:

<!-- django <= 1.4 -->
<a href="{% url url_name %}">link which calls some_view</a>

<!-- django >= 1.5 or with {% load url from future %} in your template -->
<a href="{% url 'url_name' %}">link which calls some_view</a>

это будет отображаться как

<a href="/foo/">link which calls some_view</a>

Теперь скажите, что вы хотите сделать что-то подобное в своем views.py - например. вы обрабатываете другой URL-адрес (не /foo/) в каком-либо другом виде (не some_view), и вы хотите перенаправить пользователя на /foo/ (часто в случае успешной отправки формы)

вы могли бы просто сделать

return HttpResponseRedirect('/foo/')

но что, если вы хотите изменить URL в будущем - вам придется обновить urls.py и все ссылки на него в вашем коде. Это нарушает DRY (google it).

вместо этого вы можете сказать

from django.core.urlresolvers import reverse
return HttpResponseRedirect(reverse('url_name'))

Это просматривает все URL-адреса, определенные в вашем проекте, для URL-адреса, определенного с именем url_name и возвращает фактический URL /foo/.

это означает, что вы ссылаетесь на url только по его атрибуту name - если вы хотите изменить сам URL-адрес или вид, на который он ссылается, вы можете сделать это, только редактируя одно место - urls.py. Вся эта идея редактирования только одного места называется "Не повторяй себя" и к чему стремиться.

  • 1
    К вашему сведению, {{ url 'url_name' }} должно быть {% url url_name %} в Django 1.4 или более ранней {% url url_name %} . Это изменится в следующем выпуске Django (1.5) и должно быть {% url 'url_name' %} . Документы для шаблона тега url дают некоторую полезную информацию, если вы прокрутите немного вниз до раздела «прямая совместимость»
  • 1
    j_syk спасибо - я делаю @load url из будущего @, так как вышла 1.3 и забыла, что это еще не значение по умолчанию. Я обновлю свой ответ, чтобы он не сбил с толку неопытного.
Показать ещё 6 комментариев
3

Существует документ для

https://docs.djangoproject.com/en/dev/topics/http/urls/#reverse-resolution-of-urls

его можно использовать для создания URL-адреса для данного представления

Главное преимущество заключается в том, что в коде нет жестких кодовых маршрутов.

1

Слишком старый вопрос, но это может помочь кому-то

из официальных документов

"Django предоставляет инструменты для реверсирования URL-адресов, которые соответствуют различным уровням, где нужны URL-адреса: В шаблонах: использование тега шаблона URL-адреса. В коде Python: использование функции reverse(). В коде более высокого уровня, относящемся к обработке URL-адресов экземпляров модели Django: метод get_absolute_url().

Например: в шаблонах (тег URL)

<a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a>

Например: в коде python (обратная функция)

return HttpResponseRedirect(reverse('news-year-archive', args=(year,)))
  • 1
    нужно полное описание босс
1

Функция поддерживает сухой принцип - гарантируя, что вы не будете жестко кодировать URL-адреса в своем приложении. URL-адрес должен быть определен в одном месте, и только одно место - ваш URL-адрес. После этого вы действительно просто ссылаетесь на эту информацию.

Используйте reverse(), чтобы дать вам URL-адрес страницы, задав либо путь к представлению, либо параметр page_name из вашего URL-адреса. Вы бы использовали его в тех случаях, когда это не имеет смысла делать в шаблоне с помощью {% url 'my-page' %}.

Существует множество возможных мест, в которых вы можете использовать эту функциональность. Одно место, которое я нашел, я использую, когда перенаправление пользователей в представление (часто после успешной обработки формы) -

return HttpResponseRedirect(reverse('thanks-we-got-your-form-page'))

Вы также можете использовать его при написании тегов шаблонов.

В другой раз, когда я использовал reverse(), был с наложением модели. У меня был ListView на родительской модели, но я хотел получить от любого из этих родительских объектов в DetailView связанного дочернего объекта. Я привязал функцию get__child_url() к родительскому объекту, который идентифицировал существование дочернего элемента и вернул URL-адрес его DetailView с помощью reverse().

0

Обратный() используется для закрепления принципа django DRY. Если вы в будущем измените URL-адрес, вы можете ссылаться на этот URL-адрес, используя reverse (urlname).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню