【问题标题】:django-reversion conflict with models clean methoddjango-reversion 与模型清理方法冲突
【发布时间】:2019-09-29 10:09:28
【问题描述】:

我使用 django-reversion 来控制我的模型的更改,但是我的模型清理方法有问题。

例如,我的模型如下所示:

class Document(models.Model):
    name = models.CharField(max_length=255, blank=True, null=True)
    client = models.ForeignKey(Client, on_delete=models.CASCADE)
    template = models.ForeignKey(Template, on_delete=models.CASCADE)

    def clean(self):
        if self.template.only_one and (Document.objects.filter(client=self.client, template=self.template).count() > 0):
            raise ValidationError('Test')

我在 admin.py 中注册了这个模型:

@admin.register(Document)
class DocumentReversion(VersionAdmin):
    pass

现在我在管理部分创建一个文档记录,引用一个模板,其中字段only_oneTrue。 如果我删除并检索此记录,则会触发 ValidationError。 为什么?因为我已经删除了唯一可用的记录。很好奇……

【问题讨论】:

  • 因为clean()在现有文档上被调用,因此self.template.only_oneDocument.objects.filter(...).count()也为真,因此会引发错误。

标签: python django django-models django-reversion


【解决方案1】:

对任何更新执行清理。如果您因此编辑您的Document,那么它也会检查给定的条件。由于该条件成立:模板具有only_one=True,并且存在这样的文档(您的文档),因此它将引发ValidationError

因此,您需要从查询集中排除当前项目:

class Document(models.Model):
    name = models.CharField(max_length=255, blank=True, null=True)
    client = models.ForeignKey(Client, on_delete=models.CASCADE)
    template = models.ForeignKey(Template, on_delete=models.CASCADE)

    def clean(self):
        qs = Document.objects.filter(client_id=self.client_id, template_id=self.template_id)
        if self.pk is not None:
            qs = qs.exclude(pk=self.pk)
        if self.template.only_one and qs.exists():
            raise ValidationError('A document with this template already exists')
        return super().clean()

如果这样设置了主键,我们可以从查询集中排除该主键。实际上我们这里不需要 if 条件,因为.exclude(pk=None) 无论如何都会成功。

【讨论】:

    猜你喜欢
    • 2018-01-30
    • 1970-01-01
    • 1970-01-01
    • 2012-02-22
    • 1970-01-01
    • 2014-12-22
    • 2015-03-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多