1. 本际云推荐 - 专业推荐VPS、服务器,IDC点评首页
  2. 云主机运维
  3. VPS运维

Django细腻解读多对多使用through自定中间表方法

介绍

本际云服务器推荐网的小编小本本在这里给大家介绍一下Django多对多中间表的使用。

Django细腻解读多对多使用through自定中间表方法

多对多中间表详细说明

在搭建网站时,设计方案完成用户系统十分必要,包括新用户注册、账号登录、用户认证以及销户等服务。Django作为完美主义者最终架构,它默认使用auth_user表来存储用户数据信息,其在Group模型中通过members字段,以ManyToMany的方式和Person建立模型关联。这里我们需要了解中间表的应用,可通过以下实例说明。

默认设置中间表

默认情况下,Django使用的是下一张中间表的形式来关联ManyToMany的彼此。我们以以下代码为例:

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

上述代码中的Group模型中,依据members字段,以ManyToMany的方式和Person建立模型了关联。我们可以看到中间表是一个类似于下面的形式:

ID | person_id | group_id
----------------------------
1    |     1              |     1
2    |     2              |     2
3    |     1              |     2
4    |     3              |     1
5    |     1              |     3
6    |     3              |     2

从中间表的形式可以看出,在中间表中,并不是将二张表中数据储存在一块,而是用id的关联开展投射。如果需要设定关联列,可以使用to_field主要参数。

依据through自定义中间表

在一般情况下,普通多对多已经足够,不用自己建立下一张关系图。但某些情况下,可能需要更加复杂的设计,例如储存某些人添加某一分类的时间,如何储存接戏的原因等。Django带来了一个through参数,用以特定在中间实体模型上设定其它字段名,如下实例所示:

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)#邀请原因

从Membership角度,他是建立了到两个模型(Group,Person)的多对1关系,Django在启动时,会自动在其关联的模型上建立”[model]_set”的属性。例:在Person模型上调用Membership,可使用person.membership_set查看group下的所有关系;在Group模型上使用membership_set.get查看person下的所有Membership。因此在使用through参数时,可以将其它需要的字段名放到这一正中间实体模型内。

最后,值得注意的是,此例代码中的view和serializer在此处省略,请根据实际情况使用。

原创文章,作者:小编小本本,如若转载,请注明出处:https://www.benjiyun.com/yunzhujiyunwei/vps-yunwei/6795.html