Что обратное() в Django
Когда я иногда читаю код django, я вижу в некоторых шаблонах reverse()
. Я не совсем уверен, что это такое, но он используется вместе с HttpResponseRedirect. Как и когда этот reverse()
должен использоваться?
Было бы неплохо, если бы кто-нибудь дал ответ с некоторыми примерами...
Ответы
Ответ 1
reverse()
| Django документация
В вашем 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
и все ссылки на него в своем коде. Это нарушает " СУХОЙ" ("Не повторяй себя"), всю идею редактирования только одного места, к чему нужно стремиться.
Вместо этого вы можете сказать:
from django.urls import reverse
return HttpResponseRedirect(reverse('url_name'))
Он просматривает все URL-адреса, определенные в вашем проекте, для URL-адреса, определенного с именем url_name
и возвращает фактический URL-адрес /foo/
.
Это означает, что вы обращаетесь к URL-адресу только по его атрибуту name
- если вы хотите изменить сам URL-адрес или представление, к которому он относится, вы можете сделать это, отредактировав только одно место - urls.py
Ответ 2
Это старый вопрос, но кое-что может кому-то помочь.
Из официальных документов:
Django предоставляет инструменты для выполнения реверсирования URL, которые соответствуют разным слоям, где необходимы URL: В шаблонах: Использование тега шаблона URL. В коде Python: использование функции reverse(). В коде более высокого уровня, связанном с обработкой URL-адресов экземпляров модели Django: метод get_absolute_url().
Например. в шаблонах (тег URL)
<a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a>
Например. в коде Python (с использованием reverse
функции)
return HttpResponseRedirect(reverse('news-year-archive', args=(year,)))
Ответ 3
Существует документ для
https://docs.djangoproject.com/en/dev/topics/http/urls/#reverse-resolution-of-urls
его можно использовать для создания URL-адреса для данного представления
Главное преимущество заключается в том, что в коде нет жестких кодовых маршрутов.
Ответ 4
Функция поддерживает сухой принцип - гарантируя, что вы не будете жестко кодировать 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()
.
Ответ 5
Обратный() используется для закрепления принципа django DRY. Если вы в будущем измените URL-адрес, вы можете ссылаться на этот URL-адрес, используя reverse (urlname).
Ответ 6
Существующие ответы проделали большую работу по объясняя, что этого reverse()
функции в Django.
Тем не менее, я надеялся, что мой ответ пролил другой свет на вопрос " почему": зачем использовать reverse()
вместо других более простых, возможно, более питонических подходов в привязке к представлению шаблона, и каковы некоторые законные причины популярности этого "перенаправление через шаблон reverse()
" в логике маршрутизации Django.
Одним из ключевых преимуществ является обратная конструкция URL, как уже упоминали другие. Точно так же, как вы бы использовали {% url "profile" profile.id %}
для генерации URL из файла конфигурации вашего приложения: например, path('<int:profile.id>/profile', views.profile, name="profile")
.
Но, как отметил OP, использование reverse()
также обычно сочетается с использованием HttpResponseRedirect
. Но почему?
Я не совсем уверен, что это такое, но он используется вместе с HttpResponseRedirect. Как и когда должен использоваться этот reverse()?
Рассмотрим следующие views.py
:
from django.http import HttpResponseRedirect
from django.urls import reverse
def vote(request, question_id):
question = get_object_or_404(Question, pk=question_id)
try:
selected = question.choice_set.get(pk=request.POST['choice'])
except KeyError:
# handle exception
pass
else:
selected.votes += 1
selected.save()
return HttpResponseRedirect(reverse('polls:polls-results',
args=(question.id)
))
И наш минимальный urls.py
:
from django.urls import path
from . import views
app_name = 'polls'
urlpatterns = [
path('<int:question_id>/results/', views.results, name='polls-results'),
path('<int:question_id>/vote/', views.vote, name='polls-vote')
]
В функции vote()
код нашего блока else
использует reverse
вместе с HttpResponseRedirect
по следующему шаблону:
HttpResponseRedirect(reverse('polls:polls-results',
args=(question.id)
Это, прежде всего, означает, что нам не нужно жестко кодировать URL (в соответствии с принципом DRY), но, что более важно, reverse()
предоставляет элегантный способ создания строк URL, обрабатывая значения, распакованные из аргументов (args=(question.id)
обрабатывается URLConfig). Предполагаемый question
имеет атрибут id
который содержит значение 5
, тогда URL, созданный из reverse()
будет:
'/polls/5/results/'
В обычном коде связывания представления шаблона мы используем HttpResponse()
или render()
поскольку они обычно включают меньше абстракции: одна функция представления возвращает один шаблон:
def index(request):
return render(request, 'polls/index.html')
Но во многих законных случаях перенаправления мы обычно заботимся о создании URL-адреса из списка параметров. К ним относятся такие случаи, как:
- Отправка HTML-формы через
POST
запрос - Пост-проверка логина пользователя
- Сброс пароля через веб-токены JSON
Большинство из них включают в себя некоторую форму перенаправления и URL-адрес, созданный с помощью набора параметров. Надеюсь, что это добавляет к уже полезной ветке ответов!