• Django(ORM查询2)


    day70

    ORM训练专题 :http://www.cnblogs.com/liwenzhou/articles/8337352.html

    内容回顾
        1. ORM
            1. ORM常用字段和属性
                1. AutoField(primary_key=True)
                2. CharField(max_length=32)
                3. IntgerField()
                
                4. DateField()
                5. DateTimeField()
                    1. auto_now_add    --> 创建的时候自动填充当前时间
                    2. auto_now        --> 每次修改的时候自动把当前时间更新
                    
            2. 关系字段
                1. ForeignKey(to="类名",related_name=“xx”)   --> 1对多  ,外键通常设置在多的那一边、
                2. ManyToMany(to="类名",related_name="xx")    --> 多对多,通常设置在正向查询多的那一边
                
     
            3. ORM一般操作
                1. 必知必会13条
                    1. 返回QuerySet对象的
                        1. all()
                        2. filter()
                        3. values()
                        4. values_list()
                        5. exclude()
                        6. order_by()
                        7. reverse()
                        8. distinct()
                    2. 返回具体对象的
                        1. get()
                        2. first()
                        3. last()
                    3. 返回布尔值的
                        1. exists()
                    4. 返回具体数值的
                        1. count()
                2. 单表查询的双下划线
                    1. models.Book.objects.filter(id__gt=1)
                    2. models.Book.objects.filter(id__in=[1,2,3])
                    3. models.Book.objects.filter(id__range=[1,5])
                    4. models.Book.objects.filter(title__contains="沙河")
                    5. models.Book.objects.filter(title__icontains="沙河")
                    6. models.Book.objects.filter(title__startswith="沙河")
                    7. models.Book.objects.filter(title__endswith="沙河")
                    8. models.Book.objects.filter(publish_date__year=2017)
                    9. models.Book.objects.filter(publish_date__month=2)
                3. 外键的跨表查询
                    1. 正向查找
                        1. 基于对象
                            book_obj = models.Book.object.get(id=1)
                            book_obj.publisher.name
                        
                        2. 基于双下划线的
                            models.Book.object.filter(id=1).values("publisher__name")
                        
                    2. 反向查找(由出版社查书)
                        1. 基于对象
                            publisher_obj = models.Publisher.objects.get(id=1)
                            默认反向查找的时候是表名加_set
                                publisher_obj.book_set.all()
                            如果在外键中设置了related_name="books"
                                publisher_obj.books.all()
                        
                        2. 基于双下划线
                            models.Publisher.objects.filter(id=1).values("book__title")
                            如果配置了related_query_name="books"
                            models.Publisher.objects.filter(id=1).values("books__title")
                        
                4. 分组和聚合
                    1. 聚合
                        from django.db.models import Avg, Sum, Max, Min, Count
                        models.Book.objects.all().aggregate(Avg("price"))
                    2. 分组
                        book_list = models.Book.objects.all().annotate(author_num=Count("author"))
                
                5. F和Q
                    1. 当需要字段和字段作比较的时候用F查询
                    2. 当查询条件是 或 的时候 用Q查询,因为默认的filter参数都是且的关系
                    
                6. 事务
                    1. 保证数据的原子性操作!!!
                
                7. 执行原生的SQL语句(了解即可)

    ORM一对一表结构介绍:

    1. 什么时候用一对一?
            当 一张表的某一些字段查询的比较频繁,另外一些字段查询的不是特别频繁
            把不怎么常用的字段 单独拿出来做成一张表 然后用过一对一关联起来
            
    2. 优势
            既保证数据都完整的保存下来,又能保证大部分的检索更快
                
    3. ORM中的用法
            OneToOneField(to="")

    ORM 多对多的三种方式

    在三个不同的应用中实验


    多对多的方式:
            1. ORM自动帮我创建第三张表  

    调用:

    import os
    import sys
    if __name__ == '__main__':
        # 加载Django项目的配置信息  这一句就在manage.py文件中
        os.environ.setdefault("DJANGO_SETTINGS_MODULE",
                              "ormday70.settings")
        # 导入Django,并启动Django项目
        import django
        django.setup()
    
        from app01 import models
    
      ret = models.Author.objects.get(id=1).books.all()
      print(ret)

    Author中有Book可以直接调用。


            2. 自己创建第三张表, 利用外键分别关联作者和书
                关联查询比较麻烦,因为没办法使用ORM提供的便利方法

    #
    class Book(models.Model):
        title = models.CharField(max_length=32)
        publish_date = models.DateField(auto_now_add=True)
        price = models.DecimalField(max_digits=5, decimal_places=2)
        # memo = models.TextField(null=True)
        # 创建外键,关联publish
        publisher = models.ForeignKey(to="Publisher")
    
        def __str__(self):
            return self.title
    
    # 作者
    class Author(models.Model):
        name = models.CharField(max_length=32)
        age = models.IntegerField()
        phone = models.IntegerField()
        # books = models.ManyToManyField(to="Book", related_name="authors")  # 多对多
        detail = models.OneToOneField(to="AuthorDetail")
    
        def __str__(self):
            return self.name
    
    # 自己动手 创建第三张表 作者与书
    # 在orm层面 作者和书没有多对多的关系
    class Author2Book(models.Model):
        id = models.AutoField(primary_key=True)
        # 作者id
        author = models.ForeignKey(to="Author")
        # 书id
        book = models.ForeignKey(to="Book")

    以上建了第三张表Author2Book

    调用

    from app02 import models
        # 在 app02 里面 查询 id是1的作者关联的书
        # author_obj = models.Author.objects.get(id=1)
        # book_list = author_obj.books.all()  # Author类中并没有book属性 使用ManyToManyField可行
    
        # 需在第三张表中查      关联查询比较麻烦,因为没办法使用ORM提供的便利方法
        ret = models.Author2Book.objects.filter(author_id=1).values_list("book_id")
        # id是1的作者的书的id
        print(ret) # 元组
        ret = [i[0] for i in ret]
        # 查书这张表
        ret = models.Book.objects.filter(id__in=ret)
        print(ret)

    需要在第三张表(Author2Book)中查询

      
            3. 自己创建第三张表,使用ORM 的ManyToManyFiled()
                 使用此种方式创建多对多表的时候,没有 add() remove() 等方法      

    调用:

     from app03 import models
     ret = models.Author.objects.get(id=1).books.all()
     print(ret)

    id为1的作者的所有的书。

    可以通过Author调用books,毕竟Author类中有book字段。

      

    我们应该用哪种?
            看情况:
                1. 如果你第三张表没有额外的字段,就用第一种
                2. 如果你第三张表有额外的字段,就用第三种或第一种   
            相亲网站:
                Boy
                    girls = ManyToManyField(to=“Girl")
                
                Girl        
                约会记录:多对多
                    id  boy_id girl_id  date(额外字段)

  • 相关阅读:
    JavaCV音视频开发宝典:录制vp8和vp9编码的webm格式视频,以mp4转webm为例
    JavaCV音视频开发宝典:使用JavaCV采集windows系统声音并录制成mp3音频文件(FFmpeg采集windows系统声音)
    JavaCV音视频开发宝典:使用JavaCV和springBoot实现httpflv直播服务,无需流媒体服务,浏览器网页flv.js转封装方式播放rtsp,rtmp和桌面投屏实时画面
    linux用户用户组与ACL
    QUIC协议详解
    技术分享 | 黑盒测试方法论—等价类
    技术分享 | 这些常用测试平台,你们公司在用的是哪些呢?
    干货 | 测试专家(前阿里P8)聊测试职业发展常见瓶颈
    如何做好测试开发?| 破解测试人技术成长常见的 3 种错误思维!
    技术分享 | 黑盒测试方法论—因果图
  • 原文地址:https://www.cnblogs.com/112358nizhipeng/p/10470599.html
Copyright © 2020-2023  润新知