首页 > 解决方案 > 强制 Django Admin 正确调用 .update() 而不是 .save() 以避免触发用于创建对象的检查

问题描述

我们如何强制 Django Admin 正确调用.update()而不是.save()避免触发用于创建对象的检查?

这是models.py

class BinaryChoice():
    # field definitions
    ...

    def save(self, *args, **kwargs):
        # check if binary
        if self.question.qtype == 2:
            if self.question.choices.count() < 2:
                super(BinaryChoice, self).save(*args, **kwargs)
            else:
                raise Exception("Binary question type can contain at most two choices.")
        else:
            super(BinaryChoice, self).save(*args, **kwargs)

这通过了测试,不足为奇:

class SurveyTest(TestCase):

    def test_binary_choice_create(self):
        q1 = Question.objects.create(survey=survey, title='Have you got any internship experience?', qtype=Question.BINARY)
        BinaryChoice.objects.create(question=q1, choice="Yes")
        BinaryChoice.objects.create(question=q1, choice="No")
        with self.assertRaises(Exception):
            BinaryChoice.objects.create(question=q1, choice="Unsure / Rather not say")

.save()正确检查是否存在与同一问题相关的 2 个二元选择。但是,在 Django Admin 中,当使用接口更新值(任何任意,例如将值从“是”更改为“确定”)并保存它时,人们会期望.update()调用该方法。

事实证明,根据Django 文档以及此处的相关线程,该.save()方法被调用。所以现在我们的更新操作会在已经有 2 时失败BinaryChoice,即使您打算使用 Django Admin 的默认界面就地更新一个值。

为了完整起见,这是admin.py

@admin.register(BinaryChoice)
class BinaryChoiceAdmin(admin.ModelAdmin):
    pass

标签: pythondjango

解决方案


而不是试图修补ModelAdmin你为什么不简单地修复你的save方法?只需在保存之前检查对象是否已经有 pk:

class BinaryChoice():
    # field definitions
    ...

    def save(self, *args, **kwargs):
        # check if binary
        # Here ↓
        if not self.pk and self.question.qtype == 2:
            if self.question.choices.count() < 2:
                super(BinaryChoice, self).save(*args, **kwargs)
            else:
                raise Exception("Binary question type can contain at most two choices.")
        else:
            super(BinaryChoice, self).save(*args, **kwargs)

推荐阅读