[toc]
Django 进阶操作
批量插入数据 bulk_create
class Books(View):
def get(self,request):
#方式一:速度极慢,不推荐
# for i in range(1000):
# models.Book.objects.create(title=f'book{i}')
#方式二:速度快,推荐
book_lis=[]
for i in range(10000):
book_lis.append(models.Book(title=f'book{i}'))
models.Book.objects.bulk_create(book_lis)
book_queryset=models.Book.objects.all()
return render(request,'Books.html',locals())
聚合查询
from django.db.models import Max,Min,Sum,Count,Avg
res = models.Book.objects.aggregate(Sum('price'))
print(res) #{'price__sum': Decimal('263.80')}
'''
aggregate()是QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典。键的名称是聚合值的标识符,值是计算出来的聚合值。键的名称是按照字段和聚合函数的名称自动生成出来的。
'''
聚合函数
Max,Min,Sum,Count,Avg
#其余的百度
分组查询
为调用的QuerySet中每一个对象都生成一个独立的统计值
#统计数据库中每一本书的作者个数
res=models.Book.objects.all().annotate(author_num=Count('author'))
for o in res:
print(o.author_num)#author_num作为属性存放在对象中
#找出每个出版社最便宜的书的价格
res=models.Publisher.objects.all().annotate(min_price=Min('book__price'))
#支持__操作
for p in res:
print(p.min_price)
F与Q查询
F查询
Django 提供 F() 来两个字段值之间的比较。F() 的实例可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值。
#查询卖出数量大于库存数量的书籍
models.Book.objects.filter(kucun__gt=F('maichu'))
Q查询
filter()等方法中逗号隔开的条件是与的关系。 如果你需要执行更复杂的查询(例如OR语句),你可以使用Q对象。
modesls.Book.objects.filter(Q(title='python'),Q(price=666))#与
modesls.Book.objects.filter(Q(title='python')|Q(price=666))#或
modesls.Book.objects.filter(~Q(title='python')|Q(price=666))#非 或
进阶Q查询
q = Q() #Q实例化出一个对象
# q.connector = 'or' 设置逻辑关系
q.children.append(('title','python')) #以元组方式提供键与值
q.children.append(('title__icontains','python')) #可提供多个,且支持双下划线
q.children.append(('price',666))
models.Book.objects.filter(q) #可以在fliter中直接放入实例化的对象,默认还是and关系
Django orm常见字段及参数
常见字段及参数
AutoField()
int自增列,必须填入参数 primary_key=True。当model中如果没有自增列,则自动会创建一个列名为id的列
DateField()
日期字段,日期格式 YYYY-MM-DD,相当于Python中的datetime.date()实例。
DateTimeField()
日期时间字段,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],相当于Python中的datetime.datetime()实例。
auto_now
auto_now_add
TextField()
EmailField() varchar(...)
BooleanField() 传布尔值 存0/1
choice参数
用户性别
用户学历
用户工作状态
客户来源
...
choices = (
(1,'male'),
(2,'female'),
(3,'others')
)
gender = models.IntegerField(choices=choices)
"""
1.如果我存的是上面元组中数字会怎么样
2.如果我存的数字不在元组范围内又会怎样
1.数字没有对应关系 是可以存的
"""
from app01 import models
user_obj = models.Userinfo.objects.filter(pk=4).first()
print(user_obj.username)
print(user_obj.gender)
# 针对choices字段 如果你想要获取数字所对应的中文 你不能直接点字段
# 固定句式 数据对象.get_字段名_display() 当没有对应关系的时候 该句式获取到的还是数字
print(user_obj.get_gender_display())
record_choices = (('checked', "已签到"),
('vacate', "请假"),
('late', "迟到"),
('noshow', "缺勤"),
('leave_early', "早退"),
)
record = models.CharField("上课纪录", choices=record_choices, default="checked",
score_choices = ((100, 'A+'),
(90, 'A'),
(85, 'B+'),
(80, 'B'),
(70, 'B-'),
(60, 'C+'),
(50, 'C'),
(40, 'C-'),
(0, ' D'),
(-1, 'N/A'),
(-100, 'COPY'),
(-1000, 'FAIL'),
)
score = models.IntegerField("本节成绩", choices=score_choices, default=-1)
自定义字段
百度
查询优化
only与defer
# only(self, *fields)
# 仅取某个表中的数据
models.UserInfo.objects.only('username','id')
或
models.UserInfo.objects.filter(...).only('username','id')
# defer(self, *fields)
models.UserInfo.objects.defer('username','id')
或
models.UserInfo.objects.filter(...).defer('username','id')
# 映射中排除某列数据
Django orm事务操作
from django.db import transaction
try:
with transaction.atomic():
# 事务操作
except BaseException as e:
print(e)