• Django


    一、中介模型

      我们之前学习图书管理系统时,设计了Publish、Book、Author、AuthorDetail这样几张表,其中Book表和Author表是多对多关系,处理类似这样简单的多对多关系时,使用标准的ManyToManyField就可以了。但是,有时你可能需要关联数据到两个模型之间的关系上。

      例如,有这样一个应用,它记录音乐家所属的音乐小组。我们可以用一个ManyToManyField 表示小组和成员之间的多对多关系。但是,有时你可能想知道更多成员关系的细节,比如成员是何时加入小组的。

      对于这些情况,Django 允许你指定一个中介模型来定义多对多关系。 你可以将其他字段放在中介模型里面。原模型的ManyToManyField 字段将使用through 参数指向中介模型。对于上面的音乐小组的例子,代码如下:

      from django.db import models
    
      class Person(models.Model):
          name = models.CharField(max_length=128)
    
          def __str__(self):  # __unicode__ on Python 2
              return self.name
    
    
      class Group(models.Model):
          name = models.CharField(max_length=128)
          members = models.ManyToManyField("Person", through='Membership')
    
          def __str__(self):  # __unicode__ on Python 2
              return self.name
    
    
      class Membership(models.Model):
          person = models.ForeignKey("Person", on_delete=models.CASCADE)
          group = models.ForeignKey("Group", on_delete=models.CASCADE)
          date_joined = models.DateField()
          invite_reason = models.CharField(max_length=64)

      既然你已经设置好ManyToManyField 来使用中介模型(在这个例子中就是Membership),接下来你要开始创建多对多关系。你要做的就是创建中介模型的实例:

      >>> ringo = Person.objects.create(name="Ringo Starr")   # 创建一个音乐家ringo
      >>> paul = Person.objects.create(name="Paul McCartney") # 创建一个音乐家paul
      >>> beatles = Group.objects.create(name="The Beatles") # 创建一个音乐小组beatles
      >>> m1 = Membership(person=ringo, group=beatles,
      ...     date_joined=date(1962, 8, 16),
      ...     invite_reason="Needed a new drummer.")   # 创建一个中介模型的实例
      >>> m1.save()
      >>> beatles.members.all()  # 多对多的正向查询语法
      [<Person: Ringo Starr>]
      >>> ringo.group_set.all()  # 多对多的反向查询语法
      [<Group: The Beatles>]
      >>> m2 = Membership.objects.create(person=paul, group=beatles,
      ...     date_joined=date(1960, 8, 1),
      ...     invite_reason="Wanted to form a band.") # 创建一个中介模型的实例
      >>> beatles.members.all()   # 多对多的正向查询语法
      [<Person: Ringo Starr>, <Person: Paul McCartney>]  

      注意:与普通的多对多字段不同,不能使用add、create和赋值语句(比如,beatles.members = [...])来创建关系:

      # THIS WILL NOT WORK
      >>> beatles.members.add(john)
      # NEITHER WILL THIS
      >>> beatles.members.create(name="George Harrison")
      # AND NEITHER WILL THIS
      >>> beatles.members = [john, paul, ringo, george]

      为什么不能这样做?这是因为你不能只创建 Person和 Group之间的关联关系,你还要指定 Membership模型中所需要的所有信息(比如date_joinedinvite_reason);而简单的add、create 和赋值语句是做不到这一点的。所以它们不能在使用中介模型的多对多关系中使用。此时,唯一的办法就是创建中介模型的实例。

      remove()方法被禁用也是出于同样的原因。但是clear()方法却是可用的。它可以清空某个实例所有的多对多关系:

      # Beatles have broken up
      >>> beatles.members.clear()
      # Note that this deletes the intermediate model instances
      >>> Membership.objects.all()
      []
    
  • 相关阅读:
    艾伟:WCF中通过Dispose有效实现重用 狼人:
    艾伟:用 IIS 7、ARR 與 Velocity 建置高性能的大型网站 狼人:
    艾伟:表达式树和泛型委托 狼人:
    艾伟:jQuery性能优化指南(2) 狼人:
    艾伟:在Windows Mobile上实现自动拼写和匹配建议 狼人:
    艾伟:Web.config配置文件详解 狼人:
    艾伟:对 String 的几个错误认识 狼人:
    艾伟:ASP.NET安全问题--Forms验证的具体介绍(上篇) 狼人:
    艾伟:基于web信息管理系统的权限设计分析和总结 狼人:
    艾伟:[你必须知道的.NET]第三十一回,深入.NET 4.0之,从“新”展望 狼人:
  • 原文地址:https://www.cnblogs.com/li-li/p/10009624.html
Copyright © 2020-2023  润新知