Django 路由

介绍

Django路由就是URL映射,用户通过不同的URL地址,来获取信息,而这些信息是开发者针对每个不同URL处理后做出的响应。

Django的URL配置,配置文件:ROOT_URLCONF 它允许项目URL的入口。

收到URL请求,视图接收的参数:

  • 一个 HttpRequest 实例,必须为第一项。
  • 正则组,如果没有给组命名,将使用位置传参。
  • 如果正则组中有命名,而且kwargs参数中的的键名一致,则正则表达式中的命名被覆盖。

参数kwargs

下面命名存在了覆盖,不管正则匹配到的是什么,都将会使用kwargs中的n。

re_path(r'(?P<n>\w+/$)',views.index,name='index',kwargs={'n':'kwargs_n'})

函数接收,因为命名一致,使用一个n即可。

def index(request,n):

path

在新版的Django中,默认使用path。用法与之前的url有所不同,因为它有一些自己的匹配方式。

django.urls.path()

语法:django.urls.path(route,view,kwargs,name)

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

route

route 是一个匹配 URL 的准则(类似正则表达式)。

view

当 Django 找到了一个匹配的准则,就会调用这个特定的视图函数,并传入一个 HttpRequest 对象作为第一个参数,被“捕获”的参数以关键字参数的形式传入。

kwargs

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

name

为你的 URL 取名能使你在 Django 的任意地方唯一地引用它,尤其是在模板中。这个有用的特性允许你只改一个文件就能全局地修改某个 URL 模式。

实例

from django.urls import path
from . import views

urlpatterns = [
    path('<int:year>/',views.index),
    path('<int:year>/<int:month>/',views.person_info)
]

匹配

第一个:2020/

第二个:2020/3/

无匹配:2020

注意

  • 捕捉一段url需要使用:<>
  • 捕捉后的返回内容,没有:/
  • 匹配模式的最开头不需要添加/,因为默认情况下,每个url都带一个最前面的/

规则

  • str:匹配任何非空字符串,但不含斜杠/,如果你没有专门指定转换器,那么这个是默认使用的;
  • int:匹配0和正整数,返回一个int类型
  • slug:可理解为注释、后缀、附属等概念,是url拖在最后的一部分解释性字符。该转换器匹配任何ASCII字符以及连接符和下划线,比如’ building-your-1st-django-site‘;
  • uuid:匹配一个uuid格式的对象。为了防止冲突,规定必须使用破折号,所有字母必须小写,例如’075194d3-6885-417e-a8a8-6c931e272f00‘ 。返回一个UUID对象;
  • path:匹配任何非空字符串,重点是可以包含路径分隔符’/‘。这个转换器可以帮助你匹配整个url而不是一段一段的url字符串。

re_path

如果你想使用正则表达式,你可以使用re_path。它其实是兼容老板中的url。

re_path的参数与path的参数完全一致,只是规则按照正则。它们都被放在了django.urls中。

简单用应

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

urlpatterns = [
    path('<int:year>/',views.index),
    re_path(r'^(?P<year>\d{4})/(?P<month>\d{1,2})/$',views.person_info)
]

注意

  • 传递给视图的所有参数都是字符串类型。而不像path()方法中可以指定转换成某种类型。在视图中接收参数时一定要小心。

有名分组

在Python 正则表达式中,命名正则表达式组的语法是(?P<name>pattern),其中name 是组的名称,pattern 是要匹配的模式。

我们上面其实已经用的过了,再将上面的例子拿下里应用。

实例

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

urlpatterns = [
    path('<int:year>/',views.index),
    re_path(r'^(?P<year>\d{4})/(?P<month>\d{1,2})/$',views.person_info)
]

path

<int:year> 其中year是一组命名。

视图接收

def index(request,year):

re_path

有两个有命名的组:year month。

视图接收

def person_info(request,year,month):

路由分发

