如果存在相关对象,防止更改字段?
Prevent change of field if related objects exist?
我的 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()
当调查的组织者创建调查后,他们可以指定类型。一旦出现第一个响应,我不希望组织者能够使用站点管理员更改类型(因为响应模型中的自由文本响应字段会改变含义)。
我研究过使用验证器,但据我所知,它们旨在对表单进行操作,而不是对要保存的对象进行操作。我在其中找不到对执行数据库查询的任何支持。
我也研究过重写保存方法,但据我所知,它不应该用于验证(而且我不希望在我的代码中添加任何逻辑模型)。
我在其他框架中这样做的方式是在 ORM 之上引入一些层,允许我引入业务规则。请告知 - 这里的最佳做法是什么?
在 Response
模型中设置 survey
和 response
字段唯一
unique together 像这样:
class Response(models.Model):
survey = models.ForeignKey(Survey)
response = models.TextField()
class Meta:
unique_together = (("survey", "response"),)
您实际上可以使用模型级验证:
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
得到验证时执行(因此也在管理员中),但否则你必须检查它是否验证或自己调用它。
我的 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()
当调查的组织者创建调查后,他们可以指定类型。一旦出现第一个响应,我不希望组织者能够使用站点管理员更改类型(因为响应模型中的自由文本响应字段会改变含义)。
我研究过使用验证器,但据我所知,它们旨在对表单进行操作,而不是对要保存的对象进行操作。我在其中找不到对执行数据库查询的任何支持。
我也研究过重写保存方法,但据我所知,它不应该用于验证(而且我不希望在我的代码中添加任何逻辑模型)。
我在其他框架中这样做的方式是在 ORM 之上引入一些层,允许我引入业务规则。请告知 - 这里的最佳做法是什么?
在 Response
模型中设置 survey
和 response
字段唯一
unique together 像这样:
class Response(models.Model):
survey = models.ForeignKey(Survey)
response = models.TextField()
class Meta:
unique_together = (("survey", "response"),)
您实际上可以使用模型级验证:
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
得到验证时执行(因此也在管理员中),但否则你必须检查它是否验证或自己调用它。