Промежуточная таблица Django с полем «многие ко многим» вместо внешнего ключа? - PullRequest
1 голос
/ 28 марта 2019

В моем приложении 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 Ответ

0 голосов
/ 28 марта 2019

Существует так много способов создания базы данных.

Пример:

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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...