多对多查询

 

一丶多对多查询

表建立多对多关系的方式

django通过ManyToManyField自动创建第三张表

# 1 . django通过ManyToManyField自动创建第三张表
class Book(models.Model):
   title = models.CharField(max_length=32)
   pub = models.ForeignKey('Publisher', on_delete=models.CASCADE)
   # authors = models.ManyToManyField('Author') # 描述多对多的关系   不生成字段 生成关系表

   def __repr__(self):
       return self.title

   __str__ = __repr__

class Author(models.Model):
   name = models.CharField(max_length=32)
   books = models.ManyToManyField('Book')  # 描述多对多的关系   不生成字段 生成关系表

手动创建第三张表

class Book(models.Model):
   title = models.CharField(max_length=32)


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


class Book_Author(models.Model):
   book = models.ForeignKey(Book, on_delete=models.CASCADE)
   author = models.ForeignKey(Author, on_delete=models.CASCADE)
   date = models.DateField()

自己创建 + ManyToManyField(仅限查询)

# 使用 手动创建第三章表和 ManyToMany字段时. ManyToMany的set功能可能不会更好的应用,当第三张表存在其他的字段不能通过set设置值.

class Book(models.Model):
   title = models.CharField(max_length=32)

class Author(models.Model):
   name = models.CharField(max_length=32)
   books = models.ManyToManyField(Book, through='Book_Author') # through : 表示通过那张表,
  # through_filed: 表示通过这张表哪个字段 ,有顺序


class Book_Author(models.Model):
   book = models.ForeignKey(Book, on_delete=models.CASCADE)
   author = models.ForeignKey(Author, on_delete=models.CASCADE)
   date = models.DateField()  # 不能通过ManyToMany字段的set设置值

查询

# python后端
all_authors = models.Author.objects.all().order_by('id')

for author in all_authors:
   print(author)
   print(author.name)
   print(author.pk)
   print(author.books)  # 关系管理对象
   print(author.books.all())  # 查询所有的,所关联的所有对象

# html前端
{% for author in all_author %}     ## 循环得到每个作者对象
   <tr>
       <td>
           <input type="checkbox" >
       </td>
       <td>{{ forloop.counter }}</td>
       <td>{{ author.pk }}</td>
       <td>{{ author.username }}</td>
       <td>
# book_obj 是从后端传递过来的对象,
# author.books.all 是通过查询 Author表中的books属性获得一个关系管理对象,
# .all 在前端页面不用加括号 ,查询到的是每一个book图书对象.
          {% for book_obj in author.books.all  %}
               &nbsp;&nbsp;&nbsp;<< {{ book_obj.bname }}>>
          {% endfor %}

       </td>
       <td><a class="btn btn-warning btn-sm" href="/author_edit?pk={{ author.pk }}">编辑</a>             <a class="btn btn-danger btn-sm" href="/author_del?pk={{ author.pk }}">删除</a>
       </td>
   </tr>
{% endfor %}

新增

# python后台 request接收前端发过来的数组类型的数据. 使用getlist()
books = request.POST.getlist('books')   # 获取多个元素

# 新建作者
author_obj = models.Author.objects.create(name=name)
# 给作者和书籍绑定关系
author_obj.books.set(books) # 【id,id】   # 关系管理对象使用set方法,自动循环插入数据

反查询

通过设置ManyToMany字段对应的那张表.

# 多对多
class Book(models.Model):
   bname = models.CharField(max_length=32, unique=True)
   bprice = models.CharField(max_length=32)
   pid = models.ForeignKey('Publish', on_delete=models.CASCADE)
   # 外键参数说明:
   # to_field :被关联对象的用于关联的字段. 默认情况, Django 使用被关联对象的主键
   # on_delete :   models.CASCADE 级联删除
                   # models.SET(1) 将当前字段的值设置成1
                   # models.SET_DEFAULT 设置默认值, 需要设置default:default=11
                   # models.SET_NULL 设置为空,需要设置 : null=True
                   # models.DO_NOTHING 什么都不做,关联的数据删除后不影响当前字段的值


class Author(models.Model):
   username=models.CharField(max_length=32)
   books=models.ManyToManyField('Book') # 设置了多对多关系, 对应的是book对象

# 前端页面,通过book对象反查作者表中的数据 , book.author_set是一个关系管理对象
<!--反查: book.author_set.all -->
    {% for author in book.author_set.all %}
        {{ author.username }}
    {% endfor %}

 

posted on 2020-03-02 12:07  向往1  阅读(374)  评论(0编辑  收藏  举报

导航

……