运维咖啡吧

享受技术带来的乐趣,体验生活给予的感动

Django URL常见用法及配置介绍

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

path()有四个参数,两个必须参数:route和view,两个可选参数kwargs和name

route

route是一个匹配URL的准则,当Django响应一个请求时,它会从urlpatterns的第一项开始,按顺序依次匹配列表中的项,直到找到匹配的项

route匹配准则跟请求Method或是请求参数或是域名都没有关系,例如URLconf在处理请求https://ops-coffee.cn/monitor/时,它会尝试匹配monitor/,处理请求https://ops-coffee.cn/monitor/?start=0&length=10时,也只会尝试匹配monitor/

view

当Django找到了一个匹配的route,就会调用这个特定的视图函数,并传入一个HttpRequest对象作为第一个参数

kwargs

任意个关键字参数可以作为一个字典传递给目标视图函数

name

为URL取名可以在任意地方唯一的引用它,尤其是在模板中

include

函数include()允许引用其它URLconfs。每当Django遇到include()时,它会截断与此项匹配的URL的部分,并将剩余的字符串发送到 URLconf 以供进一步处理

Django设计include()的理念使其可以即插即用。通常情况下每个APP的URL都单独在应用内管理,可以通过include()方便的引用

URL取值

转换器包含有以下几个:

re_path

使用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 %}

View中使用

from django.urls import reverse

reverse('index-url')

reverse支持添加动态参数,使用方法为:

reverse('accounts:user-list', kwargs={'pk': id})

View中的URL重定向

URL重定向有两种方式,分别是HttpResponseRedirectredirect

HttpResponseRedirect

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

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')

URL中的URL重定向

如果想在urls.py中直接配置URL重定向,可以通过如下方法

from django.views.generic import RedirectView

path('', RedirectView.as_view(url='/dashboard/'), name='index-url'),

以上的意思是将/重定向到/dashboard