urls 路由
对于 Django 1.x 版本来说,路由是通过 url 方法来写的,且默认会按照正则进行匹配:
1 | from django.conf.urls import url |
url 写法
无名分组
url 路由写法:
1 | url(r'^books/(\d+)/(\d+)/', views.books), # url无名分组,也可以叫做无名参数 |
视图函数写法:
1 | def books(request,y,n):pass # y:拿到的是第一个参数,n:拿到的是第二个参数 |
传参方式是位置传参。
有名分组
url 路由写法:
1 | url(r'^books/(?P<year>\d+)/(?P<month>\d+)/', views.books) |
视图函数写法:
1 | def books(request,year,month):pass # year和month拿到的正则有名分组匹配到的那个名字相同的参数 |
传参方式是关键字传参,不考虑参数顺序,但是名称一定要和正则的相同
1 | def books(request,y,n=None):pass # n=None就是默认值,当url正则匹配不到数据时,使用默认值,匹配到了的话,使用匹配结果 |
注意:捕获的参数永远都是字符串
Django 2.x 版本 url 写法
在 Django 2.x 版本中,路由分为两种:普通路由和正则路由。普通路由使用 path,正则路由使用 re_path。导入方式为 django.urls
,而非 django.conf.url
。其他的用法与 Django 1.x 是相同的,就不再赘述。其大致写法为:
1 | from . import views |
url 斜杠
在写 url 配置时,前置导航斜杠不需要写:
1 | url(r'^home/', views.home) |
后面的斜杠是根据 Django 的配置来的。如果在settings配置文件中我们设置了
1 | APPEND_SLASH = False |
那么浏览器发送来的请求如果没有带着后面的斜杠,也是可以正常请求的。但是如果没有这个配置或者配置成 True 的话,Django 要求浏览器必须带着路径后面的斜杠来进行访问。如果你输入路径的时候没有加 /
,那么 Django
让你的浏览器发一个重定向请求带上 /
。
url 别名和反向解析
给路径取别名,当路径需要发生改变时,不必修改视图函数和代码中的引用方式。
urls 文件中的写法:
1 | url(r'^login/v2/', views.login,name='xx'), |
视图中反向解析:
1 | from django.urls import reverse |
html 模板渲染时反向解析的语法:
1 | {% url 别名 %} |
在页面中的写法就是:
1 | <form action="{% url 'xx' %}" method="post"> <!-- 这里是反向解析 --> |
include 路由分发
实际应用中,一个项目中可能会有很多应用。如果把这些应用的路由全都放到项目的 urls.py
文件中,那将是一个灾难——项目的 urls.py
文件将会变得异常臃肿杂乱,可读性极低,且不利于管理。
为了解决这个问题,我们可以在每个应用中也都配备自己的 url.py 路由文件。项目的总路由负责把请求分发给这些应用,这就是路由分发的作用。
其用法步骤如下:
项目文件夹下的
urls.py
文件中写上以下内容:1
2
3
4
5
6
7from django.conf.urls import url,include
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^app01/', include('app01.urls',namespace='app01')),
url(r'^app02/', include('app02.urls',namespace='app02')),
#http://127.0.0.1:8000/index/
]在各个 app 应用文件夹下面创建
urls.py
文件,在urls.py
文件中写自己应用的各个路径,比如app01
和app02
:1
2
3
4
5
6
7
8
9
10
11
12
13
14app01的urls.py配置:
from django.conf.urls import url, include
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^index/', views.index,name='index'),
]
app02的urls.py配置:
from django.conf.urls import url, include
from django.contrib import admin
from app02 import views
urlpatterns = [
url(r'^index/', views.index,name='index'),
]在各个应用中写各自的视图函数,当需要进行路径分发时,使用这样的格式:
1
return redirect('app01:index')
url 命名空间
基本写法:
1 | url(r'^app01/', include('app01.urls',namespace='app01')), |
views.py
文件中写法:
1 | from django.urls import reverse |
html
中写法:
1 | {% url 'app01:login' %} |
在 Django 2 版本中,光这样写也不成,会报错,还要在应用的 app01/urls.py
子路由中加上声明应用名的属性,例如:
1 | from django.urls import path |
带参 url 反向解析
url 别名反向解析时如果需要参数,HTML 代码中可以在别名后直接加上参数:
1 | {% url '别名' 3 %} |
实际上在模板渲染时,路径被渲染为 /index/3/
的形式。所以,在路由分发时,我们可以使用正则传参的方式,把参数传递给视图函数:
1 | url(r'^index/(\d+)/', views.index, name='index'); |
如果在 views 视图反向解析时需要传入参数,我们只需增加 arg 参数即可:
1 | reverse('index',args=(3,)) # /index/3/ |
携带数据按钮
编辑按钮携带数据,主要是通过 get 请求和路径参数的方式:
1 | <a href="{% url 'book_edit' %}?book_id={{ book.id }}" class="btn btn-warning btn-sm">编辑</a> |