zoukankan      html  css  js  c++  java
  • orm的表操作

    1. ORM

    2. ORM常用字段和属性
        1. AutoField(primary_key=True)
        2. CharField(max_length=32)
        3. IntgerField()
        4. DateField()
        5. DateTimeField()

    3. auto_now_add --> 创建的时候自动填充当前时间

    4. auto_now --> 每次修改的时候自动把当前时间更新

    5. 关系字段
        1. ForeignKey(to="类名",related_name=“xx”) --> 1对多 ,外键通常设置在多的那一边、
        2. ManyToMany(to="类名",related_name="xx") --> 多对多,通常设置在正向查询多的那一边

    6. 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语句(了解即可)

    1. ORM 一对一
          1. 什么时候用一对一?
            当 一张表的某一些字段查询的比较频繁,另外一些字段查询的不是特别频繁
            把不怎么常用的字段 单独拿出来做成一张表 然后用过一对一关联起来

        2. 优势
          既保证数据都完整的保存下来,又能保证大部分的检索更快

    1. ORM中的用法
          OneToOneField(to="")

       from app01 import models

    # 一对一的查询
    # author_obj = models.Author.objects.get(id=1)
    # obj = author_obj.detail
    # print(obj.hobby, obj.addr)
    
    1. ORM 多对多的三种方式
        多对多的方式:
          1. ORM自动帮我创建第三张表  

    class Publisher(models.Model):
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=32)

    def __str__(self):
        return self.name
    

    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)
    # 创建外键,关联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
    

    作者详情

    class AuthorDetail(models.Model):
    # 爱好
    hobby = models.CharField(max_length=32)
    # 地址
    addr = models.CharField(max_length=128)

    if name == 'main':
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ormday70.settings")
    import django
    django.setup()

    # 在app01 里面 查询 id是1的作者关联的书
    from app01 import models
    ret = models.Author.objects.get(id=1).books.all()
    
    # 从作者关联的书里面移除id是1的书
    models.Author.objects.get(id=1).books.remove(1)
    print(ret)
    print("app01".center(80, "-"))
    

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

    出版社

    class Publisher(models.Model):
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=32)

    def __str__(self):
        return self.name
    

    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)
    # 创建外键,关联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()
    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")

    class Meta:
        # 建立唯一约束
        unique_together = ("author", "book")
    

    作者详情

    class AuthorDetail(models.Model):
    # 爱好
    hobby = models.CharField(max_length=32)
    # 地址
    addr = models.CharField(max_length=128)

    在app02 里面 查询 id是1的作者关联的书

    from app02 import models

    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)

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

    出版社

    class Publisher(models.Model):
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=32)

    def __str__(self):
        return self.name
    

    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)
    # 创建外键,关联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()
    # 通过through,through_fields来指定使用我创建的第三张表来构建多对多的关系
    books = models.ManyToManyField(to="Book", through="Author2Book", through_fields=("author", "book",))
    # 第一个字段: 多对多设置在哪一张表里, 第三张表通过什么字段找到这张表 就把这个字段写在前面
    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")

    # memo
    memo = models.CharField(max_length=64, null=True)
    
    class Meta:
        # 建立唯一约束
        unique_together = ("author", "book")
    

    作者详情

    class AuthorDetail(models.Model):
    # 爱好
    hobby = models.CharField(max_length=32)
    # 地址
    addr = models.CharField(max_length=128)
     # 在app03 里面 查询 id是1的作者关联的书
          from app03 import models
          ret = models.Author.objects.get(id=1).books.all()
          print(ret)
          # 从作者关联的书里面移除id是1的书
          # 没有django ORM 封装的那些快捷方式了,我们要自己亲自改第三张表
          models.Author2Book.objects.get(author_id=1, book_id=1).delete()

  • 相关阅读:
    Java微信分享接口开发
    lintcode 刷题 by python 部分链表题总结(2)
    基于CART的回归和分类任务
    机器学习: K-means 聚类
    python 中的堆 (heapq 模块)应用:Merge K Sorted Lists
    名人、皇家谱系
    python实现数组和链表的归并排序
    Python 正则 —— 捕获与分组
    ArcGIS中的数据连接问题——数据类型不统一
    Spring boot 搭建
  • 原文地址:https://www.cnblogs.com/whnbky/p/12643565.html
Copyright © 2011-2022 走看看