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)