多对多类型的表ManyToManyField怎样增加额外字段

https://docs.djangoproject.com/en/2.0/topics/db/models/#extra-fields-on-many-to-many-relationships


Extra fields on many-to-many relationships

When you’re only dealing with simple many-to-many relationships such asmixing and matching pizzas and toppings, a standardManyToManyField is all you need. However, sometimesyou may need to associate data with the relationship between two models.

For example, consider the case of an application tracking the musical groupswhich musicians belong to. There is a many-to-many relationship between a personand the groups of which they are a member, so you could use aManyToManyField to represent this relationship.However, there is a lot of detail about the membership that you might want tocollect, such as the date at which the person joined the group.

For these situations, Django allows you to specify the model that will be usedto govern the many-to-many relationship. You can then put extra fields on theintermediate model. The intermediate model is associated with theManyToManyField using thethrough argument to point to the modelthat will act as an intermediary. For our musician example, the code would looksomething like this:

from django.db import models

class Person(models.Model):
    name = models.CharField(max_length=128)

    def __str__(self):
        return self.name

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person, through='Membership')

    def __str__(self):
        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)

When you set up the intermediary model, you explicitly specify foreignkeys to the models that are involved in the many-to-many relationship. Thisexplicit declaration defines how the two models are related.

There are a few restrictions on the intermediate model:

  • Your intermediate model must contain one - and only one - foreign keyto the source model (this would be Group in our example), or you mustexplicitly specify the foreign keys Django should use for the relationshipusing ManyToManyField.through_fields.If you have more than one foreign key and through_fields is notspecified, a validation error will be raised. A similar restriction appliesto the foreign key to the target model (this would be Person in ourexample).
  • For a model which has a many-to-many relationship to itself through anintermediary model, two foreign keys to the same model are permitted, butthey will be treated as the two (different) sides of the many-to-manyrelationship. If there are more than two foreign keys though, youmust also specify through_fields as above, or a validation errorwill be raised.
  • When defining a many-to-many relationship from a model toitself, using an intermediary model, you must usesymmetrical=False (seethe model field reference).

Now that you have set up your ManyToManyField to useyour intermediary model (Membership, in this case), you’re ready to startcreating some many-to-many relationships. You do this by creating instances ofthe intermediate model:

>>> 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()
<QuerySet [<Person: Ringo Starr>]>
>>> ringo.group_set.all()
<QuerySet [<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()
<QuerySet [<Person: Ringo Starr>, <Person: Paul McCartney>]>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值