首页 > 解决方案 > 根据外键设置唯一主键

问题描述

我有一个模型定义为 -

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

现在对于每个分支,我想从 1 开始主键(例如“id”),但 Django 的默认功能将增加 id 而与任何其他数据无关。

即使 id 继续递增,我也可以,然后我设置自己的字段,使其每个分支都是唯一的,并且该字段应自动递增,而无需用户通过检查数据库中的前一个值来传递数据,例如 -

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

我不知道如何实现这一目标。使用 Django 3.1.5。

有什么帮助吗?

标签: pythondjango

解决方案


在模型的save方法中,您可以执行查询以获取当前分支字段中的最大值,将此值加 1,然后将其保存为新值。只有在还没有值的情况下才这样做,这样我们就不会覆盖现有的行

也使用Meta.unique_together在数据库级别强制执行此约束

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)

推荐阅读