没有引发IntegrityError

时间:2017-01-20 18:08:49

标签: python django nonetype data-integrity

我有一个具有以下唯一约束的模型:

class Record(Model):
    type = ForeignKey(Type, related_name='records')
    code = CharField(max_length=32)
    group = ForeignKey('self', null=True, blank=True, related_name='members')

    class Meta:
        unique_together = ('type', 'code', 'group')

如果两个记录具有相同的类型和代码,并且两者都没有组,我希望它们是相同的。我希望引发完整性错误,但在以下测试用例中不会发生这种情况:

Record.objects.create(type=type_article_structure,
                      code='shoe',
                      group=None)
Record.objects.create(type=type_article_structure,
                      code='shoe',
                      group=None)

如果我为两者填充相同的组,则唯一约束有效:

group = Record.objects.create(type=type_article_structure,
                              code='group')
Record.objects.create(type=type_article_structure,
                      code='shoe',
                      group=group)
Record.objects.create(type=type_article_structure,
                      code='shoe',
                      group=group)

这导致:

django.db.utils.IntegrityError: UNIQUE constraint failed: md_masterdata_record.type_id, md_masterdata_record.code, md_masterdata_record.group_id

如何确保在第一种情况下我得到相同的错误?

PS。我的测试用例使用SQLite,我的生产服务器使用PostgreSQL。

2 个答案:

答案 0 :(得分:4)

在数据库级别应用唯一的约束约束。许多数据库不会相互比较null值,因此,让插入操作进入。

您可以通过覆盖模型中的clean方法来解决此问题。应使用clean方法提供自定义验证或在保存之前修改字段值。另外,请注意清除is not invoked when you call保存on the object. It should be invoked before calling the save`方法。

from django.core.exceptions import ValidationError
class Record(Model):
    def clean(self):
        # check if exists
        if Record.objects.get(type=self.type,
                          code=self.code,
                          group=self.group):
              # raise an exception
              raise ValidationError("Exists")

答案 1 :(得分:0)

1)

try:
    //somthing
except IntegrityError as e:
    print("integrity")
except Exception as e:
    print(e)`

2)检查

record=Record(type=type_article_structure,
                  code='shoe',
                  group=None)
record.save()