Скажем, у меня есть модель User в django, и я хочу добавить пользователям некоторые достижения. Итак, я создал модель Achieve:
class Achive:
type = ....
value = ....
status = BooleanField(default=False)
Я хочу, чтобы все эти достижения были статическим набором моделей для каждого пользователя (например, 20 экземпляров) с возможностью удалять старые и создавать новые. Проблема в том, как это сделать. Ожидаемый поток:
1) пользователю разрешено использовать систему достижений;
2) пользователь получил все достижения (в админке отображается в виде таблицы);
3) в панели администратора для каждого пользователя я могу изменить статус каждого достижения (влияет только на редактируемого пользователя);
4) если создается новый экземпляр Achieve - добавить ко всем пользователям, у которых есть достижения;
5) если существующий экземпляр Achieve был удален - удалить у всех пользователей;
Решения, которые я придумал:
1) используйте модель Achieve с jsonfield. store достигается в json, как словарь, используйте настраиваемый виджет для панели администратора, чтобы отображать флажки для изменения статуса). Но где хранить глобальный набор достижений для создания новых / удаления старых? как с этим справиться?
2) используйте поле многие ко многим для достижения и достижения модели без статуса. Почему: если существует связь между User ← → Achieve, это означает, что пользователь зарабатывает достижение.
Оба решения мне не очень нравятся, поэтому надеюсь на ваш совет.
P.S. sqlite используется как db и не может использовать другой (например, mongo и т. д.)
Заранее спасибо!
@dirkgroten Думаю, это решит мою проблему. Не могли бы вы оставить свой комментарий в качестве ответа, чтобы я мог отметить его как правильный?





Вам нужна связь ManyToMany между Achieve и User, но с возможностью хранения дополнительных данных об этой связи (например, status).
Используя обычный ManyToManyField в модели, Django фактически создает промежуточную модель для хранения взаимосвязей в базе данных. Добавив аргумент through к вашему ManyToManyField, вы можете указать промежуточную модель, используемую для отношения, и сохранить дополнительные данные с отношением, как задокументировано здесь:
class Goal(models.Model):
type = ...
value = ...
achievers = models.ManyToManyField(to=User, through='Achievement', related_name='goals')
class Achievement(models.Model):
status = models.BooleanField()
date_reached = models.DateField(null=True)
goal = models.ForeignKey(to=Goal, on_delete=models.CASCADE)
achiever = models.ForeignKey(to=User, on_delete=models.CASCADE)
тогда вы можете создать и запросить такие отношения, если у вас есть user и goal:
achievement = Achievement.objects.create(status=True, date_reached=date(2018, 10, 12), achiever=user, goal=goal)
user.goals.filter(achievement__status=True) # gives the achieved goals of a user
goal.achievers.filter(achievement__status=True) # gives the users that achieved a goal
Посмотрите на отношения ManyToMany через промежуточную модель. Таким образом, у вас есть набор достижений, и ссылка на каждого пользователя представляет собой AchievementSatus, который позволяет вам хранить дополнительную информацию об этих отношениях, например, статус, дату, когда статус был достигнут этим пользователем, и т.д ... см. Пример Django с пользователем, группой и членством как
throughпромежуточная модель.