我们一般会在APP中创建一个urls.py,把APP中的路由放在里面,而不是放在根urls.py中,因为这样显得额外清晰。

django.urls.include(arg)

允许引用其它 URLconfs。很快我们就会用到它。

arg:URLconf的名。

实例

url地址:

127.0.0.1/index/introduce

127.0.0.1/index/music

127.0.0.1/index/movie

不使用路由分发

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

urlpatterns = [
    re_path(r'^index/introduce/$',views.introduce),
    re_path(r'^index/music/$',views.music),
    re_path(r'^index/movie/$',views.movie),
]

如果现在要将index改为home咋办?一个一个修改吗?好像有点牵强吧。

使用路由分发

app/urls.py

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

urlpatterns = [
    re_path(r'introduce/$',views.introduce),
    re_path(r'music/$',views.music),
    re_path(r'movie/$',views.movie),
]

根/ursl.py

from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('index/', include('My_app.urls'))
]

反向解析

在使用Django 项目时,一个常见的需求是获得URL 的最终形式,以用于嵌入到生成的内容中(视图中和显示给用户的URL等)或者用于处理服务器端的导航(重定向等)。

模板中

语法

{% url '名' %}

{% url '名' '参数值1' '参数值2' %}

app/urls.py

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

urlpatterns = [
    path('index/<str:name>/',views.index),
    path('person_info/<str:name>/',views.person_info,name='person_info')
]

app/views.py

from django.shortcuts import render,HttpResponse,reverse,redirect

# Create your views here.

def index(request,name):
    return render(request,'index.html',{'name':name})

def person_info(request,name):
    return HttpResponse('%s的个人博客'%name)

templates/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Index</title>
</head>
<body>

<ul>
    <li>姓名:{{ name }}</li>
    <li>个人博客:<a href="{% url 'person_info' name%}">{{ name }}</a></li>
</ul>

</body>
</html>

运行

访问:127.0.0.1/index/Kidd

点击,个人博客

Python中

语法

reverse('名',args=(,))

app/urls.py

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

urlpatterns = [
    path('<int:year>/',views.year,name='year'),
    re_path(r'^(?P<year>\d{4})/(?P<month>\d{1,2})/$',views.year_month,name='year_month')
]

app/views.py

from django.shortcuts import render,HttpResponse,reverse,redirect

# Create your views here.

def year(request,year):
    return redirect(reverse('year_month',args=(year,3)))

def year_month(request,year,month):
    return HttpResponse('year:%s,month:%s'%(year,month))

跳转

输入:127.0.0.1/2020/

自动跳转

127.0.0.1/2020/3/

命名空间

app/urls.py

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

app_name = "app_watch"

urlpatterns = [
    re_path(r"^index/$",views.index,name="index"),
]

html

 <a href="{% url 'app_watch:index' %}">首页</a>

根/urls.py

urlpatterns = [
    path('admin/', admin.site.urls),
    path("", include("app_watch.urls",namespace="app_watch"))
]

实例

当你一个视频网站有很多种类的视频时,你可以根据URL反解,来获取最终的herf。

创建HTML,当你点击时,生成一个URL。

<a href="{% url "app_watch:category" "1" %}">动作</a>
<a href="{% url "app_watch:category" "2" %}">爱情</a>
<a href="{% url "app_watch:category" "3" %}">喜剧</a>

创建命名空间,当你去访问 Category-1 时也就是动作,这样的好处后端修改URL,前端无需修改。

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

app_name = "app_watch"

urlpatterns = [
    re_path(r"^index",views.index,name="index"),
    re_path("Category-(\d+).html",views.get_data,name="category"),
]

在根目录下添加命名空间。

urlpatterns = [
    path('admin/', admin.site.urls),
    path("", include("app_watch.urls",namespace="app_watch"))
]

 

posted @ 2020-04-05 10:46  Sun先生  Views(317)  Comments(0Edit  收藏  举报