I have the following code:
from django.db import models
from django.contrib.auth import get_user_model
User = get_user_model()
class Employee(models.Model):
employee = models.OneToOneField(User, on_delete=models.CASCADE)
boss = models.ForeignKey(
"self",
on_delete=models.CASCADE,
null=True,
blank=True),
)
executive_head = models.BooleanField(
default=False,
help_text=_("e.g. Chief Executive Officer or Managing Director."),
)
job_title = models.CharField(max_length=100)
class Meta:
ordering = ["id"]
constraints = [
UniqueConstraint(
fields=["executive_head"],
name="only_one_executive_head",
condition=Q(executive_head=True),
)
]
def __str__(self):
return f"{ self.employee }"
def save(self, *args, **kwargs):
if self.employee == self.boss:
self.executive_head = True
else:
self.executive_head = False
def clean(self):
if Employee.objects.filter(executive_head=True) and
self.employee == self.boss:
raise ValidationError(
{"executive_head": _("There can only be one executive
head.")
}
)
What I would like to see is that only one value should be true in the executive_head field. It should not be possible to have more than one executive head.
Using unique_together in the class Meta does not work (in hindsight it should not) because the false values would then not be unique.
Any ideas?
Solved using my last suggestion and doing away with the class meta unique_constraint. Amended models.py. See the code. I beg your pardon that I didn't share the "boss" field. Only executive head can be own boss hence clean method works. As a result of the save method, the executive head is automatically updated and the clean method ensures no multiple executive heads.