zoukankan      html  css  js  c++  java
  • Dango-之多对多关系—基于双下划线的查询

    一对一的反向查询用表名不加_set,一对多的反向查询表名加_set

    前面写了一对多的关系,在这里升级下写下多对多的关系~~

    我们从前面的小项目app01中创建了一对多关系的Publish表,从这里我们在创建个作者表用来进行多对多关系的建立。

    在我们的models.py中:

    from django.db import models
    
    # Create your tests here.
    class Book(models.Model):
        nid=models.AutoField(primary_key=True)
        title=models.CharField(max_length=32)
        pubDate=models.DateField()
        price=models.DecimalField(max_digits=6,decimal_places=2)
        #django会自动给外键字段添加"_id",关联哪个表的字段就写哪个表名,django会自动关联publish表的主键
        publisher=models.ForeignKey("Publish")
        #书籍与作者:多对多

        #创建多对多关联字段语法,关联字段不会在表中显示,django会自动创建一张“应用名_当前表名_关联字段”app01_book_authors
        #与这本书关联的作者对象集合


    authors=models.ManyToManyField("Author") #django如果表没有创建主键,会默认创建一个主键,名字叫id class Publish(models.Model): name = models.CharField(max_length=32) addr = models.CharField(max_length=32) tel = models.BigIntegerField() class Author(models.Model): name=models.CharField(max_length=32) age=models.IntegerField() tel=models.CharField(max_length=32)

    创建Author作者表还是老方法,不一样的地方在于,我们给书籍添加了个orm层的关联字段authors,用来表示这边数据有多个作者。

    我们执行python manage.py makemigrations  python manage.py migrate来数据化新增的字段和表,之后会产生Author表和中间表

     

    可以看到我们创建的作者表,和一张关系表,表中的book_id就是数据表中的nid,author_id便是author表中的id,这样,书籍和作者就关联起来了~~~

    下面进行我们的表关系表的操作。

    多对多的添加

    我们要想给书籍绑定作者,需要拿到书籍对象,然后拿到坐着对象,然后进行关联。
    1、书籍对象:
        book_obj=models.Book.objects.create(title=title)
    2、绑定作者关系
            添加作者关系:
    作者对象:alex=models.Author.objects.get(name="alex")
    #也可以拿到一个作者对象集合:
    author_list=models.Author.objects.all()
    绑定一个对象关系 book_obj.authors.add(alex) 可以通过下面的语法
    绑定多个对象关系 book_obj.authors.add(*author_list)
    显示作者关系: book_obj.authors.all()
    #book对象相关联的作者对象集合

     解除作者关系

    #拿到书对象
    book_obj=models.Book.objects.get(id=1)
    #查看下该书对象关联多少个作者
    print(book_obj.authors.all())
    
    #拿到作者对象
    alex=models.Author.objects.get(name="alex")
    book_obj.authors.remove(alex)
    
    #清空所有作者
    book_obj.authors.clear()

    可以看出我们所有的操作都是通过关联字段authors的方法进行的。

    多对多查询

    多对多的正向查询:查询python这本书的作者的姓名和年龄
    book_obj=Book.models.objects.get(name="python")
    for obj in book_obj.authors.all():
        print(obj.name,obj.age)
    
    
    查询人民出版社出版过的书籍名称及价格
    pub_obj=models.Publish.objects.get(title="remin")
    反向查询书籍
    pub_obj.book_set.all()#与这个出版社关联的所有书籍对象
    for obj in book_list:
        print(obj.title,obj.price)
    
    多对多的反向查询:查询alex出版过的所有书籍的名称
    alex=models.Author.objects.get(name="alex")
    book_list=alex.book_set.all()
    for i in book_list:
        print(i.title)

    完善项目增加作者字段的增改查

    我们最终要实现成这种方式

    首先我们需要在index.html中添加一列作者的显示信息

    很简单,我们只需要在table中添加一个作者标题,在数据显示的地方for循环我们的书对象关联的作者集,然后显示~

     添加功能

    首先我们在view视图中add函数获取到作者列表,然后通过render方法返回给add.html

    然后我们在add.html增加了一些内容

    我们在点击添加之后会多出一个作者的多行可选筐。

     我们遍历作者列表显示作者的名字

    然后通过request.POST.get_list(authors_id)可以从视图函数中获取用户所选择的作者。

    修改功能

    作者列表的修改功能和添加功能类似

    首先我们传authors对象给edit.html

    然后

     进行显示并进行默认值设置,把作者id发送给模板,模板进行判断如果在作者列表中,变添加selected。

    基于双下划线的查询

    查询python这本书的出版社的名称和地址
    基于双下划线,双下划线相当于跨表
    models.Book.objects.filter(title="python").values("publisher__name")
    等同于
    book_obj=models.Book.object.filter(title="python")
    for obj in book_obj:
        obj.publisher.name
    
    反向双下划线查询
    models.Publish.objects.filter(book__title="python").values_list("name","addr")
    查询人民出版社出版过的所有书籍名称及价格
    models.Book.objects.filter(publisher__name="renmin").values_list("title","price")
    
    #正向
    models.Publish.objects.filter(name="remin").values("book__title","book_set__price")
    #查询egon出过的所有书籍的名字(多对多)
    models.Author.objects.get(name="egon").values("book__title")
    models.Book.objects.filter(authors__name__contains="egon").values("title")

    #地址以沙河开头的作者出版过的所有书籍和出版社名称
    models.Book.objects.filter(authors__addr__startwith("沙河")).values("title","publisher__name")
  • 相关阅读:
    设计模式学习笔记——Bridge 桥接模式
    设计模式学习笔记——Adapter 适配器模式
    protoc protobuff安装
    docker-compose启动consul
    docker etcd 环境搭建
    nifi的去重方案设计(二)-外部存储mysql全局去重
    实现一套ES全文检索语法-到Lucene语法的转换工具,以实现在es外部兼容处理文本分词
    nifi的去重方案设计(一)-单队列内去重.md
    k8s 证书过期处理
    部分项目从kafka迁移至pulsar,近期使用中碰到了一些问题,勉强把大的坑踩完了,topic永驻,性能相关
  • 原文地址:https://www.cnblogs.com/kunixiwa/p/7896006.html
Copyright © 2011-2022 走看看