python - 如果存在相关对象,则阻止字段更改?

标签 python django django-admin django-validation

我的 Django 应用程序中有两个模型:

class Survey(models.Model):
    survey_type = models.CharField(max_length=1, choices=SURVEY_TYPES)

class Response(models.Model):
    survey = models.ForeignKey(Survey)
    response = models.TextField()

调查组织者创建调查后,他们可以指定类型。一旦出现第一个响应,我不希望组织者能够使用网站管理员更改类型(因为响应模型中的自由文本响应字段会改变含义)。

我已经研究过使用验证器,但据我所知,它们旨在对表单进行操作,而不是对要保存的对象进行操作。我找不到任何对在其中执行数据库查询的支持。

我还考虑过重写 save 方法,但据我所知,它预计不会用于验证(而且我不想在我的模型中放入任何逻辑) .

我在其他框架中这样做的方式是在 ORM 之上引入一些层,允许我引入业务规则。请指教 - 这里的最佳实践是什么?

最佳答案

您实际上可以使用模型级验证:

class Survey(models.Model):
    survey_type = models.CharField(max_length=1, choices=SURVEY_TYPES)

    def __init__(self, *args, **kwargs):
        super().__init__(self, *args, **kwargs)
        self._old_survey_type = self.survey_type

    def clean(self):
        if (self.survey_type != self._old_survey_type) \
                and survey_typeself.response_set.exists():
            raise ValidationError('Cannot modify the type of a started survey') 

但请注意,保存对象时不会自动调用Model.clean。当 ModelForm 得到验证时(因此也在管理中),它会执行,但否则您必须检查它是否有效或自己调用它。

关于python - 如果存在相关对象,则阻止字段更改?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33479855/

相关文章:

python - 通配符在使用 shlex 的子进程调用中不起作用

python - 为什么 wxGlade 强制将 sizer 作为 wx.Frame 的第一个子元素?

python - 如何在 Pandas 多级数据框中选择具有相同名称(同一级别)的列

python - Django 模板不显示表数据

django - 南方不为第三方安装的应用程序创建表

django - 修改Django "save and add another"按钮,根据刚保存的对象上的字段值设置字段的初始值

Django:如何向执行管理操作的管理更改表单页面添加自定义按钮?

python - tf.contrib.framework 函数的预期用途是什么?

python - 如何将 JSON 数据从 Django View 传递到 Vue.js 实例方法

django - 在 Django Admin 中,如何禁用删除链接