python - 如何测试 Model.clean() 函数中的唯一性?

标签 python django django-models constraints

我有一个带有 UniqueConstraint 的模型:

class MyModel(models.Model)
    name = models.CharField()
    title = models.CharField()
  
    class Meta:
        constraints = [ models.UniqueConstraint(
                          fields=['name', 'title'],
                          name="unique_name_and_title") ]

这工作正常,并在创建 2 个具有相同值的对象时引发 IntegrityError

问题是 UniqueConstraint 没有向用户呈现漂亮的 ValidationError。通常,我会将这些添加到 Model.clean() 类中,但如果我这样做,那么它将在 Update 上失败,因为正在更新的实例已经存在:

def clean(self):
    if MyModel.objects.filter(title=self.title, name=self.name):
             raise ValidationError({'title':'An object with this name+title already exists'})

我如何创建一个 ValidationError 如果它是 UPDATE 而不是 INSERT 则通过?

我知道我可以在 ModelForm 上执行此操作并使用 self.instance 检查实例是否已经存在,但我想将其应用于 Model 类并且不必依赖 ModelForm。

最佳答案

您可以从您检查的查询集中排除该对象:

def clean(self):
    qs = MyModel.objects.<b>exclude(pk=self.pk)</b>.filter(title=self.title, name=self.name)
    if qs.<b>exists()</b>:
        raise ValidationError({'title':'An object with this name+title already exists'})
    return super().clean()

如果对象尚未保存,它将检查 .exclude(pk=None),但这不会排除任何对象,因为主键不可为空。

使用.exists() [Django-doc]效率更高在这里,因为它限制了从数据库到 Django/Python 层的带宽。

关于python - 如何测试 Model.clean() 函数中的唯一性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62862200/

相关文章:

python - 如何从 python 中的 .xls 文件中读取多个表?

iphone - NSURLRequest POST 到谷歌应用引擎?

html - Django:不在列表中的下拉列表值

python - 正则表达式匹配 django block templatetag

python - 如何防止多对多类链接到相同的对象?

python - django rest framework 过滤器忽略映射到枚举的 int 字段

python - 不安全请求警告 + pytest

python - 从抓取的数据中分割 html (Python+BeautifulSoup4)

python - 如何从内存文件创建 PIL 图像?

python - 我可以将 Django 模型对象作为单例获取吗?