Django中间表具有多对多字段而不是外键?

时间:2019-03-28 14:58:23

标签: django many-to-many django-database django-intermediate-table

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

  • 用户

我的目标是使用中间表将许多塔与用户相关联,因为我需要增加一段时间。

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

grepl("matt", c( "matt","joe","liz","", NA))

#[1]  TRUE FALSE FALSE FALSE FALSE

但是我的目标是让“ Date”类的现场发射塔像这样多对多:

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()

以便我可以在特定时期内将许多塔与用户关联。但是不幸的是,django说我需要对塔和用户类使用forgeignkey。

对此有什么解决方案吗?要直接在中间表中应用多对多字段?还是我必须创建一个新的类,例如GroupTower,它对Tower类具有多对多字段?像这样:

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

谢谢。

1 个答案:

答案 0 :(得分: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_dateuser但具有不同tower的实例,您仍然可以拥有所有功能。