redirect(…) 是implemented as [GitHub]:
def redirect(to, *args, permanent=False, **kwargs):
redirect_class = HttpResponsePermanentRedirect if permanent else HttpResponseRedirect
return redirect_class(resolve_url(to, *args, **kwargs))
其中resolve_url 是reverse(…) function [Django-doc] 周围的一层,正如我们在source code [GitHub] 中看到的那样:
def resolve_url(to, *args, **kwargs):
"""
Return a URL appropriate for the arguments passed.
The arguments could be:
* A model: the model's `get_absolute_url()` function will be called.
* A view name, possibly with arguments: `urls.reverse()` will be used
to reverse-resolve the name.
* A URL, which will be returned as-is.
"""
# If it's a model, use get_absolute_url()
if hasattr(to, 'get_absolute_url'):
return to.get_absolute_url()
if isinstance(to, Promise):
# Expand the lazy instance, as it can cause issues when it is passed
# further to some Python functions like urlparse.
to = str(to)
if isinstance(to, str):
# Handle relative URLs
if to.startswith(('./', '../')):
return to
# Next try a reverse URL resolution.
try:
return reverse(to, args=args, kwargs=kwargs)
except NoReverseMatch:
# If this is a callable, re-raise.
if callable(to):
raise
# If this doesn't "feel" like a URL, re-raise.
if '/' not in to and '.' not in to:
raise
# Finally, fall back and assume it's a URL
return to
因此这是一种更“丰富”的方式来解析 URL,因为:
- 如果对象有
.get_absolute_url() method [Django-doc],它将返回此方法的结果;
- 如果是
Promise,它将评估承诺;
- 如果是相对URL,则返回该URL;和
- 如果
reverse(…) 失败并且它看起来像一个 URL,它将返回您自己传递的值,因为它假定它是一个(绝对)URL。
因此,它不仅旨在找到具有该名称的视图,而且还做了一些额外的事情。
此外,您使用参数的方式更方便重定向。如果网址看起来像:
app_name = 'tasks'
urlpatterns = [
# …,
path('page/<slug:myslug>/', some_view, name='page')
]
然后当您使用reverse(…) 时,您为myslug 参数提供一个值:
return HttpResponseRedirect(reverse('tasks:index'<b>, args=('value',)</b>))
或:
return HttpResponseRedirect(reverse('tasks:index'<b>, kwargs={'myslug': 'value'}</b>))
而对于重定向,您可以使用:
return redirect('tasks:index'<b>, 'value'</b>)
或:
return redirect('tasks:index'<b>, myslug='value'</b>)