1. URL与视图函数的映射
在Django中,URL与视图函数的映射通过编写URLconf(URL配置)来完成。这些映射定义在应用的views.py文件中的视图函数,以及在应用的urls.py文件中。
项目的url.py文件,代码如下:
from django.contrib import admin
from django.urls import path
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', views.index),
path('user/list/', views.userlist),
path('something/', views.something),
path('login/', views.login),
path('orm/', views.orm),
# 用户管理
path('info/list/', views.info_list),
path('info/add/', views.info_add),
path('info/delete/', views.info_delete),
]
在app01的views.py里定义视图函数
from django.shortcuts import render, HttpResponse, redirect
from app01.models import Department, UserInfo
# Create your views here.
def index(request):
return HttpResponse("欢迎使用")
def userlist(request):
name = "张飞"
roles = ["安全管理员", "系统管理员", "审计管理员", "超级管理员"]
user_info = {"name": "Hr", "Salary": 10000, "role": "CEO"}
data_list = [
{"name": "刘备", "Salary": 20000, "role": "CEO"},
{"name": "张飞", "Salary": 18000, "role": "CFO"},
{"name": "关羽", "Salary": 15000, "role": "C00"}
]
return render(request, "user_list.html", {"n1": name, "n2": roles, "n3": user_info, "n4": data_list})
2. URL的两种传参方式
在URL中携带参数 1. 通过查询字符串(query string): https://www.baidu.com/s/wd=python$a=1$b=2 2. 在path中携带: http://127.0.0.1:8000/book/2
urls.py文件代码如下:
urlpatterns = [
# 1.通过查询字符串携带参数
# http://127.0.0.1:8000/book?id=1
path('book/', views.book_detail_query_string)
# 2.在path中携带参数
# http://127.0.0.1:8000/book/1
# 在book_id前指定参数类型有两点好处:
# 1)以后在浏览器总,如果book_id输入的是一个非整形,那么会出现404错误
# 2)在视图函数中,得到的book_id就是一个整形,否则,默认是str类型
path('book/<int:book_id>/', views.book_detail_path)
]
3. path 函数
path 函数的定义为:
path(route, view, name=None, kwargs=None)
参数详解:
- route参数:url的匹配规则,这个参数中可以制定url中需要传递的参数,比如在访问文章详情页的时候,可以传递一个id。传递参数是通过<>尖括号来进行指定的。并且在传递参数的时候,可以指定这个参数的数据类型,比如文章的id都是int类型,那么可以这样写,以后匹配的时候,就只会匹配到id为int类型的url,而不会匹配其他的url,并且在视图函数中货哦区这个参数的时候,就已经被转换成一个int类型了。其中还有几种常用的类型:
- str: 非空的字符串类型,默认的转换器,但是不能包含斜杠。
- int: 匹配任意的零或者正数的整形,到视图函数中就是一个int类型。
- slug: 由英文中的横杠 -,或者下划线_连接英文字符或者数字而成的字符串。
- uuid: 匹配uuid字符串。
- path: 匹配非空的英文字符串,可以包含斜杠/。
- view参数:可以为一个视图函数或者类视图.as_view()或者是django.urls.include()函数的返回值。
- name参数:这个参数是给这个url取名用的,这在项目比较大,url比较多的时候用处很大。
4. 路由模块化
如果有多个app,把所有app的views中的视图都放在urls.py中进行映射,肯定会让代码显得非常乱。因此django给我们提供了一个方法,可以在app内部包含自己的url匹配规则,然后在项目的urls.py中统一包含这个app的urls。使用这个技术需要借助include函数,示例代码如下:
# mysite/urls.py文件
from django.contrib import admin
from django.urls import path, include
urlpattherns = [
path('admin/', admin.site.urls),
path('book/', include("book.urls")),
]
在urls.py文件中把所有的和book这个app相关的url都移动到app/urls.py文件中,然后在mysite/ulrs.py中,通过include函数包含book.urls,以后在请求book相关的url的时候都需要加一个book的前缀。
# book/urls.py文件
from django.urls import path
from . import views
# 指定应用名称(应用命名空间)
app_name = 'book' # 名称跟app的名字保持一致
'''
在 Django 中,指定应用命名空间(app_name)是为了帮助区分不同应用中的 URL 名称,避免命名冲突,并使得 URL 反转和重定向更加清晰和可预测。
当你有多个应用,并且这些应用中有相似的 URL 名称时,如果没有命名空间,Django 无法确定你要引用的是哪个应用的 URL。指定了命名空间之后,你可以通过 :<namespace>:<name> 的形式唯一地标识一个 URL。
例如,假设你有两个应用 app1 和 app2,它们都有一个名为 detail 的 URL。如果你没有为这两个应用指定命名空间,当你尝试反转 URL(例如使用 reverse('detail'))时,Django 会不知道你要引用的是哪个应用的 detail URL。
'''
urlpatterns = [
path('list/', views.book_list),
path('detail/<int:book_id>/', views.book_detail)
]
5. 路由反转
如果想通过视图函数,反转回它的url,可以通过reverse来实现,示例代码如下:
reverse("list")
> /book/list/
如果有应用命名空间或者有实例命名空间,那么应该在反转的时候加上命名空间,示例代码如下:
reverse('book:list')
> /book/list/
如果这个url中需要传递参数,那么可以通过kwargs来传递参数,示例代码如下:
reverse("book:detail", kwargs={"book_id":1})
> /book/detail/1
因为django中的reverse反转url的时候不区分GET请求和POST请求,因此不能在反转的时候条按价查询字符串的参数,如果想要添加查询字符串的参数,只能手动的添加,示例代码如下:
login_url = reverse('login') + '?next=/'
5.1 案例
在mysite/urls.py文件里的path,一定要写name参数,如下:
# mysite/urls.py文件
from django.contrib import admin
from django.urls import path, include
urlpattherns = [
path('admin/', admin.site.urls),
path('book/', include("book.urls")),
]
在book/urls.py文件里代码如下:
# book/urls.py文件
from django.urls import path
from . import views
# 指定应用名称(应用命名空间)
app_name = 'book' # 名称跟app的名字保持一致
urlpatterns = [
path('list/', views.book_list, name='book_list'),
path('detail/<int:book_id>/', views.book_detail, name='book_detail')
]
在views.py文件里的视图函数代码如下:
from django.urls import reverse
def list(request):
url = reverse('list')
# 返回的就是 /book/list/