Django中3个表之间的多对多关系

问题描述 投票:0回答:2

我有以下型号:

class Project(models.Model):
    project_name = models.CharField(max_length=50)
    project_users = models.ManyToManyField('Users.UserAccount', related_name='project_users', blank=True)
    ....

class UserAccount(AbstractBaseUser, PermissionsMixin):
    username = models.CharField(max_length=30, unique=True)
    ....

class Discipline(models.Model):
    name = models.CharField(unique=True, max_length=27, choices=discipline_choices)

project_users
的数据库表如下所示:

*--------*----------------*---------------------*
|   ID   |   project_id   |   user_account_id   |
*--------*----------------*---------------------*

我想在

project_users
字段/表中与
Discipline
模型建立额外的关系。这在 Django 中可能吗?我一直在研究 Django 中的“中介多关系”,但这并不是我想要的。在我的应用程序中,有一定数量的学科,我想要实现的是在单个项目中为每个用户提供多个学科。所以像这样: *--------*----------------*---------------------*-------------------* | ID | project_id | user_account_id | discipline_id | *--------*----------------*---------------------*-------------------*

这可能吗?

python django many-to-many
2个回答
5
投票
ManyToManyField

在幕后所做的事情:在两者之间创建一个模型。

class UserProjectDiscipline(models.Model):
    user_account = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE
    )
    project = models.ForeignKey(
        Project,
        on_delete=models.CASCADE
    )
    discipline = models.ForeignKey(
        Discipline,
        on_delete=models.CASCADE
    )

您现在可以使用 
UserProjectDiscipline

UserAccount
Project
访问
Discipline
myuser.userprojectdiscipline_set.all()
和/或
myproject.userprojectdiscipline_set.all()
mydiscipline.userprojectdiscipline_set.all()
此外,您可以定义跨越该表的

ManyToManyField

,这样就可以轻松获取

Project
的相关
Discipline
等,使用:
class Project(models.Model):
    project_name = models.CharField(max_length=50)
    users = models.ManyToManyField(
        'Users.UserAccount',
        through='UserProjectDiscipline',
        related_name='projects',
        blank=True
    )
    disciplines = models.ManyToManyField(
        'Discipline',
        through='UserProjectDiscipline',
        related_name='projects',
        blank=True
    )
    # …

class UserAccount(AbstractBaseUser, PermissionsMixin):
    username = models.CharField(max_length=30, unique=True)
    disciplines = models.ManyToManyField(
        'Discipline',
        through='UserProjectDiscipline',
        related_name='users',
        blank=True
    ) 
    # …

然后,这些将在 
UserProjectDiscipline

的表上进行联接,以有效检索给定项目的用户等。如果您需要

UserProjectDiscipline
的对象,您仍然可以使用例如
myproject.userprojectdiscipline_set.all()
如果您想为用户

myuser

给定项目

myproject
三个学科,您可以添加这些:
UserProjectDiscipline.objects.bulk_create([
    UserProjectDiscipline(user_account=myuser, project=my_project, discipline=mydiscipline1),
    UserProjectDiscipline(user_account=myuser, project=my_project, discipline=mydiscipline2),
    UserProjectDiscipline(user_account=myuser, project=my_project, discipline=mydiscipline3)
])



0
投票

© www.soinside.com 2019 - 2024. All rights reserved.