第十二周周总结
一、可视化界面之数据增删改查
当我们在orm中使用操作对数据库数据库进行增删改查的时候,需要在视图层传入对应的数据的对象,这样我们才可以在html文件中获取到数据库中的数据信息,然后我们使用form表单的input、select等标签获取需要修改的或是增加的或是删除的信息,然后传到后端使用ORM语句对数据库进行数据操作。
二、Django请求生命周期流程图
主要讲解了Django是怎么运行工作的,通过这个图我们可以知道Django中的关键组成部分,以此来确定接下去的或是复习时候的学习重点
这里需要提一下的是客户端和Django后端交互的中间层,WSGI协议、也就是web服务网管接口,Django自带的是wsgiref协议,但是因为他的并发量不高所以通常我们会换成uwsgi协议。
三、路由层
路由层就是urls.py这个文件,他的内部存储的是网址后缀跟html文件的匹配关系,我们需要注意的是在除Django1的版本中,都是用path来绑定路由关系,但是在Django1版本中是用url来绑定的,url使用的是正则。
而在其他版本中如果需要使用正则需要导入re_path模块。
同时在路由层中‘/’符号也是需要进行设置的,在配置文件中的APPEND_SLASH = False这里要是改成了false,默认情况下写网址就需要以/结尾,否则会自动添加/符号进行匹配,匹配到了就会跳转。
转换器
当我们在浏览网页的时候,尝尝会看到进入一些功能网页的时候同城网址中间都有一些用/符号隔开的字符或是数字,通过猜测,基本上就是代表账号的或是分类的信息。如果我们也想使用这样的形式来划分网址,用之前的方式匹配路由就很笨重,因此我们需要用转换器来让他自动匹配。
path('login/<int:year>/', view.login)
通常来说有五种转换器(Django1中不一样,别的版本都一样)
str、int、slug、uudi、path
使用转换器的时候匹配的内容需要符合转换器的数据类型要求,否则会报错。
正则匹配
使用正则匹配没什么号介绍的,知识点都在正则中
这里主要是一些用法介绍
比如使用分组优先,也就是加小括号进行匹配
这是小括号中匹配到的内容会传到视图层的函数中去需要用参数接收
同时使用正则的时候哈可以用?P<名称>的形式对分组优先匹配的内容进行绑定名称的操作,
因此引出两个名词,有名分组和无名分组
需要注意的是两个分组不能一起使用
四、反向解析
反向解析就是在路由层的后面写上一个name属性,给他设置一个名称,这样我们在其他位置调用网址后缀的时候就可以通过它的名称自动匹配到后缀
这个问题主要也是为了解决工作时出现需要修改后缀名称的情况准备的策略
需要注意的是当反向解析出现动态匹配的时候需要给他绑定名称
路由层:
path('func1/<str:others>/', views.func1_func, name='func1_view')
视图层:
reverse('func1_view', args=('嘿嘿嘿',))
html页:
{% url 'func1_view' 'jason' %}
五、路由分发
当我们在urls.py文件,也就是路由层中配置路由的时候,目前来说我们是配置在django文件的路由层中,但是当某个项目,开发过程中分成了很多应用的话,当对这些应用进行整合的时候就会出现路由添加的工作量很大的情况,这种情况下就需要用到路由分发。所谓的路由分发就是把每个应用的路由配置记录在应用的路由层中,然后再导入某个应用的时候直接在总路由中导入应用中的自路由层就可以使用应用中配置好的路由。
path('app01/',include('app01.urls'))
六、名称空间
当我们在使用路由分发的时候,会出现几个app路由名称重复的情况,这时候有两种处理方法。
第一种:
使用名称空间
也就是在总路由中导入自路由的路由文件后,在后面写上namespace对他进行命名,这样操作它就相当于python中的名称空间一样,会对名称进行分块,解决名称冲突的情况。
第二种:
修改命名格式
当我们在应用中添加路由的时候,修改命名格式,比如在路由名称前添加前缀,前缀可以是应用名称,以此来区分。
七、虚拟环境创建
当我们在开发不同的项目的时候,会出现需要用到不容的模块,或是几个不同的项目需要用到几个相同模块的不同版本。
这种情况下就需要使用虚拟环境来进行开发。
虚拟环境就相当于是一个解释器的分身,但是这个分身可以自行添加需要的模块,同时在刚创建出来的时候,他是一个纯净的解释器
在pycharm中创建的时候需要注意,下方两个选项中第一个不要选,第二个勾选,第一个是继承本来解释器中的模块,第二个是让这个虚拟环境可以被别的py项目使用
在cmd中创建虚拟环境需要用到下列命令(3.3版本之后才行,之前的版本需要借助第三方库)
python -m venv 虚拟环境的名称
创建好了之后还不能使用,需要去创建的目录下打开scripts文件夹,然后运行内部的activate程序才是启动了虚拟环境,这时候我们会发现命令窗口的左边会有个括号,括号内写着解释器的名称
这时候使用pip等命令都是用虚拟环境来执行的
当我们不想使用虚拟环境的时候需要用deactivate命令来关闭,这里需要提一下
启动虚拟环境的命令,根据操作系统的不同分成三个
八、视图层三板斧
这里的三板斧是之前说的那三个,只是进行了一些深入的研究
from django.shortcuts import render, redirect, HttpResponse, reverse
这里主要是提到了一个定论:用来处理网页请求的视图函数都必须返回HttpResponse对象
这里我们是通过源码进行研究论证的
render内直接看就可以看到他是用HttpResponse返回的
HttpResponse也是一样调用的
redirect则是需要去他内部调用的类中查看父类才能找到是一样的返回HttpResponse对象
九、JsonResponse对象
之前我们提到过不同语言之间进行数据交互的时候通常是吧数据转换成json格式
但是我们使用json模块进行操作就很繁琐
因此提供了JsonResponse对象来供我们操作
只需要把要返回给网页的数据放到这个类的括号中生成对象就可以返回给网页json格式的数据(ps:他的内部一样封装了json模块)
十、视图层中如何使用request对象获取文件
这里我们需要先讲一下,在html中返回值用的是form表单标签
但是这里标签的method必须设置成post属性,因为get请求只能携带两k的数据,同时还要设置enctype="multipart/form-data"
其次
我们在视图层中需要用request对象来拿数据,如果拿的是文件,使用request.FILES就可以获得文件的数据
十一、视图层之FBV\CBV
这里讲的就是视图层中的用来处理请求的形式
FBV是基于函数的视图
CBV是基于类的视图
本质来说两者其实都是FBV视图,因为在源码中观察会发现CBV返回值是view(路由层中的)
from django import views
urlpatterns = [
path('login/', views.MyLoginView.as_view())
]
通过查看源码最后我们发现CBV内部其实是通过面向对象的反射方法来处理的
十二、模版层
语法讲解
{{ }}主要用于数据值相关的地方
{% %}主要用于逻辑相关的地方,比如用for循环等情况
这里有个小知识点
虽然我们用ORM等操作可以在html文件中写python语法
但是我们需要注意orm语法中的注释是{##}的形式
这类形式的代码并不会在前端页面的检查中被看到,因为虽然我们可以在html文件中使用python语法,但本质上是人家去后端运行后返回结果给前端
在摸板层、也就是html文件中python的基本数据类型都可以正常展示的、文件对象可以可以、当我们使用函数名加括号或是类加括号都会返回结果、对象就会返回一串对象代码
模版语法之过滤器
所谓的过滤器就是内置函数
就是我们在html文件中写了后端代码后,可以给他用下方代码的形式使用过滤器
<p>{{ s|slice:'1:4' }}</p>
同时我们可以看到管道敷是用来指定过滤器的,冒号是传参的
用的比较多的过滤器有length返回长度、slice切片操作、add数值添加或字符拼接、date日期格式、filesizeformat转换文件大小格式、truncatechars与truncatewords分别是返回几个字母或单词,剩余部分省略、safe对后端的字符串内的html代码进行转义(默认情况下不会进行转义,即不会把内部的代码执行成html代码)
十三、模板层之标签
这里主要介绍的是模版层中的if和for循环、with
if和for循环还有这个with在pycharm中编写可以用tab自动补齐
with是用于对某些值的命名,但是因为他有格式要求用的不多。
if
{% if 条件1(可以自己写也可以用传递过来的数据) %}
<p>今天又是周三了</p>
{% elif 条件2(可以自己写也可以用传递过来的数据) %}
<p>百日冲刺</p>
{% else %}
<p>没多少时间了!</p>
{% endif %}
for
{% for k in t1 %}
{% if forloop.first %}
<p>这是我的第一次循环{{ k }}</p>
{% elif forloop.last %}
<p>这是我的最后一次循环{{ k }}</p>
{% else %}
<p>这是中间循环{{ k }}</p>
{% endif %}
{% empty %}
<p>你给我传的数据是空的无法循环取值(空字符串、空列表、空字典)</p>
{% endfor %}
for循环这里的forloop内部存了很多的信息比如counter0是数据值的索引counter是计数等
同时我们还可以使用forloop点一些方法,比如first、last等判断当前遍历的值的位置
ps:模版层的语法中只支持点的形式进行操作
但是他可以点很多东西比如索引、属性
十四、自定义过滤器、标签、inclusion_tag
这些知识点了解即可
前面两个功能类似
只是标签没有参数个数显示、过滤器函数只能有两个参数
这个特点也是通过查看源码得知的,反正就是依葫芦画瓢
然后我们自定义这些语法的时候需要进行一些准备
1.在应用下创建一个名字必须叫templatetags的目录
2.在上述目录下创建任意名称的py文件
3.在上述py文件内先编写两行固定的代码
from django import template
register = template.Library()
这个创建的py文件就是模本语法的编写文件
我们使用的时候在别的地方导入这个文件就可以使用对应的语法了
这是自定义过滤器函数使用的装饰器
@register.filter(name='myadd')
这是自定义标签函数使用的装饰器
@register.simple_tag(name='mytag')
inclusion_tag
这个模板语法是在一个py文件中定义一定的功能
装饰器如下
@register.inclusion_tag('menu.html',name='mymenu')
然后再在一个html文件中写上对应的模板语法接收结果进行展示
这样就可以在别的py文件中调用他进行使用了。
十五、母版的继承与使用
说白了母版跟子板就是继承关系、但是子板可以在母版规定的区域进行一些自定义
{% extends 'home.html' %}
这是子板继承母版的代码
{% block 区域名称 %}
子板自己的内容
{% endblock %}
这是子板自定义母版中可修改内容的代码
也可以使用block.super继承母版中的内容进行展示
通常来说会根据html代码、js代码、css样式设置三个自定义区域
除了母版
我们还可以直接导入模版,也就是调用模版文件中的html代码,模版文件不能是完整的html文件
{% include 'myform.html' %}
十六、模型层
模型层也就是跟数据库进行交互的models.py文件
因为使用orm对数据库进行操作的时候需要进行一些测试
所以我们需要配置测试环境
有两种方法
第一种
pycharm中下方有一个python console可以进行操作
第二种
我们自己配置一个环境
这里需要开一个py文件
可以使用app内的test.py文件
先去项目的manage.py文件中拷贝前四行代码
然后导入djangomok
再写上django.setup()
接下去就可以在函数内写orm语句
同时外面需要调用函数
同茶馆来说前面的orm语句是不变的
models.表名称.objects.
后面的部分就是一些关键字了
比如
create创建
filter筛选
first获取第一个(查询的结果通常会返回到一个对象中,内部的结果用列表框起来,我们还需要用方法或是索引取值)
last获取最后一个
update修改
all获取所有的数据
delete删除
values根据字段值进行查找
values_list跟上面一样,但是查找的结果放到列表中
distinct去重(有主键的情况是不能成功去重的)
get根据条件进行插找,但是找不到会报错通常用values
十七、orm执行原生sql语句
虽然ORM是个好东西,但是有时候因为效率较低,我们会想使用原生的sql语句
这时候有两种使用方式
一种是在objects后点raw方法
然后内部括号中写sql语句
一种是完全避开模型层
即不用models等方式点方法或是点对象
from django.db import connection
cursor = connection.cursor()
cursor.execute('select name from app01_user;')
print(cursor.fetchall())
十八、双下划线查询
当我们在使用ORM的时候
目前阶段我们会发现大于小于等操作我们不能执行
因此我们要介绍双下划线操作
方法 | 描述 |
---|---|
__gt | 大于 |
__lt | 小于 |
__gte | 大于等于 |
__lte | 小于等于 |
__in | 或 |
__range | 取指定范围内对应数据,并且首尾都要 |
__contains | 模糊查询,查询出指定字符数据,区分大小写 |
__icontains | 忽略大小写 |
__startswith | 查询以指定字符开头数据 |
__endswith | 查询以指定字符结尾数据 |
我们在字段的后面跟上双下滑线方法就可以执行对应的查找条件
查询年龄大于18的用户数据
res = models.User.objects.filter(age__gt=18)
十九、ORM中创建外键
在orm中创建外键也是在模型层中编写代码进行映射
首先我们需要回顾之前学的那些外键相关知识点
然后根据关系确定创建外键的表
然后再创建外键
需要特殊对待的是多对多关系
他也是创在某个表中,但是这里并不会显示这个字段
而是会在进行数据库迁移的时候变成一个表
一对多外键字段
publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE)
多对多外键字段
authors = models.ManyToManyField(to='Author')
一对一外键字段
author_detail = models.OneToOneField(to='AuthorDetail', on_delete=models.CASCADE)
因为添加了外键我们在添加数据值的时候需要注意添加顺序,有些表需要用到外键中的值
二十、外键操作
这里主要介绍了四个方法
add添加
remove移除
set更新
clear清空
二十一、orm跨表查询
通过回顾我们知道跨表查询有子查询和连表查询
在orm中就相对来说简单了很多
我们使用赛选的到的对象继续用点的形式执行方法进行查询即可
这里根据外键的存在介绍两个概念:
正向查询
当我们查询的前置条件所在的表中存在与另一个表关联的外键,这时候就叫正向查询
反向查询
反之就叫反向查询
针对两个条件下的查询方式不同
我们总结了一句口诀
正向查询按外键字段
反向查询按表名小写
二十二、基于双下划线的跨表查询
当我们使用查询条件进行查询的时候通常会根据条件使用方法进行筛选
双下划线的存在就帮助我们节省了步骤,比如我们要通过外键去别的表中那记录
本来我们应该用获取的外键值,去别的表中进行查找
但是在双下划线的作用下我们可以直接获取到结果
# 1.查询主键为1的书籍对应的出版社名称
res = models.Book.objects.filter(pk=1).values('publish__name','title')
print(res)
这里还介绍了一个进阶操作
就是我们不用条件所在的表进行查询,我们用结果所在的表进行查询(其实本事来看就是子查询)
二十三、聚合查找
聚合查找需要使用aggregate方法。
这时候我们就可以用上很多的聚合方法(函数)
聚合函数:Max最大、Min最小、Sum总和、Avg平均、count统计
同时我们也可以给函数运行的结果命名
如果我们不命名就会拿字段名进行命名
但是这里不建议用中文进行命名
二十四、分组查找
.annotate
使用分组查询要用annotate方法
分组查找需要修改MySQL中配置文件的严格模式的一些配置否则运行不成功
二十五、orm中如何再次添加新字段
当我们在models.py文件中添加新的字段是需要设置字段的值
否则不让我们进行数据库迁移操作
我们可以设置字段的值为一个默认值
或是设置null = True
让他可以等于空
十六、F与Q查询当查询条件或是操作条件不明确的时候需要用f查询用f的括号把字段名称框起来q查询主要是设计到了一些逻辑运算符比如默认情况下查询条件如果有多个,基本上是and的关系我们用了q模块后