Django通过URLconf来实现请求的路由,URLConf定义了URL到视图函数的映射关系
一个简单的URLconf如下
from django.urls import path, include
from django.views.generic.base import TemplateView
from django.contrib.auth.decorators import login_required
from cmdb.views import CmdbList, CmdbDetail, PasswordList, PasswordDetail
urlpatterns = [
path('', login_required(TemplateView.as_view(template_name='index.html')), name='index-url'),
path('commons/', include('sadmin.commons.urls')),
path('accounts/', include('sadmin.accounts.urls')),
path('project/', include('sadmin.project.urls')),
path('cmdb/', CmdbList.as_view()),
path('cmdb/<int:pk>/', CmdbDetail.as_view()),
path('password/', PasswordList.as_view()),
path('password/<int:pk>/', PasswordDetail.as_view()),
]
path()
有四个参数,两个必须参数:route和view,两个可选参数kwargs和name
route是一个匹配URL的准则,当Django响应一个请求时,它会从urlpatterns的第一项开始,按顺序依次匹配列表中的项,直到找到匹配的项
route匹配准则跟请求Method或是请求参数或是域名都没有关系,例如URLconf在处理请求https://ops-coffee.cn/monitor/
时,它会尝试匹配monitor/
,处理请求https://ops-coffee.cn/monitor/?start=0&length=10
时,也只会尝试匹配monitor/
当Django找到了一个匹配的route,就会调用这个特定的视图函数,并传入一个HttpRequest
对象作为第一个参数
任意个关键字参数可以作为一个字典传递给目标视图函数
为URL取名可以在任意地方唯一的引用它,尤其是在模板中
函数include()
允许引用其它URLconfs。每当Django遇到include()
时,它会截断与此项匹配的URL的部分,并将剩余的字符串发送到 URLconf 以供进一步处理
Django设计include()
的理念使其可以即插即用。通常情况下每个APP的URL都单独在应用内管理,可以通过include()
方便的引用
转换器包含有以下几个:
使用re_path
可以通过正则表达式去匹配复杂的URL,例如
re_path('static/(?P<path>.*)$', static.serve, {'document_root': settings.STATIC_ROOT}, name='static'),
在 Python 正则表达式中,命名正则表达式组的语法是(?P<name>pattern)
,其中name是组名,pattern是要匹配的模式。组名name可以省略,不过不推荐
{% url 'monitor-list' %}
传递参数
{% url 'monitor-detail' data.id %}
from django.urls import reverse
reverse('index-url')
reverse支持添加动态参数,使用方法为:
reverse('accounts:user-list', kwargs={'pk': id})
URL重定向有两种方式,分别是HttpResponseRedirect
、redirect
HttpResponseRedirect是Django中推荐的重定向方式,在view中使用方法如下
from django.http import HttpResponseRedirect
def login(request):
if request.method == "POST":
form = AuthenticationForm(request, data=request.POST)
if form.is_valid():
auth.login(request, form.get_user())
# 登录成功重定向到next页面
return HttpResponseRedirect(_next = request.POST.get('next'))
else:
form = AuthenticationForm(request)
return render(request, 'accounts/login.html', {
'form': form,
'next': _next = request.POST.get('next')
})
HttpResponseRedirect接收一个参数就是要重定向到的URL地址
redirect是HttpResponseRedirect的便捷写法,HttpResponseRedirect能支持的URL重定向redirect都支持,例如以下三种常见写法
from django.shortcuts import redirect
from django.urls import reverse
def login(request):
return redirect('/index/')
def goto(request):
return redirect('https://blog.ops-coffee.cn')
def logout(request):
return redirect(reverse('accounts:logout-url'))
redirect不仅能根据URL重定向,还可以根据对象或试图重定向
def group(request):
obj = Model.objects.get(id=1)
return redirect(obj)
def login(request):
return redirect('some-view-name', name='coffee')
如果想在urls.py中直接配置URL重定向,可以通过如下方法
from django.views.generic import RedirectView
path('', RedirectView.as_view(url='/dashboard/'), name='index-url'),
以上的意思是将/
重定向到/dashboard