django第四天上课总结
day17
###1. 内容回顾
- 1.orm
- 参数
- null blank default ( (1,'男'),() )
- 1.必知必会13条
- 1.返回对象列表
- all()
- filter()
- exclude()
- values() {}
- values_list('id','name') ()
- order_by() -
- reverse()
- distinct()
- 2.返回对象
- get()
- first()
- last()
- 3.返回数字
- count()
- 4.返回布尔值
- exists()
- 2.单表的双下划线
- __gt lt gte lte
- __in = [] __range=[]
- __contains like __icontains 忽略大小写
- __startswith __endswith
- __istartswith __iendswith
- __isnull=True
- 3.外键
- 表示多对一的关系
- BooK:
- pub = models.ForeignKey(Publisher, on_delete=models.CASCADE,null=)
- book_obj.pub _> 所关联的对象
- book_obj.pub_id
- book_obj.pub.name
- 没有设置related_name
- pub_obj.book_set _> 关系管理对象
- pub_obj.book_set.all()
- 设置related_name='books'
- pub_obj.books.all()
- models.BooK.objects.filter(pub__name='xxx')
- models.Publisher.objects.filter(book__name='xxx')
- 4.多对多
- 表示多对多的关系
- book
- author
- author
- book_obj.author _> 关系管理对象
- book_obj.author.all()
- book_obj.author.set([]) [对象,对象] [id,id ]
- book_obj.author.add() 对象,对象 id,id
- book_obj.author.remove()
- book_obj.author.clear()
- book_obj.author.create() 创建一个作者
- 5.聚合和分组
```python
from django.db.models import Max,Min,Sum,Avg,Count
models.Book.objects.aggregate(max=Max('price')) {'max':100}
models.Author.objects.annotate(Max('books__price')).values() 对象列表
models.Book.objects.values('author').annotate(Max('price'))
```
- 6.F Q
- filter(sale__gt=F('store'))
- update(sale=F('sale')*2+13)
- Q(Q(id__gt=1) | Q(id__lt=5)) Q()
- & | ~
- 7.事务
- begin;
- commit;
```python
from django.db import transaction
import time
try:
with transaction.atomic():
# 一系列操作
models.Publisher.objects.create(name='xxxxxx')
except Exception as e:
print(e)
```
- 2.cookie session
- 1.cookie
- 保存在浏览器上的一组组键值对
- 设置
- response.set_cookie(key,value,max-age=5)
- 获取
- request.COOKIES [] .get
- 删除
- response.delete_cookie(key)
- 2.session
- 保存在服务器上的一组组键值对,依赖cookie
- request.session[k] = v
- request.session[k]
- request.session.delete()
- request.session.flush()
###2. 今日内容
- 1.中间件
- https://www.cnblogs.com/maple-shaw/articles/9333824.html
- 中间件就是一个类,处理django的请求和响应.五个方法
- 参数 执行的时间 执行的顺序 返回值
- process_request(self, request)
- 参数:
- request 跟视图函数中request同一个
- 执行时间:
- 视图函数执行之前,也在路由匹配之前
- 执行顺序:
- 按照注册顺序 顺序 执行
- 返回值:
- None: 正常流程
- HttpResponse:
- 当前中间件之后的中间件的process_request 路由匹配 视图函数 都不执行
- 直接执行当前中间件中的process_response方法,剩下正常流程将结果返回给浏览器
- process_response(self, request,response)
- 参数:
- request 跟视图函数中request同一个
- response response对象
- 执行时间:
- 视图函数执行之后
- 执行顺序:
- 按照注册顺序 倒序 执行
- 返回值:
- HttpResponse: 必须返回HttpResponse对象
- process_view(self, request, view_func, view_args, view_kwargs)
- 参数:
- request 跟视图函数中request同一个
- view_func 视图函数
- view_args 传递给视图函数的位置参数
- view_kwargs 传递给视图函数关键字置参数
- 执行时间:
- 视图函数执行之前,也在路由匹配之后
- 执行顺序:
- 按照注册顺序 顺序 执行
- 返回值:
- None: 正常流程
- HttpResponse:
- 当前中间件之后的中间件的process_view 视图函数 都不执行
- 直接执行最后一个中间件中的process_response方法,剩下正常流程将结果返回给浏览器
- process_exception(self, request, exception):
- 参数:
- request 跟视图函数中request同一个
- exception 错误对象
- 执行时间(触发条件):
- 视图出错后才执行
- 执行顺序:
- 按照注册顺序 倒序 执行
- 返回值:
- None: 正常流程 交给下一个中间件处理异常 都不处理交给django处理
- HttpResponse:
- 当前中间件之后的中间件的process_exception都不执行
- 直接执行最后一个中间件中的process_response方法,剩下正常流程将结果返回给浏览器
- process_template_response(self, request, response):
- 参数:
- request 跟视图函数中request同一个
- response template_response对象
- 执行时间(触发条件):
- 视图函数返回的是template_response对象
- 执行顺序:
- 按照注册顺序 倒序 执行
- 返回值:
- HttpResponse: 必须返回template_response对象
- 2.ajax
- https://www.cnblogs.com/maple-shaw/articles/9524153.html
- 发请求的方式:
- 1.浏览器地址上输入地址 GET
- 2.form表单 GET/POST
- 3.a标签 GET
- ajax js的技术,发送请求,传输的数据 json xml
- 局部刷新 异步
- 1.计算示例
- [] + [] = []
```javascript
$.ajax({
url: '/calc/',
type: 'post',
data: {
a1: $('input[name="ii1"]').val(),
a2: $('input[name="ii2"]').val(),
},
success: function (ret) {
$('input[name="ii3"]').val(ret)
}
})
```
- 2.ajax参数介绍
```javascript
$.ajax({
url: '/upload/', // 上传的地址
type: 'post', // 请求的类型
processData: false, // 告诉jQuery不要去处理发送的数据
contentType: false, // 告诉jQuery不要去设置Content-Type请求头
data: form_data, // 数据 {}
success: function (ret) {
console.log(ret)
},
error: function (ret) {
alert(ret)
}
})
```
- 3.提交post请求的设置
- 前提 有csrftroken的cookie
- 1.data中添加 csrfmiddlewaretoken 键值对
- 2.headers: {
'x-csrftoken': $('input[name="csrfmiddlewaretoken"]').val(),
}
- 3.引入文件
- 3.form组件
- https://www.cnblogs.com/maple-shaw/articles/9537309.html
- form组件的作用:
- 1.自动生成input框
- 2.可以对数据进行校验
- 3.有错误提示
- 1.注册示例
- 2.form组件的使用
```python
class RegForm(forms.Form):
username = forms.CharField(label='用户名',min_length=6)
password = forms.CharField(label='密码',widget=forms.PasswordInput)
```
- 视图:
```python
form_obj = RegForm()
form_obj = RegForm(request.POST)
form_obj.is_valid() # 对数据进行校验的
form_obj.cleaned_data # 只有通过校验的数据
return render(request, 'reg.html', {'form_obj': form_obj})
```
- 模板:
- {{ form_obj.as_p }} 演示使用
- {{ form_obj.username }} input框
- {{ form_obj.username.label }} label的值
- {{ form_obj.username.id_for_label }} input框的id
- {{ form_obj.username.errors }} 当前字段的所有的错误
- {{ form_obj.username.errors.0 }} 当前字段的第一个的错误
- {{ form_obj.non_field_errors }} __all__ 全局的错误
- 3.字段及参数的介绍
- CharField
- ChoiceField
- MultipleChoiceField
- required=True, 是否允许为空
- widget=None, HTML插件
- label=None, 用于生成Label标签或显示内容
- initial=None, 初始值
- help_text='', 帮助信息(在标签旁边显示)
- error_messages=None, 错误信息 {'required': '不能为空', 'invalid': '格式错误'}
- validators=[], 自定义验证规则
- disabled=False, 是否可以编辑
- 4.内置校验和自定义校验
- required
- max_length
- min_length
- 1.使用内置的校验器
```python
from django.core.validators import RegexValidator
phone = forms.CharField(
validators=[RegexValidator(r'^1[3-9]\d{9}$','手机号格式不正确')],
)
```
- 2.自定义函数
```python
from django.core.exceptions import ValidationError
def check_username(value):
if 'alex' in value:
raise ValidationError('用户名含有非法字符,请重新选择')
```
- 5.is_valid源码解析及局部、全局钩子
```python
def clean_username(self):
#局部钩子 对当前字段做校验
# 通过校验 返回当前的字段的值
# 不通过校验 抛出异常ValidationError
pass
def clean(self):
# 全部钩子 对任意字段做校验
# 通过校验 返回所有字段的值
# 不通过校验 抛出异常ValidationError __all__
password = self.cleaned_data.get('password')
re_password = self.cleaned_data.get('re_password')
if password == re_password:
return self.cleaned_data
self.add_error('re_password', '两次密码不一致!!!!')
raise ValidationError('两次密码不一致')
```