django学习笔记51.路由层1.re_path(reg,view,name) #reg正则2.re模块3.re.match与re.search4.无名分组,有名分组5.前端反向解析{% url 'ooo'%}6.后端反向解析reverse()7.无名分组,有名分反向解析2.快捷创建应用3.include路由分发
项目同名文件夹下init.py这个文件中添加以 下两句话:(数据库8.0时,进行数据库迁移时报错 为2026的解决方法) import pymysql pymysql.install_as_MySQLdb()
models创建一些外键字段
from django.db import models # Create your models here. class User(models.Model): #auto_increament,int类型 id = models.AutoField(primary_key=True) username = models.CharField(max_length=32) password = models.CharField(max_length=32) #每增加记录,需要设空或设置默认值,并进行数据迁移 hobby = models.CharField(max_length=32,null=True) info = models.CharField(max_length=32,default='student') class Book(models.Model): title = models.CharField(max_length=32) #max_digits表示总位数,decimal_places表示小数点位数 price = models.DecimalField(max_digits=8,decimal_places=2) # 图书和出版社是一对多的关系,一般情况下会将外键字段建立在查询比较多的图书表中 # 可以将外键字段名字就设置为publish, orm会自动加上id # 默认就是与出版社的主键字段进行关联 publish = models.ForeignKey('Publish', on_delete=models.CASCADE,null=True) # authors是一个虚拟字段,相当于一个地址并不存在 authors = models.ManyToManyField('Author') class Publish(models.Model): name = models.CharField(max_length=32) addr = models.CharField(max_length=64) class Author(models.Model): name = models.CharField(max_length=32) author_detail = models.OneToOneField('AuthorDetail',on_delete=models.CASCADE,null=True) class AuthorDetail(models.Model): age = models.IntegerField() phone = models.BigIntegerField() addr = models.CharField(max_length=64)
1.路由层
path(路由,视图,别名)
1.re_path(reg,view,name) #reg正则
正则表达式是一个特殊的字符序列,能够帮助你 检查一个字符串是否与某种模式匹配
^:匹配字符串的开头'^1' $:匹配字符串的末尾
[...]:用来表达一组字符 [ ^.. . ]:不在的字符
*:0个或多个
:1个或多个 {n}:匹配n个前面的表达式 ():对表达式进行分组 \w:匹配字母数字下划线 \W:匹配非字母数字下划线 \d:匹配任意数字->[0-9] \D:匹配非数字 \s:匹配空白字符 \S:匹配非空字符
关于url后面加/的问题:有时候你没有加/,django 也会自动帮你加上/去匹配 #取消自动加/ 在settings.py中加上 APPEND_SLASH=False#默认是自动加斜杆的
2.re模块
re模块是python提供正则表达式功能的 re.match(匹配的正则,字符串) span():查询匹配到的字符串的索引 re.match('www 'www.baidu.com').span() re.search(匹配的正则,字符串) match和search的区别:match只会匹配字符串的 开始,如果开始不符合则匹配失败.search匹配整 个字符串
re.match只能匹配开头
3.re.match与re.search
compile():用于编译正则表达式的,生成一个正则 表达式,供match和search函数使用
4.无名分组,有名分组
无名分组
re_path('test/(\d+)/',views.test), 正则匹配会将括号内匹配的内容当做位置参数 传递给后面的视图函数
有名分组
re_path('(?P<year>d+)/',views.test), 有名分组就是将括号内正则表示式匹配到的内 容当做关键字参数传递给后面的视图函数
视图函数需要使用参数去接收传递过来的参数,有名分组与无名分组唯一的区别就是参数名是否指定
test1(request, x) test2(request,name)
urlpatterns = [ path('admin/',admin.site.urls), re_path('',views.home), #无名分组加括号 re_path('test/(\d+)/',views.test1), #有名分组需要一个名字去命名 re_path('(?P<name>\d+)/',views.test2), ]
views.py 需要分别传递参数 位置参数 与 name参数
test1(request, x) test2(request,name)
urls.py
url_patterns=[ re_path('^$',views.home), re_path('test/(\d+)/(\d+)/(\d+)/',views.testadd), re_path('(?P<year\d+)/(?P<month>\d+)/(?P<day>\d+)/',views.test) ]
views.py
def testadd(request,x,y,z): #x,y,z是位置参数 print(x,y,z) return HttpResponse('无名分组') def test(request,year,month,day ) #year,month,day是关键字参数 print(year,month,day) return HttpResponse('有名分组')
5.前端反向解析{% url 'ooo'%}
反向解析 反向解析的本质:通过一些方法可以得到一个结 果,该结果可以直接访问对应的url触发的视图函 数
path('/index/',views.index,name='ooo')
无论url怎么变化,只要有{% url 'ooo'%}就能进入相应路由
<a href = "{% url 'ooo' %}"> 666 </a>
6.后端反向解析reverse()
views.py导入reverse
from django.shortcuts import render,HttpResponse,reverse
可以通过name得到进入的路由
urls.py
path('func_ooo/',views.func,name='ooo'),
views.py
print(reverse('ooo'))
7.无名分组,有名分反向解析
html页面需要用{% url name 参数值%},参数值是位置参数或者关键字参数
urls.py
写成
<a href="{%ur1'xxx'123%}">111</a>
或者
<a href="{%ur1'xxx' uid = 123%}">111</a>
re_path('test/(\d+)/',views.testadd,name='xxx'), #testadd(request,xyz)需要用xyz去接收,而无名分组则不需要指定的名字 re_path('test/?<xyz>(\d+)/',views.testadd,name='yyy')
home.html
123作为 参数 传递给 分组
<a href="{%ur1'xxx'123%}">111</a> <a href="{%ur1'yyy'123%}">111</a>
后端也需要位置参数args=(123,) 或者关键字参数kw_args={'xyz':123}去接收
def home(request): # 无名参数 需要 位置参数 ,也就是元组 print(reverse('xxx',args=(123,)) print(reverse('yyy',kw_args={'xyz':123}) return render(request,home.html')
2.快捷创建应用
创建qpp02
-
1.命令行 执行 python manage.py startapp app02
-
或者快捷 执行命令startapp app02
-
在settings.py注册应用
3.include路由分发
1.app01,app02两个文件夹分别创建urls.py,urls.py,templates文件夹创建应用文件夹app01,app02
app01>urls.py
from django.contrib import admin from django.urls import path,re_path from app01 import views as app01views urlpatterns = [ path('admin/', admin.site.urls), re_path('^$',app01views.home), re_path('/func/(\d+)',app01views.func1,name='wuming'), re_path('/func2/?<year>(\d+)',app01views.func2,name='youming'), path('login/',app01views.login), path('register/',app01views.register) ]
app01>views.py
def home(request): #增加app01/前缀 return render(request, 'app01/home.html')
2.删除day2>urls.py原来的 路由-视图 对应关系,导入include模块,导入其他应用的urls.py
day2>urls.py
from django.urls import path,re_path,include from appe1 import urls as app01_url from app02 import urls as app02_url
3.总路由只做include分发,而对应关系留给app路由
day2>urls.py
urlpatterns = [ path('admin/',admin.site.urls), path('app01/',include(appe1_url)), path('app02/',include(app02_ur1)), ]
或者只导入include,相应的include直接写字符串应用名
from django.contrib import admin from django.urls import path,re_path,include urlpatterns = [ path('admin/', admin.site.urls), path('app01/',include('app01.urls')), path('app02/',include('app02.urls')), ]