• 多表查询


    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

  • 相关阅读:
    poj 3243 Clever Y(BabyStep GiantStep)
    poj 2417 Discrete Logging
    poj 3481 Double Queue
    hdu 4046 Panda
    hdu 2896 病毒侵袭
    poj 1442 Black Box
    hdu 2815 Mod Tree
    hdu 3065 病毒侵袭持续中
    hdu 1576 A/B
    所有控件
  • 原文地址:https://www.cnblogs.com/suncunxu/p/10491885.html
Copyright © 2020-2023  润新知