zoukankan      html  css  js  c++  java
  • 多表查询

    1.增删改

    一对多

      增:先一后多,外键可以为对象或依赖表的主键

        publish = Publish.objects.create(...)

        Book.objects.create(...,publish=publish | publish_id = publish.id)

      删:存在级联删除

      改:Book修改外键,对应的值一定要提前存在

    一对一

      同上

    多对多

      关系表的获取,Book(author) Author==>book.author

      增:add(作者对象们或主键们) book.author.add()

      删:clear()   |  remove()

      改:set([a2,a3])    a1,a2   => a2,a3

    2.查:

      基于对象,正向找属性,反向找类名小写(多条记录类名小写加_set)

      Book.objects.filter(id=1)[0].publish.first().name

      Publish.objects.filter(id=1)[0].book_set.first().name

      基于双下划线,正向找属性,反向找类名小写

      Book.objects.filter(id=1).values('name','publish__name')[0]

      Publish.objects.filter(id=1).values('name','book__name')[0]

    三,分组查询概念

    Book:id  name  price  publish_date  publish

    1.聚合函数可以单独使用:将整张表作为一个大的分组,查询字段只能是聚合结果

    select max(price),group_concat(name) from book where id<10;

    2.聚合函数在分组下使用

    select publish_id ,max(price) as high_price from book group by publish_id having max(price) > 50

    四,聚合查询

    聚合函数的使用场景

      单独使用:不分组,只查局和结果

      分组使用:按字段分组,可查分组字段与局和结果

    导入聚合函数

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

    五,单独聚合查询:aggregate

    语法:aggregate(别名=聚合函数('字段'))

    规则:

    1.可以同时对多个字段进行聚合处理,aggregate(别名1=聚合函数1('字段1'),...别名n=聚合函数n('字段n'))

    2.方法返回值为dict类型

    3.是QuerySet对象方法

    案例:所有书中最贵的书的价格:

    Book.objects.all().aggregate(high_price=Max('price'))

    六,组聚合查询:annotate

    语法:values('分组字段').annotate(别名=聚合函数('字段')).filter(聚合字段别名条件).values('取分组字段','取聚合字段别名')

    规则:

    1.values(...).annotate(...)为分组组合,values控制分组字段,annotate控制聚合字段

    2.values可按多个字段分组calues('分组字段1',...,'分组字段n'),??如果省略则代表按操作表的主键分组

    3.可以同时对多个字段进行聚合处理annotate(别名1=聚合函数1('字段1'),...,别名n=聚合函数n('字段n'))

    4.分组后的filter代表having判断,只对聚合字段进行条件判断,可以省略(对非聚合字段或分组字段进行条阿金判断则代表where判断)

    5.取字段值values(...)省略默认取所有分组字段与聚合字段,也可以自主取个别分组字段及聚合字段(取字段的values中出现了非分组或非聚合字段,该字段自动成为分组字段)

    案例:每个出版社出版的最贵的书的价格高于50元的出版社名与最高价格

    Book.objects.all().values('publish__name').annotate(high_price=Max('price')).filter(high_price_gt=50).values('publish__name,'high_price')

    七,常用共有字段属性

    1.null:默认为False,True表示字段可为null

    2.blank:默认为False,True表示字段可为空

    3.choice:可选的,限制了该选项的字段值必须是所指定的choice中的一个:

    sex = models.SmallIntegerField(choices=((1,'男'),(2,'女')))

    obj.get_sex_display()取对应的值

    4.db_column:自定义字段名

    5.db_index:如果为True的话,设置索引

    6.default:字段默认值

    7.editable:默认为True,若为False,则不会在/admin/界面表示

    8.primary_key:若设置为True,则表示将该字段设置为主键,一般情况下django默认会设置一个自增长的id主键

    9.unique:若设置为True,该字段值不可重复

    八,常用字段

    1.AutoField():默认自增主键(primary_key=True),django会默认建立id字段主键

    2.BooleanField():布尔字段,对应数据库tinyint类型

    3.CharField():字符类型  字段属性max_length=64,数据长度,必须明确

    4.DateField():年月日时间类型

    字段属性auto_now=True,数据被更新就会更新时间

    字段属性auto_now_add=True,数据第一次参数时产生

    5.dateTimeField():年月日小时分钟秒时间类型

    字段属性auto_now=True,数据被更新就会更新时间

    字段属性auto_now_add=True,数据第一被赋值时产生

    6.DecimalField():混合精度的小数类型

    字段属性max_digits=3,限定数字的最大位数(包含小数位)

    字段属性decimal_places=2,限定小数的最大位数

    7.IntegerField():整形

    九,不常用字段

    1.BigAutoField():大整形自增

    2.BigIntegerField():长整型

    3.EmailField():邮箱字段,拥有/admin/验证

    4.FloatField():浮点型小数

    5.SmallIntegerField():小整形

    6.TextField():大文本类型

    7.FileField():文件字段

    十,关系字段

    1.ForeignKey():外键字段

    字段属性to关联模型类

    字段属性to_field关联字段,省略默认关联主键

    字段属性on_delete(外键关联数据被删除时的操作)

      models.CASCADE级联删除

      models.PROTECT 抛出异常

      models.SET_NULL 设置空值

      models.SET_DEFAULT 设置默认值

      models.SET(value)自定义值

    字段属性related_name自定义反向查询的字段名

    字段属性db_constraint=False取消关联关系,但还可以使用连表查询

    总结:models.ForeignKey(to='关联的类名',null=True,on_delete=models.SET_NULL,db_constraint=False,related_name='本类名小写')

    2,OneToOneField():一对一外键字段

    字段同外键

    3.ManyToManyField():多对多关系字段

      字段属性to关联模型类

      字段属性through关联关系类

      字段属性through_fields关联关系表中(本身类名小写字段,关联表类名小写字段)

    十一,断开外键关联的ForeignKey使用

    1.不使用ForeignKey方式断开关联,不再支持Django ORM连表查询语法

    class Publish(models.Model):
    name = models.CharField(max_length=20)
    class Book(models.Model):
    name = models.CharField(max_length=20)
    # 字段需要写_id来表示相关表的字段信息
    publish_id = models.IntegerField()

    # 2、使用ForeignKey方式用db_constraint=False字段属性断开关联
    ,依然支持Django ORM连表查询语法,建议使用
    class Publish(models.Model):
    name = models.CharField(max_length=20)
    class Book(models.Model):
    name = models.CharField(max_length=20)
    # 字段不需要写_id来表示相关表的字段信息,ORM会自动添加
    my_publish = models.ForeignKey(to='MyPublish', null=True,
    on_delete=models.SET_NULL, db_constraint=False)

    十二,断开关联的多对多自动创建关系表

    使用ManyToManyField方式用db_constraint=False字段属性断开关联,依然支持Django Orm连表查询语法,建议使用

    class MyBook(models.Model):
    name = models.CharField(max_length=20)
    my_author = models.ManyToManyField(to='MyAuthor',
    db_constraint=False)
    class MyAuthor(models.Model):
    name = models.CharField(max_length=20)

    十三,断开关联的多对多手动创建关系表

    手动创建关系表可以让关系表可以拥有更多的自身的字段,同时可以通过关系表类名直接获取第三张表

    1.和自动建立关系表类似,依然支持Django ORM连表查询语法(多对多借助关系表连表查询)

    class Book(models.Model):
    name = models.CharField(max_length=20)

    class Author(models.Model):
    name = models.CharField(max_length=20)

    class Book_Author(models.Model):
    book = models.ForeignKey(to="Book", null=True,
    on_delete=models.SET_NULL, db_constraint=False)
    author = models.ForeignKey(to='Author', null=True,
    on_delete=models.SET_NULL, db_constraint=False)
    time = models.DateField()

    2.手动创建关系表,用ManyToManyField方式支持ORM连表查询,需要用db_constraint=False断开关联

    to:多对多的关系表

    through:手动建立的关系表

    through_fields:('关系表代表本类的字段名','关系表代表关联类的字段名')class Book(models.Model):

    name = models.CharField(max_length=20)
    author = models.ManyToManyField(to='Author',
    through='Book_Author', through_fields=('book_id', 'author_id'),
    )

    class Author(models.Model):
    name = models.CharField(max_length=20)

    class Book_Author(models.Model):
    book_id = models.IntegerField()
    author_id = models.IntegerField()
    time = models.DateField()

    3、手动创建关系表,在关系表中用ForeignKey方式支持基于外键关系表的ORM连表查询,同时明确ManyToManyField字段,所以也支持ORM正向方向连表查询-- db_constraint=False断开关联可以在ForeignKey或

    ManyToManyField任意一方完成
    class Book(models.Model):
    name = models.CharField(max_length=20)
    # 明确through与through_fields,ManyToManyField才不会自动建立关系表
    author = models.ManyToManyField(to='Author',
    through='Book_Author', through_fields=('book_id', 'author_id'),
    )
    class Author(models.Model):
    name = models.CharField(max_length=20)

    class Book_Author(models.Model):
    book = models.ForeignKey(to="Book", null=True,
    on_delete=models.SET_NULL, db_constraint=False)
    author = models.ForeignKey(to='Author', null=True,
    on_delete=models.SET_NULL, db_constraint=False)
    time = models.DateField()
    '''
    # 总结:手动创建第三张表,第三张表的增删改就采用关系表类名
    衍生的create|delete|update,就不再拥有add|clear|remove|set
    (因为关系表拥有自己的字段,这些方法无法直接操作这些字段)

    db_constraint:是否在数据库中创建外键约束,默认为true

  • 相关阅读:
    中国电信翼聊学习(概述)
    Silverlight应用程序的本地通讯
    XmlSerialize构造函数发生错误FileNotFoundException
    使用 .NET Framework 中的函数式编程技术
    月份统计精简Sql
    poj 2421 Constructing Roads
    POJ 3026 Borg Maze
    POJ 1258 AgriNet
    zoj 1718 Building a Space Station
    zoj 1203 Swordfish
  • 原文地址:https://www.cnblogs.com/suncunxu/p/10491885.html
Copyright © 2011-2022 走看看