• Django ORM 多对多操作 使用聚合函数和分组 F查询与Q查询


    创建表

      
    # models.py
    
    form django.db import models
    
    class Book(models.Model):  # 表名book,django会自动使用项目名+我们定义的表名
      # 如没有自定义主键,django会自动添加一个主键,字段名id 自增
      name = models.CharField(max_length=20)  # 字段名name 类型 vachar(20)
      price = models.IntegerField()   # 字段名price 类型int
      pub_date = models.DateField()   # 字段名pub_date 类型 date (时间戳)
      publish = models.ForeighKey('Publish')  # 创建外键关联到Publish表的id字段,django会自动将该名称改为publish_id  
    # 如果这样写 publish = models.ForeighKey(Publish) 括号内无引号,则必须将Publish类放到Book类的上面
      authors = models.ManyToManyField('Author',related_name='xxx')  将book与author表做多对多关系 related_name 同一对多中的说明
      # django会自动创建一张表(book与author的中间关联表)名称为appname_book_authors
      def __str__(self):
        return self.name  # 打印实例对象时显示为self.name


    #class Book_Author(models.Model):  自己创建第三张表
    #  book = models.ForeignKey('book')
    #  author = models.ForeignKey('Author')

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

    class Author(models.Model):
      name = models.CharField(max_length=32)
      age = models.IntegerField()

      def __str__(self):
        return self.name
    
    
     
    复制代码

    多对多的添加设置删除

    复制代码
     
    # views.py
    
    from django.shortcuts import render
    from app_name.models import *  # 导入models.py
    
    def add(request):  # 增加数据的视图函数
      # 系统自己创建的第三张表使用创建对象操作
    book_obj = Book.objects.get(id=4)  # 取出id为4的书
      # book_obj.authors.all()  此时取出的是一个空的集合
      authors_obj = Author.objects.all()  # 取出所有author名称的集合
      book_obj.authors.add(*author_obj)  # 将所有作者添加到这本书中
      book_obj.authors.remove(*author_obj) # 将所有作者从书中删除
      book_obj.authors.add(2) # 将id为2的作者添加到此书
      book.obj.authors.add([1,2])  # 将id为1和2的作者添加到此书
      book_obj.authors.remove(1) # 将id为1的作者从书中删除
    book_obj.authors.clear() # 清除此书所有的作者
    book_obj.authors.set([2,3,4]) # 将书的作者设置为id为2,3,4的作者 (相当于重新设置)
      

    # 我们自己定义的第三张表(不常用)
      Book_Author.objects.create(book_id=2, author_id=3)
      
    obj = Book.objects.get(id=2)
    obj.book_author_set.all()[0]l.author
      

      return HttpResponse('xxx')
    
    
    
    
    复制代码

    多对多的查询

    复制代码
     
    # 怎么使用多对多查询呢?
    book_obj = Book.objects.get(name='python')
    print(book_obj.name)  # python
    print(book_obj.authors.all())  # QuerySet  返回一个QuerySet对象,里面是author的实例集合
    print(type(book_obj.authors.all()))  # <class 'django.db.models.query.QuerySet'>

    1、查询作者id为2出的所有的书
    author_obj=Author.objects.get(id=2)
    author_obj.book_set.all()

    2、查询三班所对应的所有老师
    obj = Classes.objects.filter(name='三班').first()  从班级表取出三班
    obj.m.all()  # 从三班中取所有的老师 m表示多对多关系的名称

    还是通过双下划线
    2、查询作者alex出的所有书
    Book.objects.filter(authors__name='alex').values('name','price')
    
    
     
    复制代码

    使用聚合函数和分组

    复制代码
    
    
    # views.py

    from django.db.models import Avg,Min,Sum,Max,Count

    # 聚合函数
    # 取出所有书总价格的平均值
    Book.objects.all().aggregate(Avg('price'))  # 必须使用aggregate函数
    # 取alex出的书的总价格
    Book.objects.filter(author__name='alex').aggregate(alex_money=Sum('price'))  # {'alex_money':166}
    # 取alex出的书的数量
    Book.objects.filter(author__name='alex').aggregate(alex_count=Count('price'))  # {'alex_count':2}

    # 分组
    # 每一个作者出的书的总价
    Book.objexts.values('author__name').annotate(Sum('price'))  # QuerySet [{'price__sum':211, 'authors__name':'alex'},...]
    # 查每个出版社最便宜书的价格
    Publish.bojects.values('name').annotate(Min('book__price'))


    复制代码

    F查询和Q查询

    针对的问题:1、在filter中定义的条件只能是and操作没有or和not   2、如果要将所有书的价格都加上10 用price=price+10是不行的

    复制代码
    
    
    from django.db.models import Q,F
    #第一个问题
    Book.objects.filter(Q(price=87)|Q(name='linux'))  # select * from book where (price=87 or name='linux')
    Book.objects.filter(~Q(name='linux'))  # select * from book where name != 'linux'
    #第二个问题
    Book.objects.all().update(price=F('price')+10)

    关键字查询与F,Q查询一起使用时,必须将F,Q查询放在前面
    Book.objects.filter(Q(name='Go'),price=87)


  • 相关阅读:
    团队开发day09
    团队开发day08
    团队开发day07
    python 字符串操作,获取任意字符串的方法(开头,结尾开始)
    ERIKA OS学习和使用总结
    解决win7无法正常进入睡眠的问题
    简单实用的Makefile
    js 签字插件
    html2canvas实现截取指定区域或iframe的区域
    jquery监听动态添加的input的change事件
  • 原文地址:https://www.cnblogs.com/huhuxixi/p/10681373.html
Copyright © 2020-2023  润新知