djiango路由匹配、djiango路由层、反向解析、有名无名反向解析
djiango路由匹配、djiango路由层、反向解析、有名无名反向解析
一、作业讲解(数据的增删改查)
urls代码
from django.contrib import admin
from django.urls import path, re_path
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
# 访问用户数据的接口
path('user_list/', views.user_list_func), # user_list_func(实参request对象)
# 添加用户数据的接口
path('user_add/', views.user_add_func),
# 编辑用户数据的接口
path('user_edit/', views.user_edit_func),
# 删除用户数据的接口
path('user_delete/', views.user_delete_func)
]
views代码
from django.shortcuts import render, HttpResponse, redirect, reverse
from app01 import models
Create your views here.
def user_list_func(request):
# 1.获取user表中所有的数据展示到html页面上
user_data = models.User.objects.filter() # 括号内不填筛选条件等价于查所有 QuerySet [对象1,对象2,对象3...]
# 2.利用模板语法传递数据到html页面并完成处理最终返回给浏览器展示
return render(request, 'userListPage.html', {'user_data': user_data})
def user_add_func(request):
# 2.根据不同的请求方式做不同的处理
if request.method == 'POST':
# 3.获取用户相关数据
name_data = request.POST.get('name')
age_data = request.POST.get('age')
# 4.继续一些小的判断
if len(name_data) == 0 or len(age_data) == 0:
return HttpResponse('用户名或年龄不能为空')
user_data = models.User.objects.filter(name=name_data)
if user_data:
return HttpResponse("用户名已存在")
models.User.objects.create(name=name_data, age=age_data)
# 5.重定向到数据展示页
return redirect('/user_list/')
# 1.先返回一个获取新增用户数据的html页面
return render(request, 'userAddPage.html')
def user_edit_func(request):
# 1.获取用户想要编辑的数据主键值
target_edit_id = request.GET.get('edit_id')
# 4.根据不同的请求处理不同的逻辑
if request.method == 'POST':
name_data = request.POST.get('name')
age_data = request.POST.get('age')
if len(name_data) == 0 or len(age_data) == 0:
return HttpResponse('用户名或年龄不能为空')
models.User.objects.filter(pk=target_edit_id).update(name=name_data, age=age_data)
# 5.重定向到数据展示页
return redirect('/user_list/')
# 2.根据主键值获取对应的数据
target_edit_obj = models.User.objects.filter(pk=target_edit_id)[0] # QuerySet [对象1,对象2,...]
# 3.返回一个编辑数据的页面 并且该页面上需要提前展示出原来的数据
return render(request, 'userEditPage.html', {'target_edit_obj': target_edit_obj})
def user_delete_func(request):
target_delete_id = request.GET.get('delete_id')
models.User.objects.filter(pk=target_delete_id).delete()
return redirect('/user_list/')
def index_func(request, info, id):
print('info:', info)
print('id:', id)
return HttpResponse("index func")
def index_func(request,id):
print('id:', id)
return HttpResponse("index func")
def test(request, aaa, others):
print('aaa', aaa)
print('others', others)
return HttpResponse("test")
def testadd(request):
return HttpResponse("testadd")
def login(request):
return HttpResponse('login html')
def home(request):
print(reverse('login_view'))
print(reverse('func1_view', args=('嘿嘿嘿',)))
return render(request, 'homePage.html')
def func1_func(request, others):
return HttpResponse('func1_func html')
models代码
from django.db import models
Create your models here.
class User(models.Model):
# 主键字段可以不写 ORM会自动帮你创建一个id的主键字段
name = models.CharField(max_length=32, verbose_name='用户名')
age = models.IntegerField(verbose_name='年龄')
# 便于对象打印之后的查看 不影响数据库 所以不需要执行迁移命令
def __str__(self):
return '用户对象:%s' % self.name
二、django请求生命周期流程图
django请求生命周期指的是:当用户在浏览器上输入url到用户看到网页的这个时间段内,Django后台所发生的事情。
首先,用户在浏览器中输入url,发送一个GET方法的request请求。
Django中封装了socket的WSGi服务器,监听端口接受这个request 请求,
再进行初步封装,然后传送到中间键中,这个request请求再依次经过中间键,
对请求进行校验或处理,再传输到路由系统中进行路由分发,匹配相对应的视图函数(FBV),
再将request请求传输到views中的这个视图函数中,进行业务逻辑的处理,
调用modles中表对象,通过orm拿到数据库(DB)的数据。
同时拿到templates中相应的模板进行渲染,然后将这个封装了模板response响应传输到中间键中,
依次进行处理,最后通过WSGi再进行封装处理,响应给浏览器展示给用户。
三、路由层
1.路由匹配
默认情况下如果不加/的话,django会做第二次处理
第一次匹配不上,会让浏览器再次请求
django配置文件中科院指定是否自动添加斜杠
APPEND_SLASH = Fale(默认是True,不加/的话就不能访问到了)
2.path转换器
当网址后缀不固定的时候,可以用转换器来匹配
'int' : IntConverter(), 匹配0或者任意正整数
'path' : PathConverter(), 能够匹配完整的URL路径
'slug' : SlugConverter(), 匹配任意一个由字母或数字组成的字符串
'str' : StrConverter(), 匹配除路径分隔符外的任何非空字符串
'uuid' : UUIDConverter(), 匹配格式化后的UUID
path('func/<int:year>/<str:info>',view.func)
转换器匹配到的内容会当做视图函数的关键字参数传入
转换器有几个,叫什么名字,视图函数的形参必须一一对应
path('index/<str:info>/', views.index_func),
# index_func(实参request对象,info='转换器匹配到的类型转换之后的内容')
path('index/<str:info>/<int:id>/', views.index_func)
# index_func(实参request对象,info='转换器匹配到的类型转换之后的内容',id='转换器匹配到的类型转换之后的内容')
path('index/<str:info>/p/<int:id>/', views.index_func)
# index_func(实参request对象,info='转换器匹配到的类型转换之后的内容',id='转换器匹配到的类型转换之后的内容')
3.re_path正则匹配
re_path(正则表达式,函数名)
一旦网址后缀的正则能够匹配到内容就会自动执行后面的函数,并结束整个路由的匹配
re_path('^test/$',view.test)
当网址后缀不固定时,可以使用转换器来匹配
4.正则匹配之无名分组
re_path('^test/(\d+)/',view.test)
正则表达式匹配到的内容会当做
5.正则匹配之有名分组
re_path('^path/(?p<year>\d{4})/',views.test)
会将括号内正则匹配到的内容当做关键字参数传递给视图函数
6.django版本的区别
在django1.11中
只支持正则匹配,并且方法是url()
在django2.22中
path()/re_path() 等价于url()
四、反向解析
1.反向解析的概念
页面提前写死了很多的路由,一旦路由发生变化会导致页面相关的链接失效
为了防止这种问题的出现,就需要使用反向解析’
通过一些方法得到一个结果 该结果可以直接访问对应的url触发视图函数
实现url路由频繁变化,html界面与后端动态解析连接地址操作步骤
2.反向解析路由配置
先给路由起一个别名:
url('/index/',index_func,name = 'index')
3.反向解析语法
1.导入模块
from django.shortcts import reder,HttpResponse,redirect,reverse
2.反向解析 关键字 reverse('insex')
def home(request):
print(reverse('index'))
return render(request,'home.html')
3.前端模板文件反向解析
<a href = '{% url 'index' %}'>111</a>
4.动态路由的反向解析
path('reg/<str:info>/',views.reg,name='reg_view')
党路由中又不确定的匹配因素,返现解析的时候需要认为给出一个具体的值
reverse('reg_view',args=('jason',))
{% url 'reg_view' 'jason' %}
ps:
反向解析的操作,三个方法都是一样(path()/re_path()/url())