[Answered ]-Automatic set/update fields in Django

1👍

The best way is not to store the leader at all, since that is duplicated data. You can determine the leader with. Otherwise you store duplicated data, and as you actually already found out yourself, keeping tables in sync, turns out to be a much harder problem that what one might expect:

class Team(models.Model):
    name = models.CharField(verbose_name='Team Name', max_length=200)
    slug = AutoSlugField(
        populate_from='Name',
        always_update=True,
        editable=True,
        verbose_name='Team Slug',
    )
    location = models.CharField(verbose_name='Team Location', max_length=200)
    arrival_date = models.DateTimeField(
        default=timezone.now, editable=False, verbose_name='Arrival Date'
    )
    departure_date = models.DateTimeField(
        null=True, blank=True, verbose_name='Departure Date'
    )

    @property
    def leader(self):
        return Member.objects.filter(team=self, is_leader=True).first()

in the Member model, we can add a constraint that there is at most one such leader:

from django.db.models import Q


class Member(models.Model):
    name = models.CharField(verbose_name='Member Name', max_length=200)
    team = models.ForeignKey(Teams, on_delete=models.CASCADE)
    phone_number = models.CharField(max_length=20, null=True, blank=True)
    email = models.EmailField(max_length=50, null=True, blank=True)
    blood_type = models.CharField(
        max_length=3, choices=BLOOD_TYPE_CHOICES, null=True, blank=True
    )
    is_leader = models.BooleanField(default=False)

    class Meta:
        constraints = [
            models.UniqueConstraint(
                fields=('team',),
                condition=Q(is_leader=True),
                name='one_leader_per_team'
            ),
        ]

Note: Normally you should not change slugs when the related fields change. As is written in the article Cool URIs don’t change [w3.org], URIs are not supposed to change, since these can be bookmarked. Therefore the slug should only be created when creating the object, not when you change any field on which the slug depends.


Note: normally a Django model is given a singular name, so Member instead of Members.


Note: normally the name of the fields in a Django model are written in snake_case, not PascalCase, so it should be: blood_type instead of Bloodtype.

Leave a comment