• orm多表操作


    一.创建表

    1.一对多

            必须在"多"的表中创建关联字段,在外加约束
    class Book(models.Model):
    id=models.AotuField(primary_key=True)
    title=models.CharField(max_length=32)
    publish=models.ForeignKey(to='Publish',on_delete=models.CASCADE)

    注:正常为字段起名即可,Django会默认为外键属性拼接_id,以此作为表的字段
    to对应的是关联的表

    2.一对一

            可以在任意表中创建关键字段,Django默认为其加上唯一约束
    class Author(models.Model):
    id=models.AutoField(primary_key=True)
    name=models.CharField(max_length=32)
    ad=models.OneToOneField(to='AuthorDetail',on_delete=models.CASCADE)

    3.多对多

            class Book(models.Model):
    id=models.AotuField(primary_key=True)
    title=models.CharField(max_length=32)
    authors=models.ManyToMany(to='Author')

    注:Django对默认为其创建第三张表
    第三张表的表名为:此表表名(小写)_创建多对多的字段
    第三张表的字段为 id,此表表名_id,关联表表名_id
    注:用Django创建表时,不加id字段会被默认添加
    外键字段有一个null=True的设置,表示允许外键为空值

    二.对表记录的操作

    1.填加表记录

            (1)一对多
    方式1:
    Book.objects.create(title='王八蛋啥时候来',pub_date='2012-12-12',price=12,publish_id=1)
    此处的1代表'一'表中的主键值为1
    方式2:
    publish_obj=publish.objects.get(id=1)
    Book.objects.create(title='王八蛋啥时候来',pub_date='2012-12-12',price=12,publish=publish_obj)
    注:如果直接用数字,要用表的字段值 publish_id
    如果用'一'表对象,要用类的属性 publish
    (2)多对多
    a.生成书籍对象
    book_obj=Book.objects.create(title='王八蛋啥时候来',pub_date='2012-12-12',price=12,publish_id=1)
    b.为书籍对象绑定作者
    shy=Author.objects.filter(name='shy').first()
    jwb=Author.objects.filter(name='jwb').first()
    c.向关系表book_authors中添加纪录
    方式1:book_obj.authors.add(shy,jwb)
    方式2:book_obj.authors.add(1,2)
    方式3:book_obj.authors.add(*[1,2])

    其他方法:
    book_obj.authors.remove() # 将某个特定的对象从被关联对象集合中去除。 (book_obj.authors.remove(*[]))
    book_obj.authors.clear() #清空被关联对象集合
    book_obj.authors.set() #先清空再设置 

    2.查询表记录

            注:正向查询与反向查询
    正向查询:关联属性所在的表查询关联表记录
    反向查询:关联表查询关联属性所在的表记录
    (1)基于对象的跨表查询
    一对多
    正向查询按字段:book.publish
    Book----------------------------------------->Publish
    反向查询按表名小写+_set.all():publish.book_set.all()

    正向查询例:查询python这本书出版社的名字和邮箱
    book_obj=Book.objects.filter(title='python').first()
    publish_obj=Publish.objects.filter(id=book_obj.publish).first().values('name','email')
    反向查询例:查询人民出版社出版的所有书籍的名称
    publish_obj=Publish.objects.filter(name='人民出版社').first()
    print(publish_obj.book_set.all())
    多对多
    正向查询按字段:book.authors.all()
    Book----------------------------------------->Publish
    反向查询按表名小写+_set.all():author.book_set.all()
    正向查询例:查询python这本书作者的名字
    book_obj=Book.objects.filter(title='python').first()
    print(book_obj.authors.all().values('name'))
    反向查询例:查询shy出版过的所有书籍的名称
    author_obj=Author.objects.filter(name='shy').first()
    print(author_obj.book_set.all().values('title'))
    一对一
    正向查询按字段:author.ad
    Book---------------------------------------->Publish
    反向查询按表名小写:authordetail.author
    正向查询例:查询shy的手机号
    author_obj=Author.objects.filter(name='shy').first()
    print(author_obj.ad.tel)
    反向查询例:查询地址为北京的作者
    authordetail_obj=AuthorDetail.objects.filter(addr='北京')
    print(authordetail_obj.author)
    (2)基于双下划线的跨表查询
    基于双下划线的单次跨表查询
    语法:正向查询按字段,反向查询按表名小写

    一对多查询
    正向查询例:查询本草纲目这本书出版社的名字
    Book.objects.filter(title='本草纲目').values('publish__name')
    正向查询例:查询北京出版社出版的所有书籍的名称与价格
    Publish.objects.filter(name='北京出版社').values('book__title','book__price')

    多对多查询
    正向查询例:查询皇帝的新装这本书的作者和年龄
    Book.objects.filter(title='皇帝的新装').values('authors__age')
    反向查询例:查询尚宏运出版过的所有书籍的名字
    Author.objects.filter(name='尚宏运').values('book__title')

    一对一查询
    正向查询例:查询尚宏运的手机号
    Author.objects.filter(name='尚宏运').values('ad__tel')
    反向查询例:查询手机号为123456的作者
    AuthorDetail.objects.filter(author__name='尚宏运').values('tel')
    基于双下划线的连续跨表查询:
    例查询北京出版社出版过的所有书籍的名字及作者的名字
    方式1:
    Publish.objects.filter(name='北京出版社').values('book__title','book__authors__name')
    方式2;
    Book.objects.filter(publish__name='北京出版社').values('title','authors__name')
    方式3:
    Author.objects.filter(book__publish__name='北京出版社').values('book__title','name')
    (3)聚合和分组查询
    聚合:
    注:使用聚合函数前先引入
    from django.db.models import Avg,Max,Sum,Min,Count
    例:查询所有书籍的平均价格
    Book.objects.all().aggregate(avg_price=Avg('price'))
    分组:
    语法:annotate()前values哪个字段,就用哪个字段进行分组,在annotate后的括号中使用聚合函数

    单表分组查询
    例:查询每一个部门对应员工的平均薪水
    Emp.obj.values('dep').annotate(Avg('salary'))
    跨表分组查询
    例:查询每一个出版社的名称以及出版的书的平均价格
    Publish.objects.values('name').annotate(Avg('book__price'))
    简便写法:
    例:查询每一个出版社的名称,以及对应书籍的平均价格
    方式1:
    Publish.objects.values('name').annotate(avg_price=Avg('book__price'))
    方式2:
    Publish.objects.all().annotate(avg_price=Avg('book__price')).values('name','avg_price')
    方式3:
    Publish.objects.annotate(avg_price=Avg('book__price')).values('name','avg_price')
    注:使用聚合函数时,最好另起别名
    (4)F与Q查询
    注:使用F和Q查询前需要先引入
    from django.db.models import F,Q
    F查询
    例:查询评论数大于点赞数的所有书籍的名称
    Book.objects.filter(comment_count__gt=F('poll_count')).values('title')
    给每一本书的价格提升100
    Book.objects.all().values(price=F('price')+100)
    Q查询
    当查询的条件中存在与(&)或(|)非(~)时,使用Q查询
    例:查询价格大于300或评论数大于3000的书籍
    Book.objects.filter(Q(price__gt=300)|Q(comment__count__gt=3000))
    查询价格大于100,或者不是尚宏运写的书
    Book.objects.filter(Q(price__gt=100)|~Q(authors__name='尚宏运')).values('title')

  • 相关阅读:
    JS创建类的方法--简单易懂有实例
    CommonJS, AMD, CMD是什么及区别--简单易懂有实例
    JS回调函数--简单易懂有实例
    单链表应用(2)--使用快慢指针,如何判断是否有环,环在哪个节点
    单链表应用(1)--使用快慢指针,找链表中间值
    自定义线性结构-有序Map
    C++中final和override
    双向链表翻转
    检查“()”是否匹配并返回深度
    是否存在K
  • 原文地址:https://www.cnblogs.com/shanghongyun/p/9843944.html
Copyright © 2020-2023  润新知