Промежуточная таблица 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,

Другие вопросы по тегам