第58天:django学习(七)
orm增删改查
????????在model.py中建表,然后迁移数据库
from django.db import models
?
# Create your models here.
?
class Book(models.Model):
? ?title = models.CharField(max_length=32)
? ?price = models.DecimalField(max_digits=8, decimal_places=2)
? ?publish_date = models.DateField(auto_now_add=True)
?
? ?# 一对多
? ?publish = models.ForeignKey(to='Publish', on_delete=models.DO_NOTHING)
? ?# 多对多
? ?authors = models.ManyToManyField(to='Author')
?
class Publish(models.Model):
? ?name = models.CharField(max_length=32)
? ?addr = models.CharField(max_length=64)
?
?
? ?def __str__(self):
? ? ? ?return self.name
?
?
class Author(models.Model):
? ?name = models.CharField(max_length=32)
? ?age = models.IntegerField()
? ?# 一对一
? ?author_detail = models.OneToOneField(to='AuthorDetail',on_delete=models.DO_NOTHING)
?
?
class AuthorDetail(models.Model):
? ?phone = models.BigIntegerField()
? ?addr = models.CharField(max_length=64)
????????在测试文件test.py中启动django和导入应用下的model.py
import os
?
# Create your tests here.
?
if __name__ == '__main__':
? ?os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'day58_dj.settings')
? ?import django
? ?django.setup()
? ?from app01 import models
一对多外键的增删改查
????????增加数据
models.Book.objects.create(title='论语', price=45, publish_id=1)
????????删除数据
models.Book.objects.filter(pk=1).delete()
????????修改数据
models.Book.objects.filter(pk=1).update(price=35)
????????查询数据
res = models.Book.objects.all()
print(res)
多对多外键的增删改查
????????增加数据
book_obj = models.Book.objects.filter(pk=1).first()
book_obj.authors.add(1)
????????同时也支持对象的添加方式
author_obj1 = models. Author. objects. filter(pk=1). first()
author_obj2 = models. Author. objects. filter(pk=2). first()
author_obj3 = models. Author. objects. filter(pk=3). first()
book_obj.authors.add(author_obj1, author_obj2, author_obj3)
????????删除数据
book_obj.authors.remove([2, 3])
????????同时也支持对象的删除方式
book_obj.authors.remove([author_obj1, author_obj2, author_obj3])
????????修改数据
book_obj.authors.set([2, 3])
????????同时也支持对象的修改方式
book_obj.authors.set([author_obj1, author_obj2, author_obj3])
????????清空数据
book_obj.authors.clear()
多表查询
子查询(基于对象的跨表查询)
正反向的概念
????????正向查询
????????带有外键字段的表去查不带外键字段的表,通过外键字段查询
????????反向查询
????????不带有外键字段的表去查带外键字段的表,通过表名小写或表名小写_set查询
????????查询书籍主键为1的出版社
????????这是正向查询,按外键字段查询
res=models.Book.objects.filter(pk=1).first()
print(res.publish)
-
输出结果就是出版社对象
????????查询书籍主键为2的作者
????????这是正向查询,按外键字段查询
res=models.Book.objects.filter(pk=2).first()
print(res.authors.all())
????????查出来的是结果要用for循环进行打印
for i in res.authors.all():
? ?print(i.name)
????????查询作者kevin的电话号码
????????这是正向查询,按外键字段查询
res=models.Author.objects.filter(name='kevin').first()
print(res.author_detail.phone)
????????查询出版社是北京出版社出版的书
????????这是反向查询,按表名小写查询
res=models.Publish.objects.filter(name='北京出版社').first()
print(res.book_set.all())
????????查询作者是kevin的书
????????这是反向查询,按表名小写查询
res=models.Author.objects.filter(name='kevin').first()
print(res.book_set.all())
????????查询手机号是110的作者姓名
????????这是反向查询,按表名小写查询
res=models.AuthorDetail.objects.filter(phone=110).first()
print (res.author.name)
-
当查询结果可以有多个的时候,就必须加set.all()
-
当你的结果只有一个的时候,不需要加set.all()
联表查询(基于双下划线的跨表查询)
????????查询jason的手机号和作者姓名
????????正向查询,按外键字段查询
res = models.Author.objects.filter(name='jason').values('author_detail__phone','name')
print(res)
????????反向查询,按表名小写查询
res=models.AuthorDetail.objects.filter(
? ?author__name='jason'
).values('phone','author__name')
print(res)
????????查询书籍主键为1的出版社名称和书的名称
????????正向查询,按外键字段查询
res = models.Book.objects.filter(pk=1).values('title','publish__name')
print(res)
????????反向查询,按表名小写查询
res = models.Publish.objects.filter(book__id=1).values('name','book__title')
print(res)
????????查询书籍主键为1的作者姓名
????????正向查询,按外键字段查询
res = models.Book.objects.filter(pk=1).values('authors__name')
print(res)
????????反向查询,按表名小写查询
res = models.Author.objects.filter(book__id=1).values('name')
print(res)
????????查询书籍主键是1的作者的手机号
????????这是正向查询,按外键字段查询,且跨了多张表进行查询,总共使用了三种表
res = models.Book.objects.filter(pk=1).values('authors__author_detail__phone')
print(res)
分组
聚合查询
????????作用
????????聚合查询通常情况下都是配合分组一起使用的
????????导入
from app01 import models
from django.db.models import Max,Min,Sum,Count,Avg
????????所有书的平均价格
res = models.Book.objects.aggregate(Avg('price'))
print(res)
????????导入的方法一次性使用
res=models.Book.objects.aggregate(
? ?Max('price'),Min('price'),Sum('price'),Count('pk'),Avg('price')
)
print(res)
分组查询
????????统计每一本书的作者个数
res=models.Book.objects.annotate(
? ?author_num=Count('authors')
).values('title','author_num')
print(res)
????????统计每个出版社卖的最便宜的书的价格
res=models.Publish.objects.annotate(
? ?min_price=Min('book__price')
).values('name','min_price')
print(res)
????????统计不止一个作者的图书
-
先按照图书分组 求每一本书对应的作者个数
-
过滤出不止一个作者的图书
res=models.Book.objects.annotate(
? ?author_num=Count('authors')
).filter(author_num__gt=1).values('title','author_num')
print(res)
????????查询每个作者出的书的总价格
res=models.Author.objects.annotate(
? ?sum_price=Sum('book__price')
).values('name','sum_price')
print(res)
F与Q查询
前期准备
????????在model.py中Book表中添加字段,再次迁移数据库
maichu=models.IntegerField(default=1000)
kucun=models.IntegerField(default=2000)
F查询
????????作用
????????能够直接获取到表中某个字段对应的数据
????????导入
from django.db.models import F
from django.db.models.functions import Concat
from django.db.models import Value
????????查询卖出数大于库存数的书籍
res = models.Book.objects.filter(maichu__gt=F('kucun'))
print(res)
????????将所有书籍的价格提升500块
models.Book.objects.update(price=F('price') + 500)
????????将所有书的名称后面加上爆款两个字
models.Book.objects.update(title=Concat(F('title'), Value('爆款')))
-
在操作字符类型的数据的时候 F不能够直接做到字符串的拼接
Q查询
????????导入
from django.db.models import Q
????????例:查询卖出数大于100或者价格小于600的书籍
res = models.Book.objects.filter(maichu__gt=100,price__lt=600)
-
之前的查询方法,filter括号内多个参数是and关系
res = models.Book.objects.filter(Q(maichu__gt=100),Q(price__lt=600))
-
Q包裹逗号分割 还是and关系
res = models.Book.objects.filter(Q(maichu__gt=100)|Q(price__lt=600))
-
这是or关系
res = models.Book.objects.filter(~Q(maichu__gt=100)|Q(price__lt=600))
-
这是not关系
Q的高阶用法
????????能够将查询条件的左边也变成字符串的形式
q = Q()
q.connector = 'or'
q.children.append(('maichu__gt',100))
q.children.append(('price__lt',600))
res = models.Book.objects.filter(q)
print(res)
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!