Перенаправление и обратные различия в Django
У меня вопрос о том, чем отличаются редирект и реверс. Влияет ли это на производительность. И кто-нибудь может мне объяснить разницу между этими 3 примерами кода? Каково их назначение и как я могу эффективно их применить.
if 'comment' in request.POST:
form = CommentCreationForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.comment_user = request.user
comment.comment_item = Item.objects.get(id=pk)
comment.save()
//1 return redirect('detail-page', pk=item.id)
//2 return redirect(reverse('detail-page', kwargs={'pk': item.id}))
//3 return reverse('detail-page')
(я не могу добавить ни одного аргумента к третьему, это единственное отличие, которое я заметил).
Согласно https://docs.djangoproject.com/en/3.2/topics/http/shortcuts/#redirect 1 и 2 эквивалентны. Я предполагаю, что 3 не работает, поскольку в нем отсутствует "требуемый" идентификатор товара
Эти два понятия не совпадают по нескольким причинам. Первая заключается в том, что reverse(…)
[Django-doc] возвращает строку, которая является URL для посещения данного представления. redirect(…
) [Django-doc] с другой стороны, возвращает HttpResponseRedirect
объект [Django-doc]. Этот объект может быть возвращен представлением и, как правило, вызовет переход браузера на страницу, указанную в HTTP-ответе. redirect(…)
имеет специальный параметр permanent=…
, который в зависимости от значения возвращает HttpResponseRedirect
(если permanent=False
, что является значением по умолчанию), или HttpResponsePermanentRedirect
для permanent=True
.
Другим отличием является то, что reverse(…)
работает с параметрами args=…
и kwargs=…
для заполнения значений шаблонов URL. Это отличается от redirect(…)
, где передаются позиционные и именованные параметры, как позиционные и именованные параметры. Это означает, что если вы выполните reverse('some_view', args=(some_parameter,), kwargs={'name': other_parameter})
, вы получите HTTP-ответ, указывающий на этот URL с помощью reverse('some_view', some_parameter, name=other_parameter)
.
А redirect(…)
сама по себе не работает на имени представления. Действительно, если вы передадите URL функции redirect(…)
, например redirect('/foo/bar/qux/')
, она построит HttpResponseRedirect
, который перенаправляет на URL /foo/bar/qux
. Это отличается от reverse(…)
, которая строит URL только на основе имени представления и его параметров.
В конечном итоге redirect(…)
также принимает объект модели, который имеет .get_absolute_url()
метод [Django-doc] приведет к HttpResponseRedirect
, который перенаправляет на URL, построенный этим .get_absolute_url()
методом.
Ваша первая (//1
) и вторая (//2
) строки, таким образом, дадут одинаковый результат: HttpResponseRedirect
, который перенаправляет на тот же URL, тогда как последняя (//3
) вернет строку, содержащую URL к detail-page
представлению.