zoukankan      html  css  js  c++  java
  • 10 django模型层_多表

    模型层_多表

    建表&绑定关系

    06 django模型层 ables ables_app001models.py

     1 from django.db import models
     2 
     3 # Create your models here.
     4 
     5 
     6 class Publish(models.Model):
     7     id = models.AutoField(primary_key=True)
     8     name = models.CharField(max_length=32)
     9     city = models.CharField(max_length=32)
    10     email = models.EmailField()
    11 
    12     def __str__(self):
    13         return self.name
    14 
    15 
    16 class Author(models.Model):
    17     id = models.AutoField(primary_key=True)
    18     name = models.CharField(max_length=32)
    19 
    20     # 一对一  与AuthorDetail
    21     authorDetail = models.OneToOneField(to='AuthorDetail', on_delete=models.CASCADE)
    22 
    23     def __str__(self):
    24         return self.name
    25 
    26 
    27 class AuthorDetail(models.Model):
    28     id = models.AutoField(primary_key=True)
    29     age = models.BigIntegerField()
    30     addr = models.CharField(max_length=32)
    31     phone = models.BigIntegerField()
    32 
    33     def __str__(self):
    34         return self.age
    35 
    36 
    37 class Books(models.Model):
    38     id = models.AutoField(primary_key=True)
    39     title = models.CharField(max_length=32, unique=True)
    40     price = models.DecimalField(max_digits=5, decimal_places=2)
    41     pub_date = models.DateField()
    42     read_num = models.BigIntegerField(default=0)
    43     comment_num = models.BigIntegerField(default=0)
    44 
    45     # 一对多
    46     publish = models.ForeignKey(to='Publish', to_field='id', on_delete=models.CASCADE)
    47 
    48     # 多对多    自动创建第三张表  book_authors
    49     authors = models.ManyToManyField(to='Author',)
    50 
    51     def __str__(self):
    52         return self.title
    53 
    54 
    55 class Employee(models.Model):
    56     id = models.AutoField(primary_key=True)
    57     name = models.CharField(max_length=32, unique=True)
    58     age = models.BigIntegerField()
    59     sal = models.DecimalField(max_digits=5, decimal_places=1)
    60     dep = models.CharField(max_length=32)
    61 
    62     def __str__(self):
    63         return self.title

     增删改查

      1 from django.shortcuts import render, HttpResponse
      2 from tables_app001.models import *
      3 
      4 # Create your views here.
      5 
      6 
      7 def add(request):
      8 
      9     ###################    单表插入记录   ####################
     10     Publish.objects.create(name='人民出版社', city='北京', email='qwe@qq.com')
     11     Publish.objects.create(name='湖南出版社', city='湖南', email='hn@qq.com')
     12     Publish.objects.create(name='深圳出版社', city='深圳', email='sz@qq.com')
     13     AuthorDetail.objects.create(age=18, addr='湖南', phone='13537730001')
     14     AuthorDetail.objects.create(age=28,  addr='湖南', phone='13537730002')
     15     AuthorDetail.objects.create(age=38,  addr='深圳', phone='13537730003')
     16 
     17     ##################    一对一插入记录   ####################
     18     detail_obj1 = AuthorDetail.objects.filter(id=1).first()
     19     detail_obj2 = AuthorDetail.objects.filter(id=2).first()
     20     detail_obj3 = AuthorDetail.objects.filter(id=3).first()
     21     Author.objects.create(name='杨一', authorDetail_id=detail_obj1.id)
     22     Author.objects.create(name='杨二', authorDetail=detail_obj2)
     23     Author.objects.create(name='杨三', authorDetail=detail_obj3)
     24 
     25     ##################    一对一插入记录   ####################
     26     publish_obj = Publish.objects.filter(id=1).first()
     27     book_obj1 = Books.objects.create(title='盘龙', price=16, pub_date='2018-12-12', publish=publish_obj)
     28     book_obj2 = Books.objects.create(title='星辰变', price=20, pub_date='2017-12-12', publish=publish_obj)
     29 
     30 
     31     ##################    多对多插入记录 add 方法  ####################
     32     book_obj1 = Books.objects.filter(id=1).first()
     33     book_obj2 = Books.objects.filter(id=2).first()
     34 
     35     author_obj1 = Author.objects.filter(name='杨一').first()
     36     author_obj2 = Author.objects.filter(name='杨二').first()
     37     author_obj3 = Author.objects.filter(name='杨三').first()
     38 
     39     book_obj1.authors.add(author_obj1, author_obj2, author_obj3)
     40     # book_obj2.authors.add(1)
     41     book_obj2.authors.add(*[1,4])
     42 
     43 
     44     ##################    解除多对多的关系   ####################
     45     # book_obj1.authors.remove(1)
     46     # book_obj1.authors.remove(*[4,])
     47     # book_obj1.authors.remove(author_obj3)
     48     # book_obj1.authors.clear()  # 删除所有
     49 
     50 
     51     return HttpResponse('OJBK!')
     52 
     53 
     54 def query(request):
     55     """
     56     跨表查询:
     57        1 基于对象查询
     58        2 基于双下划线查询
     59        3 聚合和分组查询
     60        4 F 与 Q查询
     61     """
     62     # -------------------------基于对象的跨表查询(子查询)-----------------------
     63     # 一对多查询的正向查询 : 查询盘龙这本书的出版社的名字
     64     res = Books.objects.filter(title='盘龙').first().publish.name
     65     # 一对多查询的反向查询 : 查询人民出版社出版过的书籍名称
     66     res = Publish.objects.filter(name='人民出版社').first().books_set.all().values('title')
     67     # 多对多查询的正向查询 : 查询星辰变这本书的所有作者的名字
     68     res = Books.objects.filter(title='星辰变').first().authors.all().values('name')
     69     # 多对多查询的反向查询 : 查询杨一出版过的所有书籍名称
     70     res = Author.objects.filter(name='杨一').first().books_set.all().values('title')
     71     # 一对一查询的正向查询 : 查询杨二的手机号
     72     res = Author.objects.filter(name='杨二').first().authorDetail.phone
     73     # 一对一查询的反向查询 : 查询手机号为0001尾号的作者的名字
     74     res = AuthorDetail.objects.filter(phone__endswith='0001').first().author.name
     75 
     76 
     77     # -------------------------基于双下划线的跨表查询(join查询)-----------------------
     78     '''
     79         正向查询按字段,反向查询按表名小写用来告诉ORM引擎join哪张表
     80     '''
     81     # 一对多查询的正向查询 : 查询盘龙这本书的出版社的名字
     82     res = Books.objects.filter(title='盘龙').values('publish__name')
     83     # ----->  <QuerySet [{'publish__name': '人民出版社'}]>
     84 
     85     # 一对多查询的反向查询 : 查询人民出版社出版过的书籍名称
     86     res = Publish.objects.values('name').filter(books__title='盘龙')
     87     res = Publish.objects.filter(books__title='盘龙').values('name')  # 都可以
     88     # -----> <QuerySet [{'name': '人民出版社'}]>
     89 
     90     # 多对多查询的正向查询 : 查询星辰变这本书的所有作者的名字
     91     res = Books.objects.filter(title='星辰变').values('authors__name')
     92     # -----> <QuerySet [{'authors__name': '杨一'}, {'authors__name': '杨二'}]>
     93 
     94     # 多对多查询的反向查询 : 查询杨一出版过的所有书籍名称
     95     res = Author.objects.filter(books__title='星辰变').values('name')
     96     res = Author.objects.values('name').filter(books__title='星辰变')  # 都可以
     97     # -----> <QuerySet [{'name': '杨一'}, {'name': '杨二'}]>
     98 
     99     # 一对一查询的正向查询 : 查询杨二的手机号
    100     res = Author.objects.filter(name='杨二').values('authorDetail__phone')
    101     # -----> <QuerySet [{'authorDetail__phone': 13537730002}]>
    102 
    103     # 一对一查询的反向查询 : 查询手机号为0001尾号的作者的名字
    104     res = AuthorDetail.objects.filter(phone__endswith='0001').values('author__name')
    105     # ----->  <QuerySet [{'author__name': '杨一'}]>
    106 
    107     # 练习: 查询人民出版社出版过的所有书籍的名字以及作者的姓名
    108     res = Books.objects.filter(publish__name='人民出版社').values('title', 'authors__name')
    109 
    110     # 练习: 手机号以0001结尾的作者出版过的所有书籍名称以及出版社名称
    111     res = Author.objects.filter(authorDetail__phone__endswith='0001').values('books__title', 'books__publish__name')
    112     # < QuerySet[{'books__title': '星辰变', 'books__publish__name': '人民出版社'}, {'books__title': '盘龙','books__publish__name': '人民出版社'}] >
    113 
    114 
    115     # --------------  聚合 aggregate:返回值是一个字典,不再是queryset  --------------
    116     # 查询所有书籍的平均价格
    117     from django.db.models import Avg, Max, Min, Count, Sum
    118     res = Books.objects.all().aggregate(Avg('price'))
    119     # --------> {'price__avg': Decimal('18.000000')}
    120     res = Books.objects.all().aggregate(avgPrice=Avg('price')) # 取别名
    121     # --------> {'avgPrice': Decimal('18.000000')}
    122 
    123     # 查询价格最高的书籍
    124     res = Books.objects.all().aggregate(Max('price'))
    125     # -------->  {'price__max': Decimal('20.00')}
    126 
    127 
    128     # ---------------  分组查询 annotate ,返回值依然是queryset  ---------------
    129 
    130     # ------------------------->单表分组查询:
    131     # Employee.objects.create(name='steven', age=18, sal=1000, dep='销售部')
    132     # Employee.objects.create(name='mike', age=28, sal=2000, dep='销售部')
    133     # Employee.objects.create(name='ben', age=38, sal=1000, dep='销售部')
    134     # Employee.objects.create(name='jack', age=48, sal=8000, dep='IT部')
    135     # Employee.objects.create(name='Mary', age=18, sal=3000, dep='IT部')
    136     # 单表分组查询的ORM语法: 单表模型.objects.values("group by的字段").annotate(聚合函数("统计字段"))
    137 
    138     # 查询每一个部门的名称以及员工的平均薪水
    139     res = Employee.objects.values('dep').annotate(Avg('sal'))
    140     # <QuerySet [{'dep': '销售部', 'sal__avg': Decimal('1333.33333')}, {'dep': 'IT部', 'sal__avg': Decimal('5500.00000')}]>
    141 
    142     # 查询每一个部门的名称以及员工数
    143     res = Employee.objects.values('dep').annotate(Count('id'))
    144     #  <QuerySet [{'dep': '销售部', 'id__count': 3}, {'dep': 'IT部', 'id__count': 2}]>
    145 
    146     # ------------------------->多表分组查询:
    147     # Books.objects.create(title='吞噬星空', price=30, pub_date='2017-12-12', publish_id=2)
    148     # Books.objects.create(title='蛮荒记', price=40, pub_date='2017-12-12', publish_id=2)
    149 
    150     ## 示例1 查询每一个出版社的名称以及出版的书籍个数
    151     res = Books.objects.values('publish__name').annotate(c=Count('id'))
    152     res = Books.objects.values('publish__id').annotate(c=Count('id')).values('publish__name', 'c')
    153     res = Publish.objects.values('id').annotate(c=Count('books__id')).values('name', 'c')
    154     # <QuerySet [{'publish__name': '人民出版社', 'c': 2}, {'publish__name': '湖南出版社', 'c': 2}]>
    155 
    156     ## 示例2 查询每一个作者的名字以及出版过的书籍的最高价格
    157     res = Author.objects.values('pk').annotate(Max('books__price'))
    158     res = Author.objects.values('pk').annotate(max=Max('books__price')).values('name', 'max')
    159     # <QuerySet [{'name': '杨一', 'max': Decimal('20.00')}, {'name': '杨二', 'max': Decimal('20.00')}, {'name': '杨三', 'max': Decimal('16.00')}]>
    160 
    161     # 总结 跨表的分组查询的模型:
    162     # 每一个后表模型.objects.values("pk").annotate(聚合函数(关联表__统计字段))
    163     # 示例3 查询每一个书籍的名称以及对应的作者个数
    164     res = Books.objects.values('pk').annotate(c=Count('authors__id')).values('title','c')
    165     # < QuerySet[{'title': '盘龙', 'c': 3}, {'title': '星辰变', 'c': 2}, {'title': '吞噬星空', 'c': 0}, {'title': '蛮荒记', 'c': 0}] >
    166 
    167     #################### 跨表分组查询的另一种玩法  ####################
    168     # 示例1 查询每一个出版社的名称以及出版的书籍个数
    169     res = Publish.objects.values('pk').annotate(c=Count('books__id')).values('name','c')
    170     res = Publish.objects.all().annotate(c=Count('books__id')).values('name','c')
    171     res = Publish.objects.annotate(c=Count('books__id')).values('name','c')
    172     # < QuerySet[{'name': '人民出版社', 'c': 2}, {'name': '湖南出版社', 'c': 2}, {'name': '深圳出版社', 'c': 0}] >
    173 
    174     ##################### 练习   ####################
    175     # 统计每一本以'盘'开头的书籍的作者个数:
    176     res = Books.objects.filter(title__startswith='').annotate(c=Count('authors__id')).values('title','c')
    177     # <QuerySet [{'title': '盘龙', 'c': 3}]>
    178 
    179     # 统计不止一个作者的图书
    180     res = Books.objects.annotate(c=Count('authors__id')).filter(c__gt=1).values('title','c')
    181     # < QuerySet[{'title': '盘龙', 'c': 3}, {'title': '星辰变', 'c': 2}] >
    182 
    183     # 根据一本图书作者数量的多少对查询集QuerySet进行排序
    184     res = Books.objects.annotate(c=Count('authors__id')).values('title', 'c').order_by('c')
    185     # < QuerySet[{'title': '吞噬星空', 'c': 0}, {'title': '蛮荒记', 'c': 0}, {'title': '星辰变', 'c': 2}, {'title': '盘龙', 'c': 3}] >
    186 
    187     # 查询各个作者出的书的总价格:
    188     res = Author.objects.annotate(total=Sum('books__price')).values('name','total')
    189     # <QuerySet [{'name': '杨一', 'total': Decimal('36.00')}, {'name': '杨二', 'total': Decimal('36.00')}, {'name': '杨三', 'total': Decimal('16.00')}]>
    190 
    191     # 总结 跨表的分组查询的模型:
    192     # 每一个后的表模型.objects.values("pk").annotate(聚合函数(关联表__统计字段)).values("表模型的所有字段以及统计字段")
    193     # 每一个后的表模型.objects.annotate(聚合函数(关联表__统计字段)).values("表模型的所有字段以及统计字段")
    194 
    195 
    196     # ###############  F 查询条件里包含字段  ###############
    197     # 查询评论数大于阅读数的书记
    198     from django.db.models import F
    199     res = Books.objects.filter(read_num__gt=F('comment_num'))
    200     # < QuerySet[ < Books: 盘龙 >, < Books: 星辰变 >] >
    201 
    202     # 所有书的价格上调 10%
    203     res = Books.objects.update(price=F('price')*1.1)
    204 
    205 
    206     # ###############  Q 查询条件关系  与或非 ###############
    207     from django.db.models import Q
    208     # 与 &
    209     res = Books.objects.filter(price__lt=3, read_num__gt=100)
    210     res = Books.objects.filter(Q(price__lt=3)&Q(read_num__lt=100))
    211 
    212     # 或 |
    213     res = Books.objects.filter(Q(price__lt=3)|Q(read_num__lt=100))
    214 
    215     # 非 ~
    216     res = Books.objects.filter(~Q(price__lt=3))
    217 
    218 
    219     print(res)
    220     return HttpResponse('OJBK!')
  • 相关阅读:
    MainFrm.cpp
    MyView.h
    我的东软实习项目一:车牌识别之MFC----MyView.cpp
    洛谷P1055 字符串的处理-----ISBN
    跳出多重循环------设置标志量
    单链表的创建及操作
    线性表的建立及运算
    JVM--你常见的jvm 异常有哪些? 代码演示:StackOverflowError , utOfMemoryError: Java heap space , OutOfMemoryError: GC overhead limit exceeded, Direct buffer memory, Unable_to_create_new_native_Thread, Metaspace
    JVM-gcRoots 和 强引用,软引用, 弱引用, 虚引用, 代码演示和应用场景
    JUC 并发编程--08,线程池,三大方法,七大参数,4种拒绝策略,代码演示
  • 原文地址:https://www.cnblogs.com/znyyy/p/11337687.html
Copyright © 2011-2022 走看看