Q查询 orm字段补充 查询优化事务操作 图书管理系统

Q查询 orm字段补充 查询优化事务操作 图书管理系统

 

  • 外键字段数据的增删改查

    一对多与一对一
    	publish=对象
        publish_id=数字
    多对多
    	add()  
        set()
        remove()
        clear()
    
  • 正反向查询的概念

    所谓的正反向完全取决于外键字段在谁那儿
    """
    正向查询按外键字段
    反向查询按表名小写
    """
    
  • 基于对象的跨表查询(子查询)

    1.先获取一个数据对象
    2.其次使用该对象点外键字段或者表名小写(_set.all())
    # 1.查询主键为2的书籍对应的出版社
        # 分两步看 先查询书籍对象
        # book_obj=models.Book.objects.filter(pk=2).first()
        #书籍对象查出版社对象  (当前在book表 外键字段在这 正向 .外键字段)
        # res=book_obj.publish
        # print(res,res.pk,res.name,res.addr)
    
    # 5.查询泰罗写过的书籍
        # 先查询作者对象
        # author_obj=models.Author.objects.filter(name='泰罗').first()
        #作者对象查询书籍对象  (当前在author对象里,外键字段在书籍对象里 ,所以反向 .表名小写)
        # res=author_obj.book_set.all()  #加了_set 和all
        # # print(res)
        # for i in res:
        #     print(i.title)
    
    
  • 基于双下划綫的跨表查询(连表操作)

    """SQL语句:inner join  left join  right join  union"""
    一句orm完成查询操作
    # 1.查询主键为2的书籍对应的出版社
        #也符合 正向反向查询    目前在book表 外键字段在这 正向 .外键字段
        # values('publish'): 目前已经到了出版社这个表 拿什么字段直接__字段名
        #返回的是一个列表套字典
        # res=models.Book.objects.filter(pk=2).values('publish__name','publish__addr')
        # print(res)
     # 5.查询北方出版社出版的书籍
        #查出版社对象 出版社对象查询书籍对象  外键不在自己这 反向查询
        # res=models.Publish.objects.filter(name='北方出版社').values('book__title')
        # print(res)
    
    
  • 双下划綫的进阶操作

    filter方法内直接使用
    	相同的查询题既可以使用一张表也可以换另外一张表
    # 1.查询主键为2的书籍对应的出版社(不能点书籍)
        # 获取出版社对象数据的.filter方法里面先判断
        # 我在出版社这,查找书籍对象 外键字段在书籍对象  反向查询 .表名小写__查询的条件
        # res = models.Publish.objects.filter(book__pk=2)
        # print(res) #获取的是列表套数据对象<QuerySet [<Publish: 这是对象:东方出版社>]>
        #
        # res = models.Publish.objects.filter(book__pk=2).first()
        # print(res.name)  #东方出版社
     # 5.查询北方出版社出版的书籍
        # 创建书籍表对象  书籍表查询出版社对象 外键字段在自己这  正向查询.外建名字
        # res=models.Book.objects.filter(publish__name='北方出版社')
        # #返回的是列表套数据对象
        # print(res) #<QuerySet [<Book: 这是对象:活着>, <Book: 这是对象:我在精神病院学斩神>]>
        #
        # for i in res: #先循环出来数据对象 在点字段名
        #     print(i.title) #活着   我在精神病院学斩神
    
    
    
  • 聚合查询

    from django.db.models import Max,Min,Count,Sum,Avg
    models.Book.objects.aggregate()
    
    # 3.统计价格最高的
    # res=models.Book.objects.aggregate(Max('price'))
    # print(res)
    
  • 分组查询

    """SQL语句:group by"""
    models.Book.objects.annotate()  # 按照models后面的表数据主键分组
    models.Book.objects.values('price').annotate()  # 指定分组的依据
    # 4.查询各个作者出的书的总价格
        #每个 以作者分组
        #作者对象 查找书籍对象 反向查询 
        # res= models.Author.objects.annotate(sum_price=Sum('book__price')).values('sum_price','name')
        # print(res)
        """
        1.大的分组
            models.表名.objects.annotate  按照models后面的表名分组(主键)
        2.小的分组
            models.表名.objects.values('price').annotate()  按照values括号内指定的字段分组
        """
    
    
  • F查询

    """F查询能够帮助我们获取到表中指定字段对应的原始数据"""
    from django.db.models import F
        # 1.将所有书籍的价格提升100块
        #使用F
        # models.Book.objects.update(price=F('price')+100)
    
        # 2.将所有书籍名称后面加上爆款后缀
        # 一般F用来操作数据对象  这个不常用
        # from django.db.models.functions import Concat
        # from django.db.models import Value
        # models.Book.objects.update(title=Concat(F('title'), Value('爆款')))
    
        # 3.查询库存数大于卖出数的书籍
        # res=models.Book.objects.filter(kucun__gt=F('maichu'))
        # print(res)
        # for i in res:
        #     print(i.title)
    
    

 

  • Q查询
  • orm字段相关补充
  • orm查询优化相关
  • orm事务操作
  • 图书管理系统练习

 

Q查询

