Как сделать так, чтобы только одна запись была True в модели Django?
Я застрял на мысли о реализации "только одна запись может быть True для одной комбинации".
Проект имеет n членов (охранников) через промежуточную таблицу.
- каждый Страж может быть членом n Проектов
- допускается только одна комбинация Guard <-> Project (unique_together)
- членский корабль может быть "главным" (is_main)
- BUT: Только одно из членств может быть главным. .
Я что-то упустил или мне нужно самостоятельно реализовать пользовательскую валидацию?
Чтобы завершить это, смотрите данную модель:
class Project(models.Model):
client = models.ForeignKey(Client, on_delete=models.CASCADE)
shortname = models.CharField(_('shortname'), max_length=50)
description = models.TextField(_('description'), blank=True)
members = models.ManyToManyField(Guard, through='ProjectMembership')
class Meta:
unique_together = ['client', 'shortname']
class ProjectMembership(models.Model):
guard = models.ForeignKey(Guard, on_delete=models.CASCADE)
project = models.ForeignKey(Project, on_delete=models.CASCADE)
is_main = models.BooleanField(_('is main project'), default=False)
class Meta:
unique_together = ['guard', 'project']
Вы можете работать с UniqueConstraint
[Django-doc], который фильтруется:
from django.db.models import UniqueConstraint, Q
class ProjectMembership(models.Model):
guard = models.ForeignKey(Guard, on_delete=models.CASCADE)
project = models.ForeignKey(Project, on_delete=models.CASCADE)
is_main = models.BooleanField(_('is main project'), default=False)
class Meta:
constraints = [
UniqueConstraint(fields=('guard', 'project'), name='unique_guard'),
UniqueConstraint(fields=('guard',), condition=Q(is_main=True), name='one_main_project_per_guard'),
]
Здесь мы гарантируем, что если мы фильтруем ProjectMembership
для is_main=True
, то набор guard
уникален, следовательно, определенный Guard
может встречаться только один раз для is_main
, и это означает, что Guard
имеет максимум один Project
, для которого is_main
является True
.
Note: As the documentation on
unique_together
[Django-doc] says, theunique_together
constraint will likely become deprecated. The documentation advises to use theUniqueConstraint
[Django-doc] from Django's constraint framework.