Промежуточная таблица Django с полем "многие ко многим" вместо внешнего ключа?
У меня есть 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)
Так что я могу связать много башен с пользователем в определенный период. Но, к сожалению, Джанго говорит, что мне нужно использовать forgeignkey для классов Tower и User.
Есть какое-то решение для этого? Применить непосредственно поле "многие ко многим" в промежуточной таблице? Или я должен создать новый класс, своего рода 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()
Заранее спасибо.
1 ответ
Существует так много способов, которыми вы можете создать базу данных.
Пример:
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_date
, begin_date
а также user
,
А теперь, если вам нужны башни:
user_members = User.objects.get(pk=1).members.all().values_list('tower', flat=True)
towers = Tower.objects.filter(pk__in=user_members).distinct()
Этот дизайн хорошо, только если вы действительно не хотите дубликаты с одинаковыми begin_date
а также begin_date
что я не могу найти причину.
Вы все еще можете иметь все функции, если вы добавите несколько экземпляров с одинаковыми begin_date
, begin_date
а также user
но разные tower
,