zoukankan      html  css  js  c++  java
  • Django框架 之 ORM中介模型

    中介模型

    处理类似搭配 pizza 和 topping 这样简单的多对多关系时,使用标准的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)
        group = models.ForeignKey(Group)
        date_joined = models.DateField()
        invite_reason = models.CharField(max_length=64)
    

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

    >>> ringo = Person.objects.create(name="Ringo Starr")
    >>> paul = Person.objects.create(name="Paul McCartney")
    >>> beatles = Group.objects.create(name="The 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模型中所需要的所有信息;而简单的addcreate 和赋值语句是做不到这一点的。所以它们不能在使用中介模型的多对多关系中使用。此时,唯一的办法就是创建中介模型的实例。

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

    >>> # Beatles have broken up
    >>> beatles.members.clear()
    >>> # Note that this deletes the intermediate model instances
    >>> Membership.objects.all()
    []
    

     

  • 相关阅读:
    前台调用后台方法循环绑定数据到前台
    禁用绑定在Repeater的控件
    Repeater,ItemDataBound事件,获取绑定列的值,给指定列添加js方法
    Oracle定时值执行存储过程
    A页面跳到B页面,B页面获取A页面的URL
    Jquery获取用户控件页面中控件的值
    Web页面获取用户控件页面中服务器控件的值
    springmvc静态资源;mvc:default-servlet-handler后Controller失效
    创建 Angular 8.0 项目
    window location跳转
  • 原文地址:https://www.cnblogs.com/gaoya666/p/8877131.html
Copyright © 2011-2022 走看看