聚合查询
# 聚合查询
max min avg sum count
from django.db.models import Max, Min, Sum, Count, Avg
# 可以起别名
# res = models.Book.objects.aggregate(max_price=Max('price'))
# print(res)
# 2. 查询所有书籍的总价格
# sql: select sum(price) as sum_price from book
# sql: select sum(price) sum_price, min(price) min_price from book
# res = models.Book.objects.aggregate(sum_price=Sum('price'))
# print(res)
# 3. 查询所有书籍的平均价格
# sql: select avg(price) as avg_price from book
# res = models.Book.objects.aggregate(avg_price=Avg('price'))
# print(res)
# 4. 一起使用
res = models.Book.objects.aggregate(max_price=Max('price'), min_price=Min('price'), avg_price=Avg('price'), count=Count('pk'), sum_price=Sum('price'))
print(res)
分组查询
# group by
select * from t group by price, title,
# sql_mode='only_full_group_by'
'''分组之后只能拿到分组的依据'''
1. group_concat: 分组之后用
2. concat: 分组之前使用
3. concat_ws:
'''
select concat(title,":",age,":", gender,":") from t
'''
select concat_ws(':', title, age, gender) from t;
ORM中使用分组:annotate
'''分组查询:annotate'''
# 1.
# 统计每一本书的作者个数
# res = models.Book.objects.annotate() # 代表按照书籍分组
# res = models.Book.objects.annotate(author_num=Count('authors__pk')).values('title', 'author_num')
# print(res)
# 2.
# 统计出每个出版社卖的最便宜的书的价格
# res = models.Publish.objects.annotate(min_price=Min('book__price')).values('name', 'min_price')
# print(res)
# 3.
# 统计不止一个作者的图书
# 1. 先查询每个图书的作者个数
# 2. 在筛选掉小于等于1
# res = models.Book.objects.annotate(Count('authors__pk'))
# res = models.Book.objects.annotate(author_num=Count('authors')).filter(author_num__gt=1).values('title', 'author_num')
# print(res)
# 4.
# 查询各个作者出的书的总价格
res = models.Author.objects.annotate(sum_price=Sum('book__price')).values('name', 'sum_price')
print(res)
事务
# 保证数据安全
'''
四大特性:ACID
事务的隔离级别
'''
1. 开启事务:
start transaction;
2. 提交事务
commit;
3. 回滚事务
rollback;
'''django开启事务'''
from django.db import transaction
try:
'''执行的SQL语句'''
with transaction.Atomic:
# sql1
# sql2
pass
# 写在这个里面的都是属于同一个事务
except Exception as e:
print(e)
transaction.rollback()
ORM中常用的参数
on_delete
当删除关联表中的数据时,当前表与其关联的行的行为。
models.CASCADE
删除关联数据,与之关联也删除
models.DO_NOTHING
删除关联数据,引发错误IntegrityError
models.PROTECT
删除关联数据,引发错误ProtectedError
models.SET_NULL
删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空)
models.SET_DEFAULT
删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值)
models.SET
删除关联数据,
a. 与之关联的值设置为指定值,设置:models.SET(值)
b. 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象)
choices参数
eg:
性别
学历
来源
# 针对与这种可以列举完的可能性,我们就可以使用choices参数
gender_choices = (
(1, '男'),
(2, '女'),
(3, '其他'),
)
'''
对于choices参数,数据类型该怎么选?
判断依据是:小元组里面第一个参数的数据类型
'''
gender = models.IntegerField(choices=gender_choices)
####字符串类型的##################################
score_choices = (
('A', '优秀'),
('B', '良好'),
('C', '及格'),
('D', '不及格'),
)
score = models.CharField(max_length=8)
##############读取##############################
res = models.User.objects.filter(pk=4).first()
print(res)
print(res.gender)
'''
固定语法结构取值:get_字段名_display()
如果查询出来的数据不再choices范围内,会显示原始数据。
'''
print(res.get_gender_display())
多对多的创建方式
一共三种创建方式
1. 自动创建表关系
2.
'''自行创建第三张表'''
#
# class Book(models.Model):
# title = models.CharField(max_length=32)
# price = models.DecimalField(max_digits=8, decimal_places=2)
#
#
# class Publish(models.Model):
# title = models.CharField(max_length=32)
#
#
# class Author(models.Model):
# name = models.CharField(max_length=32)
#
# class Book2Author(models.Model):
# book = models.ForeignKey(to='Book')
# author = models.ForeignKey(to='Author')
# create_time = models.DateTimeField()
'''
扩展性高了
'''
''''
自行创建第三张表不能使用一下四个方法
add set remove clear
不支持正反向查询
'''
####第三种方式
class Book(models.Model):
title = models.CharField(max_length=32)
price = models.DecimalField(max_digits=8, decimal_places=2)
class Author(models.Model):
name = models.CharField(max_length=32)
book = models.ManyToManyField(to='Author', through='Book2Author',
through_fields=('author', 'book')
)
class Book2Author(models.Model):
book = models.ForeignKey(to='Book')
author = models.ForeignKey(to='Author')
create_time = models.DateTimeField()
Ajax技术
'''
ajax的精髓:
1. 异步提交
2. 局部刷新
'''
1. 我们不学习原生的ajax(js)
2. 我们目前学习jq封装之后的
3. 如果想使用ajax,必须引入jquery
小案例:
我们在页面上,来一个简单计算
'''
注意事项:
后端使用HttpResponse,前端使用下面的方式
1. // 反序列化
res = JSON.parse(res) // {}
console.log(res.username);
后端使用JsonResponse,前端使用下面的方式
2. // 反序列化
// res = JSON.parse(res) // {}
console.log(res.username);
3. 指定请求方式
// 指定后端返回的数据格式
dataType:'json',
'''