必备概念

# 多表查询
***子查询和连表操作

	子查询:基于对象的跨表查询
    连表操作:基于双下划线的跨表查询

***正向查询和反向查询:
    
    当前查询对象是否包含有外键字段
    	如果有就是正向
        没有则就是反向
    口诀:
    	正向查询按外键字段
        	多对多需要额为再加一个.all()
            一对多和一对一不需要加
        反向查询按表名小写
        	一对多与多对多再加一个_set.all()
            一对一不需要
   

多表查询

###基于对象的跨表查询###
	*子查询:将一张表的查询结果当做另外一条SQL语句的条件
    # 1.查询书籍主键为4的出版社名称
    	#先查询书籍对象
    	book_obj = models.Book.objects.filter(pk=4).first()
        #外键字段在书表中,所以是正向查询
        res = book_obj.publish
        print(res.title)
    # 2.查询书籍主键为3的作者姓名
    	#先查询书籍对象
        book_obj = models.Book.objects.filter(pk=3).first()
        #外键字段在书中,所以是正向查询
        res = book_obj.authors.all()
    # 3.查询作者jason的地址
    	#先查询作者jason数据对象
        author_obj = models.Author.objects.filter(name='jason').first()
        #外键字段在作者表中,所以是正向查询
        res = author_obj.author_detail
    # 4.查询东方出版社出版的书籍
    	#先查询出版社对象
        publish_obj = models.Publish.objects.filter(title='东方出版社').first()
        #外键字段在书籍表中,所以是反向查询
        res = publish_obj.book_set.all()
    # 5.查询jason写过的书籍
    	#先查询作者jason数据对象
        author_obj = models.Author.ojects.filter(name='jason').first()
        #外键字段在书籍表中,反向
        res = author_obj.book_set.all()
    # 6.查询电话是120的作者
    	#先查询电话120数据对象
        author_detail_obj = models.AuthorDetail.objects.filter(phone=120).first()
        #外键字段在作者表中,反向
        res = author_detail_obj.author
###基于双下划线的跨表查询###
	# 1.查询书籍主键为4的出版社名称
    	res = models.Book.objects.filter(pk=4).values('publish__title')
    # 2.查询书籍主键为3的作者姓名
    	res = models.Book.objects.filter(pk=3).values('authors__name')
    # 3.查询作者jason的地址
    	res = models.Author.objects.filter(name='jason').values('author_detail__addr')
    # 4.查询北方出版社出版的书籍名称
    	res = models.Publish.objects.filter(title='北方出版社').values('book__title')
    # 5.查询jason写过的书籍
    	res = models.Author.objects.filter(name='jason').values('book_title')
    # 6.查询电话是120的作者
    	res = models.AuthorDetail.objects.filter(phone=120).values('author__name')
######进阶操作######
	# 1.查询书籍主键为4的出版社名称
    	res = models.Book.objects.filter(pk=4).values('publish_title')
    # 反向查询高阶部分
    	res = models.publish.object.filter(book__pk=4)
    # 2.查询书籍主键为3的作者姓名
    	res = models.Book.objects.filter(pk=3).values('authors__name')
    # 反向查询高阶部分
    	res = models.Author.objects.filter(book_pk=3)
    # 3.查询作者jason的地址
    	res = models.Author.objects.filter(name='jason').values('author_detail__addr')
    # 反向查询高阶部分
    	res = models.AuthorDetail.objects.filter(author__name='jason')
    # 查询书籍主键为3的作者的电话号码
    	#正向
    	res = models.Book.objects.filter(pk=3).values('authors__author_detail__phone')
        #反向
        res = models.AuthorDetail.objects.filter(author__book__pk=3).values('phone')
        res = models.Author.objects.filter(book__pk=3).values('author_detail__phone')

聚合查询

#聚合查询    aggregate
'''
	聚合查询通常情况下配合分组一起使用
	只要跟数据库相关的模块基本都在django.db.models中,没有则在django.db中
'''
from app01 import models
from django.db.models import Max,Min,Sum,Count,Avg

#所有书的平均价格
res = models.Book.objects.aggregate(Avg('price'))

分组查询

# 分组查询     annotate
# 1.统计每一本书的作者个数
	res = models.Book.objects.annotate(author_num=Count('authors__pk')).values('title','author_num')
	print(res)
	res1 = models.Book.objects.annotate(author_num=Count('authors')).values('title', 'author_num')
	print(res1)
# 2.统计出每个出版社卖的最便宜的书的价格
	res = models.Publish.objects.annotate(not_expensive=Min('book__price')).values('title','not_expensive')
	print(res)
# 3.统计不止一个作者的图书
	res = models.Book.objects.annotate(author_num=Count('authors__pk')).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)
'''如果你按照表里面某个指定的字段分组'''
	res = models.Book.objects.values('publish_time').annotate()
	res1 = models.Book.objects.annotate()

F查询

from django.db.models import F

#查询库存数大于卖出数的书籍
	res = models.Book.objects.filter(kucun__gt=F('maichu'))
#将所有书籍价格上涨100
	res = models.Book.objects.update(price=F('price')+100)
# 3.将所有的书籍名称加上"爆款"后缀
    '''针对字符串不能直接拼接 需要额外导入模块操作'''
    from django.db.models.functions import Concat
    from django.db.models import Value
    
    ret3 = models.Book.objects.update(title=Concat(F('title'), Value('爆款')))

Q查询

from django.db.models import Q

# 1.查询书名是三国演义爆款或者库存是100的书籍
    '''filter()括号内可以写多个参数 逗号隔开  默认只支持and连接'''
	res1 = models.Book.objects.filter(Q(title='三国演义爆款'),Q(kucun=100))  # and
	res1 = models.Book.objects.filter(Q(title='三国演义爆款')|Q(kucun=100))  # or
	res1 = models.Book.objects.filter(~Q(title='三国演义爆款')|Q(kucun=100))  # not
    
 '''Q进阶用法'''
	# condition = input('请输入你需要按照什么字段查询数据>>>:')
    # data = input('请输入你需要查询的数据名称>>>:')
    # q = Q()  # 生成一个Q对象
    # q.children.append((condition,data))
    # res = models.Book.objects.filter(q)
    
    q.connector = 'or'  # 可以修改连接条件

事物

"""
1.事务四大特性 	ACID
	原子性
	一致性
	独立性
	持久性
2.数据库设计三大范式

	第一范式(1NF):
	数据表中的每一列(字段),必须是不可拆分的最小单元,也就是确保每一列的原子性。满足第一范式是关系模式规范化的最低要求,否则,将		有很多基本操作在这样的关系模式中实现不了。
	
	第二范式(2NF):
	满足1NF后要求表中的所有列,每一行的数据只能与其中一列相关,即一行数据只做一件事。只要数据列中出现数据重复,就要把表拆分开来。
	
	第三范式(3NF):
	满足2NF后,要求:表中的每一列都要与主键直接相关,而不是间接相关(表中的每一列只能依赖于主键)。

*
start transcation 开启一个事物
commit   事物的确认
rollback  回滚
*

from django.db import transaction
    try:
        with transaction.atomic():
            # 创建一条订单数据
            models.Order.objects.create(num="110110111", product_id=1, count=1)
            # 能执行成功
            models.Product.objects.filter(id=1).update(kucun=F("kucun") - 1, maichu=F("maichu") + 1)
    except Exception as e:
        print(e)

执行原生SQL语句

res = models.Book.objects.raw('select * from app01_book')
posted on 2021-05-26 10:45  lzl_121  阅读(45)  评论(0编辑  收藏  举报