#django #database-design #django-models
#django #проектирование базы данных #django-модели
Вопрос:
Я работаю над дизайном для некоторых моделей в Django и хотел бы получить несколько советов. У меня есть модель для команд, частью которых могут быть многие пользователи. Пользователи также могут быть членами многих команд, но они не могут быть членами одной команды дважды. Существует также отдельная информация, которую я хочу отслеживать для каждой группы команд / пользователей. Кроме того, для каждой команды будет пользователь, который является «администратором», но у каждой команды может быть только один администратор. У меня есть несколько сокращенных определений модели данных следующим образом:
class Team(models.Model):
name = models.CharField()
members = models.ManyToManyField(User, through='Membership')
admin = models.ForeignKey(User)
class Membership(models.Model):
user = models.ForeignKey(User)
team = models.ForeignKey(Team)
extra_data = models.CharField()
Итак, я предполагаю, что мои два вопроса:
1) как бы мне сделать так, чтобы в модели членства ни одна комбинация пользователя и команды не появлялась более одного раза?
2) Есть ли лучший способ обозначить администратора в команде, убедившись при этом, что в каждой команде был только один администратор? Похоже, что если я сохраняю администратора таким образом, применяя при этом правило наличия только одного администратора, становится слишком громоздким запрашивать всех членов команды, поскольку администратора не будет в таблице членства. И если они хранятся в membership, мне пришлось бы выполнить другой запрос, чтобы узнать, являются ли они администраторами этой команды или нет. Мысль об использовании поля «is_admin» в членстве пришла мне в голову, но я не уверен, как сохранить ограничения в 1 администратора на команду.
Любая помощь была бы очень признательна.
ОБНОВЛЕНИЕ: похоже, что мета-тег unique_together — это то, что я ищу в первом вопросе. Мне все еще интересно узнать о втором….
Комментарии:
1. Я думаю, вы правы, что отношения администратора основаны на командной модели. Это наиболее подходящее место для этого с точки зрения характера отношений. API набора запросов позволяет вам получать практически все, что вы хотите, обычно с минимальным количеством запросов.
Ответ №1:
Первый вопрос:
Вы можете добавить ограничение, чтобы предотвратить это:
class Membership(models.Model):
user = models.ForeignKey(User)
team = models.ForeignKey(Team)
extra_data = models.CharField()
class Meta:
unique_together = (('user','team'),)
Второй вопрос (ы):
Вы могли бы добавить поле ранжирования в модель членства и сделать ‘user’ и ‘rank’ unique_together полями с положительным целым числом. И пользователь с rank == 1
является администратором. Или аналогичный. Это обеспечит соблюдение вашей схемы, но может быть громоздким для кодирования ее обслуживания. Возможно, вам будет лучше с тем, что у вас есть.
Комментарии:
1. Спасибо за помощь. Я только что закончил редактировать свой пост, касающийся unique_together, когда увидел, что вы ответили.
Ответ №2:
В ответ на ваш второй вопрос:
Почему бы вам не включить администратора в m2m участников команды?
Когда вы хотите, чтобы вся команда, включая администратора:
some_team.members
Сохранение администратора fk в командной модели имеет смысл, когда вы хотите, чтобы администратор мог использовать:
some_team.admin
и когда вам нужна команда без администратора, вы можете использовать:
some_team.members.exclude(pk = some_team.admin.pk)
Комментарии:
1. Моя единственная проблема с этим подходом заключалась в том, как обеспечить, чтобы при создании команды и добавлении администратора они также добавлялись в команду в качестве участника. На странице регистрации команды это достаточно легко реализовать, но я немного беспокоился о командах, созданных через другие интерфейсы (например, admin), которые должны полагаться на пользователей, добавляющих их вручную.
2. Возможно, это хорошее место для перезаписи метода сохранения team и автоматического добавления администратора в качестве первого члена команды?