目录
一.路由层
1.路由的作用
路由即请求地址与视图函数的映射关系,如果把网站比喻成一本书,那路由就好比是这本书的目录,在Django中路由默认配置urls.py中
2.路由匹配
# 路由匹配
path('test',views.test),
path('testadd',views.testadd),
无法跳转到testadd
- url方法第一个参数是正则表达式
- 只要第一个参数正则表达式能够匹配到内容,就会立刻停止匹配,执行视图函数
# 路由匹配
path('test/',views.test),
path('testadd/',views.testadd),
在参数尾部加一个/
- 在输入url的时候会默认加一个/
- Django内部会帮助我们做一个重定向
- 一次匹配不行就再加一个/再尝试一次
在配置文件中,有一个参数可以帮助我们干这件事
APPEND_SLASH = True
这个参数默认是True,即自动帮我们加/
re_path('^test/$',views.test),
这才是完整版的路由匹配格式
re_path('^$',views.test),
匹配首页的路由格式
二.无名分组
分组就是将某段正则表达式用()括起来
# 无名分组
re_path(r'^test/(\d+)/', views.test),
def test(request,data):
print(data)
return HttpResponse('test')
无名分组就是将括号内正则表达式匹配到的内容当作位置参数传给后面的视图函数
三.有名分组
可以给正则表达式起一个别名
# 有名分组
re_path(r'r^testadd/(?P<year>\d+)',views.testadd),
def testadd(request,year):
print(year)
return HttpResponse("testadd")
有名分组就是将括号内正则表达式匹配到的内容当作关键字参数传给后面的视图函数
四.无名分组和有名分组混用
无名分组和有名分组不可以混用,但是一个分组可以使用多次
# 无名分组和有名分组混用
re_path(r'^index/(\d+)/(?P<year>\d+)/',views.index),
def index(request,args,year)
return HttpResponse("index")
五.反向解析
- 通过一些方法得到一个结果,该结果可以直接访问到对应的url,触发视图函数
- 先给路由与视图函数起个别名
re_path(r'func/', views.func,name="xxxxxx"),
- 反向解析
- 后端反向解析
from django.shortcuts import render, HttpResponse,reverse
def home(request):
reverse("xxxx"))
- 前端反向解析
<a href="{% url 'xxxx' %}">111</a>
六.无名有名分组反向解析
本质上还是通过一些方法得到一个结果,该将结果可以访问到对应的url从而触发相应的视图和功能
1.无名分组反向路由解析
(1)引入
1.1路由
# 无名分组反向解析
re_path(r'^index/(\d+)/',views.index,name='xxx'),
1.2视图
def home(request):
print(reverse('xxx'))
return render(request,'home.html')
1.3前端
<a href="">{%url 'xxx' %}</a>
我们会发现这样跳转到我们的xxx指定路由字段的时候会报错,提示匹配不到我们写的路由表单式,这是因为我们返回数据的时候,因为我们的路由正则表达式是r'^index/(\d+)/'路由地址后面是需要跟数字的,我们现在在根路由的后面不跟参数就不能被匹配到,所以主动抛出异常
(2)解决方法
2.1路由
# 无名分组反向解析
re_path(r'^index/(\d+)/',views.index,name='xxx'),
2.2视图
def home(request):
print(reverse('xxx',args=(1,)))
return render(request,'home.html')
2.3前端
<a href="">{% url 'xxx' 123 %}</a>
当我们跳转到指定路由地址的时候,在后面携带参数,这样就可以避免像上面一样,抛出异常,匹配不到
(3)小结
- 这个数字存在的意义到底是什么?
- 数字一般情况下放的是数据的主键值
- 数据的标记和删除功能
通过在根路径的后面拼接指定的地址,从而对这个指定的地址进行数据的更改
# 路由层
re_path('edit/<int:pk>/',views.deit,name='edit')
# 视图层def edit(request,edit_id):
reverse("edit",args=(edit_id,))
# 前端{% for user.obj in user_queryset %}
<a href="{% url 'edi' user_obj.id %}">
{% endfor %}
2.有名分组反向解析
(1)问题引入
2.1路由
# 有名分组反向解析
re_path(r'^fuc/(?P<year>\d+)', views.func, name='ooo')
2.2视图
def func(request,year):
print(reverse('000')
return render(request, 'home.html')
问题同上面,还是没有匹配到符合正则表达式的路由,因为我们的正则表达式是r'^func/(?P<year>\d+)',理论上无名传入的数据格式应该对year进行指定func/year=1/
(2)解决方案
2.1路由
# 有名分组反向解析
re_path(r'^func/(?P<year>\d+)',views.func,name='xxx')
2.2视图
def home(request,year):
# print(reverse('xxx', args=(1,)))
# 有名分组的标准写法
# print(reverse('ooo', kwargs={"year": 123}))
# 简便写法
print(reverse('xxx', args=(1,)))
return render(request, 'home.html')
2.3前端
<a href="">{% url 'ooo' year=123 %}</a>有名分组
当我们向指定的形参进行参数传递时,就能被指定的路由匹配表达式所匹配,从而访问到指定的页面
七.路由分发
-
Django每一个应用都可以拥有属于自己的
- templates文件夹
- urls.py
- static文件夹
-
正是基于上述的特点,Django可以很好的做到自己的分组开发(每个人只写自己的app)
-
最后只需要将所有的app拷贝到新的文件,并将这些APP注册到配置文件中,然后再利用路由分发的特点,将所有的APP整合起来
-
当一个项目中的URL特别多的时候,总路由urls.py的代码非常冗余而且不好维护,这个时候就可以利用路由分发来减轻总路由的压力
-
利用路由分发之后,总路由不再干预路由与视图函数的直接对应关系
- 而是做一个分发处理
- 识别当前的url是属于哪个应用下的,直接分发给对应的应用去处理
1.总路由
from django.contrib import admin
from django.urls import path, re_path, include
import app01
import app02
urlpatterns = [
path('admin/', admin.site.urls),
path('app01/', include(app01.urls)),
path('app02/', include(app02.urls)),
]
总路由尾部不能加$,否则会中断匹配,导致匹配失败
2.子路由
自己的逻辑路径
八.名称空间
- 当多个应用出现相同的别名,反向解析不会自动识别应用前缀
- 正常情况下的反向解析是不能识别前缀的
# 路由
urlpatterns = [
path('admin/', admin.site.urls),
path('app01/', include(app01.urls), namespace='app01'),
path('app02/', include(app02.urls), namespace='app02'),
]
# 视图解析
reverse('app01:reg')
reverse('app02:reg')
# 前端
{% url 'app01:reg' %}
{% url 'app02:reg' %}
只要保证名字不冲突就没必要使用名称空间
一般情况下,有多个app的时候只要在前面加上app前缀,这样就能确保多个app之间名字不冲突
九.伪静态
- 静态网页
- 数据是写死的
- 伪静态
- 将一个动态网页伪装成静态网页
- 伪装的目的在于增大本网站的seo查询力度
- 并且增加搜索引擎收藏本网页的概率
- 搜索引擎本质上就是一个巨大的爬虫程序
十.虚拟环境
- 在正常开发中,我们会给每一个项目独有的解释器环境
- 该环境内只有该项目用到的模块,用不到的一概不装
虚拟环境:
每创建一个虚拟环境就类似于重新下载了一个纯净的python解释器
但是虚拟器不建议下载太多,创建虚拟环境是需要消耗磁盘空间的
模块管理文件:
每个项目都需要用到很多模块,并且每个模块的版本可能是不一样的
这种情况下我们会给每一个项目配备一个requirements.txt文件,里面存放着我们这个项目所安装的所有模块及版本
只需要一条命令即可安装所有模块及版本
十一.Django1和Django2的区别
1.路由文件
django1.x中使用的是url:支持正则
django2.x中使用的是path(不支持正则:精准匹配)和re_path(url):支持正则
path:但是它只支持五种转换器
2.Django默认支持以下5个转化器
● str,匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式
● int,匹配正整数,包含0。
● slug,匹配字母、数字以及横杠、下划线组成的字符串。
● uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
● path,匹配任何非空字符串,包含了路径分隔符(/)