Home > database >  Set unique primary key based on foreignkey
Set unique primary key based on foreignkey

Time:10-14

I have a model defined as -

class sales_order(models.Model):
    customer=models.ForeignKey()
    item=models.ForeignKey()
    branch=models.ForeignKey()
    ---
    ---other fields

Now for each branch, I want to start the primary key from 1 ("id" for eg.), but the default functionality of Django will increment the id irrespective of any other data.

I'm ok even if id keeps on incrementing as it does, and then I set my own field making it unique per branch and this field should auto increment without the user passing the data by checking the previous value from the database such as -

class order_serializer(serializers.ModelSerializer):
    class Meta:
        validators = [
            UniqueTogetherValidator(
                queryset=sales_order.objects.all(),
                fields=['myOwnDefinedField', 'branch']
            )
        ]

I'm in a state of no idea how to achieve this. Using Django 3.1.5.

Any help?

CodePudding user response:

In the model's save method you can perform a query to get the greatest value in the field for the current branch, add 1 to this value and then save that as the new value. Only do this if there is not already a value so that we don't overwrite existing rows

Use Meta.unique_together to enforce this constraint at the DB level too

from django.db.models.functions import Coalesce

class SalesOrder(models.Model):
    branch = models.ForeignKey(Branch, on_delete=models.CASCADE)
    branch_unique_id = models.IntegerField(editable=False, blank=True)

    class Meta:
        unique_together = (
            ('branch', 'branch_unique_id'),
        )

    def save(self, *args, **kwargs):
        if not self.branch_unique_id:
            self.branch_unique_id = SalesOrder.objects.filter(
                branch=self.branch
            ).aggregate(
                max=Coalesce(models.Max('branch_unique_id'), 0)
            )['max']   1
        super().save(*args, **kwargs)
  • Related