"""Q查询"""
    # filter括号内多个条件默认逗号分隔 均为and关系
    # 1.查询主键为3或者卖出数为1000的数据
    # res = models.Book.objects.filter(pk=3, maichu=1000)  # 逗号分隔为and关系
    from django.db.models import Q

    ###########基本用法###########
    # res = models.Book.objects.filter(Q(pk=3), Q(maichu=1000))  # 逗号分隔为and关系
    # res = models.Book.objects.filter(Q(pk=3) | Q(maichu=1000))  # |分隔为or关系
    # res = models.Book.objects.filter(~Q(pk=3) | Q(maichu=1000))  # ~分隔为not关系
    # print(res)
    ###########进阶用法###########
    # filter(title='123') filter('title'='123')
    q = Q()  # 默认多个条件之间也是and关系
    q.connector = 'or'  # 也可以修改链接关系
    # q.children.append(('title', '三国演义爆款'))
    q.children.append(('title__contains', '爆'))
    q.children.append(('price', 1123))
    res = models.Book.objects.filter(q)
    print(res)

orm事务操作

"""
事务:ACID
		A原子性 每个事务都是不可分隔的最小耽误,要么同时成功,要么同时失败
		C一致性  执行完事务之后,数据库数据的状态从一个一致性状态变为另一个一致性状态(一致性与原子性是密切相关的)
		I独立性 事务与事务之间彼此独立 互不干扰
		D持久性 一个事务提交之后 他对数据的操作是永久的
start transaction 开启事务
...
rollback 回滚
commit 确认
"""
from django.db import transaction
    # 事务
    # 买一本 跟jason学Linux 书
    # 在数据库层面要做的事儿
    # 1. 创建一条订单数据
    # 2. 去产品表 将卖出数+1, 库存数-1
    from django.db.models import F
    # 开启事务处理
    try:
        with transaction.atomic():
            # 创建一条订单数据
            models.Book.objects.create(num="110110111", product_id=1, count=1)
            # 能执行成功
            models.Book.objects.filter(id=1).update(kucun=F("kucun") - 1, maichu=F("maichu") + 1)
    except Exception as e:
        print(e)
        transaction.rollback()  # 回滚
        transaction.commit()  # 提交

orm常用字段

# verbose_name  中文标识
AutoField()  # 专门用于主键
	"""需要指定primary key参数"""
CharField()
	"""需要指定max_length参数  varchar()"""
IntegerField()
DecimalField()
DateField()
DateTimeField()
	"""
	auto_now	  每次更新数据记录的时候会更新该字段
	auto_now_add  创建数据记录的时候会把当前时间添加到数据库
	"""
BooleanField()  # 布尔值类型
	"""
	传布尔值 存0或1
		is_delete = models.BooleanField()
		is_alive = models.BooleanField()
		is_buy = models.BooleanField()
	"""
TextField()  # 文本类型
	"""
	专门用于存储大段文本数据
		比如文章内容...
	"""
EmailField()  # 邮箱类型
FileField()
        - 字符串,路径保存在数据库,文件上传到指定目录
        - upload_to = ""    上传文件的保存路径
DecimalField(Field)
        - 10进制小数
        - 参数:
            max_digits,小数总长度
            decimal_places,小数位长度
        
"""自定义字段:为了防止django版本与最新的数据库产生差异"""
class MyCharField(models.Field):
    def __init__(self, max_length, *args, **kwargs):
        self.max_length = max_length
        super().__init__(max_length=max_length, *args, **kwargs)

    def db_type(self, connection):
        return 'char(%s)' % self.max_length
    
# 重要参数
	null = True
    default = None
    unique  如果设置为unique=True 则该字段在此表中必须是唯一的 。
    db_index  如果db_index=True 则代表着为此字段设置索引。
# 外键字段
	to、to_field、on_delete、related_name(给外键字段起别名 用于正反向)
    db_constraint
django1.x 2.x以上版本外键区别
django1.x是级联更新,级联删除

django2.x以上需要手动同步on_delete=CASCADE

orm查询优化

only与defer
select_related与prefetch_related


"""1.在ORM语句中 默认所有的查询都是惰性查询"""
    # res = models.Book.objects.all()
    # res1 = models.Book.objects.filter(pk=1)
    """2.only与defer"""
    # 获取指定字段对应的数据 并且封装成字典
    # res = models.Book.objects.values('title')
    # for d in res:
    #     print(d,type(d))
    #     print(d.get('title'))
    # 获取指定字段对应的数据 并且封装成对象
    # res = models.Book.objects.only('title')
    # for obj in res:
        # print(obj.title)
        # print(obj.price)
        # print(obj.publish_time)
    """
    对象点击only括号内填写的字段名称不会再走数据库查询
    但是点击括号内不存在的字段名称则每次都会走数据库查询
    """
    # res = models.Book.objects.defer('title')
    # for obj in res:
    #     print(obj.price)
    """
    与only互为反操作
    """
    # res = models.Book.objects.filter(pk=3).first()
    # print(res.publish.name)
    """select_related括号内只能放外键字段 并且不支持多对多外键字段"""
    # res = models.Book.objects.select_related('publish')
    # for obj in res:
    #     print(obj.publish.name)
    """
    内部是连表操作 会将外键关联的表与当前表拼接 之后将所有的数据全部封装到数据对象中 一条sql
    之后对象无论查询哪个表的数据都不再走数据库查询
    """
    res = models.Book.objects.prefetch_related('publish')
    for obj in res:
        print(obj.publish.name)
    """
    内部是子查询操作 先查询所有的书籍数据 之后查询每本书籍数据对应的出版社数据 两条sql
    之后将总数据封装到数据对象中
    """

图书管理系统

功能:只需要实现图书的增删改查即可
界面:使用bootstrap框架
知识点:路由层 视图层 模板层 模型层全部
1.先创建数据库db321
2.新建项目 创建数据表 添加数据
posted @ 2021-12-01 08:28  迪迦张  阅读(43)  评论(0编辑  收藏  举报