首页 > 解决方案 > 在 django 中为每个公司保存一个唯一的订单 ID

问题描述

我希望每个公司都有一个唯一的 id_order,如果已经存在,我无法保存订单或表格无效。在我的例子中,每家公司保存订单,A公司可以保存id_order 1 id_order 2 id_order 3 ...公司B可以保存id_order 10 id_order 20 id_order 30 ...我现在想要的是A公司不能保存两次id_order 3或B公司无法保存两次id_order 20。

class Company(models.Model):
    name = models.CharField(max_length=240)
    last_order = models.DecimalField(max_digits=20, decimal_places=0)

class Order(models.Model):
    company = models.ForeignKey('Company', on_delete=models.CASCADE)
    id_order = models.DecimalField(max_digits=20, decimal_places=0)

    def save(self, *args, **kwargs):
        created = not self.pk
        super().save(*args, **kwargs)
        if created:
            Company.objects \
                .filter(pk=self.company_id) \
                .update(last_order=self.id_order)

形式:

class OrderForm(ModelForm):

    class Meta:
        model = Order

    def __init__(self, company , *args, **kwargs):
        super(OrderForm, self).__init__(*args, **kwargs)
        self.fields['company'] = forms.ModelChoiceField(queryset=Company.objects.filter(name=company), initial = company)
        try:
            code = company.last_order + 1
            self.fields["id_order"].initial = code
        except Exception as e:
            print(e)

标签: djangodjango-modelsdjango-viewsdjango-forms

解决方案


您可以对这对夫妇添加一个唯一的约束,company并且id_order

class Order(models.Model):
    company = models.ForeignKey('Company', on_delete=models.CASCADE)
    id_order = models.IntegerField(max_digits=20, decimal_places=0)

    # …

    class Meta:
        constraints = [
            models.UniqueConstraint(
                fields=['company', 'id_order'],
                name='unique_per_company'
            )
        ]

但是,我不会last_orderat the company 模型存储起来。这可能是一个问题,因为订单 id 本身并不是按顺序分派的,例如,最后一个订单 id 可能是4,而已经有5.

对于一家公司,您可以简单地计算最大值并将其加一:

from django.db.models import Max

class OrderForm(ModelForm):

    class Meta:
        model = Order

    def __init__(self, company , *args, **kwargs):
        super(OrderForm, self).__init__(*args, **kwargs)
        self.fields['company'] = forms.ModelChoiceField(queryset=Company.objects.filter(pk=company.pk), initial=company)
        code = (company.order_set.aggregate(
            max_id=Max('id_order')
        )['max_id'] or 0) + 1
        self.fields["id_order"].initial = code

您可能还需要考虑将 替换DecimalFielddecimal_places=0[ BigIntegerFieldDjango-doc]


推荐阅读