为模型添加限制

时间:2017-01-25 11:17:51

标签: django django-models

鉴于这两个模型:

models.py

PRIMARY, SECONDARY = 0, 1
STORAGE_TYPE = (
    (PRIMARY, "Primary"),
    (SECONDARY, "Secondary"),
)


class Storage(models.Model):
    company = models.ForeignKey(Company, related_name='storage')
    storage_type = models.PositiveIntegerField(choices=STORAGE_TYPE)

class Company(models.Model):
    name = models.CharField(max_length=64)

我想添加一个限制,以便一个公司只能拥有一个主存储类型。其余的必须是中学。

实现这一目标的最佳方式是什么?

这是一个好习惯吗?:

models.py

# ... Storage model

def clean(self):
    if self.storage_type == PRIMARY:
        if self.objects.filter(company=self.company, storage_type=PRIMARY).exists():
            raise ValidationError({'storage_type': 'Already exists a Primary storage.'})

2 个答案:

答案 0 :(得分:1)

如果您使用的数据库不支持约束,那么这是一个很好的做法。例如,postgresql可以在数据库级别进行此类检查。在可能的情况下依靠数据库来保持数据完整性总是更好。那是因为你在干净方法中进行的那种检查会导致竞争条件。

如果您使用的是mysql(仅具有唯一和外键约束),则可以继续使用当前的方法。您可能还需要考虑在您的字段中存储数字(1,2,3,),以便1代表主数据,2,3,4等代表辅助存储。这样你就可以给他们一个优先顺序。然后:

class Storage(models.Model):
    company = models.ForeignKey(Company, related_name='storage')
    storage_type = models.PositiveIntegerField(choices=STORAGE_TYPE)

    class Meta:
       unique_together = ('company','storage')

答案 1 :(得分:0)

您应该使用表单保存方法完成此任务。

forms.py

class StorageForm(forms.ModelForm):
    def clean_company(self):
        company = self.cleaned_data.get('company')
        if company.storage_set.filter(storage_type=0).exists():
            raise forms.ValidationError('your_message')
        return company

    class Meta:
        model = Storage
        fields = '__all__'