Django HttpResponseRedirect 与重定向
Django HttpResponseRedirect versus redirect
鉴于以下情况:
def add(request):
if request.method == "POST":
task = request.POST.get('task')
form = NewTaskForm(request.POST)
if form.is_valid():
task = form.cleaned_data["task"]
request.session['tasks'] += [task]
# return HttpResponseRedirect(reverse("tasks:index"))
return redirect('tasks:index')
else:
return render(request, "tasks/add.html",{
"form": form
})
return render(request, "tasks/add.html",{
"form": NewTaskForm()
})
有什么区别,你为什么要用一个而不是另一个,介于:
return HttpResponseRedirect(reverse("tasks:index"))
和:
return redirect('tasks:index')
redirect(…)
is implemented as [GitHub]:
def redirect(to, *args, permanent=False, **kwargs):
redirect_class = HttpResponsePermanentRedirect if permanent else HttpResponseRedirect
return <b>redirect_class(</b>resolve_url(to, *args, **kwargs)<b>)</b>
其中 resolve_url
是 reverse(…)
function [Django-doc], as we can see in the 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] 它将 return 此方法的结果;
- 如果是
Promise
,它将评估承诺;
- 如果是亲戚URL,它将return URL;和
- 如果
reverse(…)
失败 并且它看起来像 URL,它将 return 您传递给自己的值,从那时起它假设它是一个(绝对)URL.
因此,它不仅旨在找到具有该名称的视图,而且还会做一些额外的事情。
此外,使用重定向的参数使用方式更方便。如果 url 看起来像:
app_name = 'tasks'
urlpatterns = [
# …,
path('page/<b><slug:myslug></b>/', 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>)
就功能而言,就可读性而言,没有区别,是的!
HttpResponseRedirect 来自 django.http 库,redirect() 来自 django.shortcuts 库。
这与使用 render() [来自 django.shortcuts] 函数或 TemplateResponse() [来自 django.templates]
相同
鉴于以下情况:
def add(request):
if request.method == "POST":
task = request.POST.get('task')
form = NewTaskForm(request.POST)
if form.is_valid():
task = form.cleaned_data["task"]
request.session['tasks'] += [task]
# return HttpResponseRedirect(reverse("tasks:index"))
return redirect('tasks:index')
else:
return render(request, "tasks/add.html",{
"form": form
})
return render(request, "tasks/add.html",{
"form": NewTaskForm()
})
有什么区别,你为什么要用一个而不是另一个,介于:
return HttpResponseRedirect(reverse("tasks:index"))
和:
return redirect('tasks:index')
redirect(…)
is implemented as [GitHub]:
def redirect(to, *args, permanent=False, **kwargs): redirect_class = HttpResponsePermanentRedirect if permanent else HttpResponseRedirect return <b>redirect_class(</b>resolve_url(to, *args, **kwargs)<b>)</b>
其中 resolve_url
是 reverse(…)
function [Django-doc], as we can see in the 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] 它将 return 此方法的结果; - 如果是
Promise
,它将评估承诺; - 如果是亲戚URL,它将return URL;和
- 如果
reverse(…)
失败 并且它看起来像 URL,它将 return 您传递给自己的值,从那时起它假设它是一个(绝对)URL.
因此,它不仅旨在找到具有该名称的视图,而且还会做一些额外的事情。
此外,使用重定向的参数使用方式更方便。如果 url 看起来像:
app_name = 'tasks'
urlpatterns = [
# …,
path('page/<b><slug:myslug></b>/', 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>)
就功能而言,就可读性而言,没有区别,是的!
HttpResponseRedirect 来自 django.http 库,redirect() 来自 django.shortcuts 库。
这与使用 render() [来自 django.shortcuts] 函数或 TemplateResponse() [来自 django.templates]
相同