1. 程式人生 > >Django基礎(10): URL重定向的HttpResponseDirect, redirect和reverse的用法詳解

Django基礎(10): URL重定向的HttpResponseDirect, redirect和reverse的用法詳解

detail djang 包含 war sed 模型 博客 nbsp rep

利用django開發web應用, 我們經常需要進行URL重定向,有時候還需要給URL傳遞額外的參數。比如用戶添加文章完成後需要轉到文章列表或某篇文章詳情。因此熟練掌握HttpResponseDirect, redirect和reverse這三種方法對於Django Web開發是至關重要。今天小編我就帶你看下Django URL重定向的HttpResponseDirect, redirect和reverse方法的詳細用法。

HttpResponseDirect方法

HttpResponseRedirect是django首選的URL重定向方法,在django.http模塊裏。該方法的第一個參數是必要的,是用來重定向的URL地址。這個URL可以是完整的鏈接(比如’http://www.baidu.com‘),也可以是一個不包含域名的靜態鏈接(例如‘/index/’)。

我們下面以新聞博客(blog)為例來看看如何使用HttpResponseDirect方法。假如我們有如下3個urls, 一個展示文章,一個添加文章,一個展示文章詳情。我們需要使用該方法在視圖中實現兩種URL重定向:

轉向不含參數的URL: 用戶添加文章完成後轉向文章列表(/index/); 或

轉向包含參數的URL: 用戶添加文章完成後轉向文章詳情(/article/2/new-day/)

from django.urls import path, re_path
from . import views

# namespace
app_name = ‘blog‘
urlpatterns = [
# 展示所有文章
path(‘/index/‘, views.ArticleListView.as_view(), name=‘article_list‘),
# 展示文章詳情
re_path(r‘^article/(?P<pk>\d+)/(?P<slug1>[-\w]+)/$‘,
views.ArticleDetailView.as_view(), name=‘article_detail‘),
# 添加文章
re_path(r‘^article/create/$‘,
views.ArticleCreateView.as_view(), name=‘article_create‘),
]

1. 在視圖views.py中利用HttpResponse重新定向至不含參數的URL

from .models import Article,
from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import ArticleForm

def article_create(request):
if request.method == ‘POST‘:
form = ArticleForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect("/index/")
else:
form = ArticleForm()
return render(request, ‘blog/article_create_form.html‘, {‘form‘: form})
如果/index/頁面有分頁功能, 你還可以通過使用HttpResponseRedirect(‘/index/?page=2‘)直接獲取第2頁的文章列表。

HttpReponseDirect只支持hard coded urls(硬編碼鏈接), 不能直接使用命名的URL,如使用HttpResponseDirect(‘blog:article_list‘)是錯誤的。在使用URL命名時,我們需要先通過URL反向解析方法reverse先對命名URL(article_list)進行解析,然後再使用HttpReponseRedirect定向(如下面的代碼)。背後的邏輯是reverse(‘blog:article_list‘)=‘/index/‘。

......
from django.http import HttpResponseRedirect
from django.urls import reverse
.....

def article_create(request):
if request.method == ‘POST‘:
form = ArticleForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse(‘blog:article_list‘))
....

2. 在視圖views.py中利用HttpResponseDirect重新定向至包含參數的URL

對於包含參數的URL(/article/2/new-day/),使用HttpResponseDirect定向前一般需要先使用reverse方法對命名的URL(如‘article_detail‘)進行解析,同時傳遞參數(如id, slug等)。

from .models import Article
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.shortcuts import render
from .forms import ArticleForm

def article_create(request):
if request.method == ‘POST‘:
form = ArticleForm(request.POST)
if form.is_valid():
article = form.save()
return HttpResponseRedirect(reverse(‘blog:article_detail‘, args=[str(article.pk), article.slug]))
else:
form = ArticleForm()
return render(request, ‘blog/article_create_form.html‘, {‘form‘: form})

其中最重要的一行代碼如下所示。大家可以仔細看下參數是如何傳遞到url的。

reverse(‘blog:article_detail‘, args=[str(article.pk), article.slug]

redirect方法

redirect是URL重新定向的便捷方法,在django.shortcuts模塊裏。HttpResponseRedirect能支持的URL重定向,redirect都支持。比如下面3種重定向是redirect的常規用法。

from django.shortcuts import redirect
from django.urls import reverse

# 案例1
def my_view(request):
...
return redirect(‘/index/‘)

# 案例2
def my_view(request):
...
return redirect(‘https://www.baidu.com/‘)

# 案例3
def my_view(request):
...
return redirect(reverse(‘blog:article_list‘))
redirect真正NB的地方在於,它不僅能根據URL重定向,還可以根據對象Object重定向和根據視圖view重定向,根據視圖重定向的時候還可以傳遞額外的參數。

1. 根據對象Object重定向

使用該方法的前提是模型裏已經定義了get_asbolute_url方法,使用redirect會自動調用get_absolute_url方法。

from django.shortcuts import redirect

def my_view(request):
...
obj = MyModel.objects.get(...)
return redirect(obj)

2. 根據視圖view重定向

使用該方法的前提已對URL進行了命名,且對應了相應的視圖。下面案例中redirect會先根據視圖函數的名字查找對應url,在傳遞額外參數。後臺工作還是由reverse方法來完成的。

def my_view(request):
...
return redirect(‘some-view-name‘, foo=‘bar‘)

reverse方法

reverse方法的作用是對已命名的URL進行反向解析,還傳遞相應的參數(args或帶key的參數kargs)。該方法位於django.urls模塊。reverse方法一般有2種應用場景:

在模型中自定義get_absolute_url時使用,傳遞參數

在視圖中對命名URL進行解析,傳遞參數,再使用HttpResponseDirect和redict進行重定向

1. 模型中自定義get_absolute_url,並傳遞參數args

def get_absolute_url(self):
return reverse(‘blog:article_detail‘, args=[str(self.pk), self.slug])

2. 在視圖中配合URL重定向使用,並傳遞kargs

from django.urls import reverse
from django.shortcuts import redirect

def my_view(request):
...
return redirect(reverse(‘admin:app_list‘, kwargs={‘app_label‘: ‘auth‘}))

還有一點容易被人們忽略的是reverse方法不僅能對命名的urls進行反向解析,還可以對視圖函數進行反向解析,找到需要重新定向的url, 如下面代碼所示。當然但這個方法我們並不推薦使用。與此功能相反的是resolve方法,該方法可以根據url找到對應視圖函數。

from django.urls import reverse
from blog import views
reverse(views.index)

小結

HttpResponseDirect, redirect和reverse三個方法都非常常用,在使用它們前忘了import進來哦。註意它們在不同的模塊。

HttpResponseDirect - django.http

redirect - django.shortcuts

reverse - django.urls

Django基礎(10): URL重定向的HttpResponseDirect, redirect和reverse的用法詳解