Django中间表用多对多字段代替外键?

问题描述 投票:1回答:1

我的应用程序中有2个模型:

  • 用户

我的目标是使用中间表将多个塔关联到用户,因为我需要添加一段时间。

所以我的模型中有这样的东西:

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

class User(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField('Tower', through='Dates')

class Dates(models.Model):
    user = models.ForeignKey('User', on_delete=models.CASCADE)
    tower = models.ForeignKey('Tower', on_delete=models.CASCADE)
    begin_date = models.DateTimeField()
    end_date = models.DateTimeField()

但我的目标是让课堂日期达到多对多,如下所示:

tower = models.ManyToManyField('Tower', blank=True)

这样我就可以在一定时期内将许多塔与用户联系起来。但不幸的是django说我需要使用forgeignkey来塔和用户类。

有什么解决方案吗?直接应用中间表中的多对多字段?或者我必须创建一个新的类,一个GroupTower,它具有Tower类的多对多字段?像这样的东西:

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

class GroupTower(models.Model):
    tower = models.ManyToManyField('Tower', blank=True)

class User(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField('Tower', through='Dates')

class Dates(models.Model):
    user = models.ForeignKey('User', on_delete=models.CASCADE)
    tower = models.ForeignKey('GroupTower', on_delete=models.CASCADE)
    begin_date = models.DateTimeField()
    end_date = models.DateTimeField()

提前致谢。

django many-to-many django-database django-intermediate-table
1个回答
0
投票

您可以通过多种方式设计数据库。

一个例子:

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

class User(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField('UserTower')

class UserTower(models.Model):
    user = models.ForeignKey('User', on_delete=models.CASCADE)
    tower = models.ManyToManyField('Tower')
    begin_date = models.DateTimeField()
    end_date = models.DateTimeField()

在此设计中,您可以向用户添加许多UserTower实例,每个UserTower实例可以包含许多塔。

现在,如果您查询用户的成员:

User.objects.get(pk=1).members.all()

如果您以这种方式保存它们,您将按时间段对成员进行分组,但它需要您编写一些代码以避免重复begin_datebegin_dateuser

现在,如果你需要塔楼:

user_members = User.objects.get(pk=1).members.all().values_list('tower', flat=True)
towers = Tower.objects.filter(pk__in=user_members).distinct()

只有当你真的不希望重复使用相同的begin_datebegin_date时,我才能找到合理的设计。

如果添加多个具有相同begin_datebegin_dateusertower不同的实例,您仍然可以拥有所有功能。

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