【发布时间】:2020-01-30 19:54:13
【问题描述】:
我问了一个问题,我读了一点,现在可以更好地表达我的需要: How to do model level custom field validation in django?
我有这个模型:
class StudentIelts(Model):
SCORE_CHOICES = [(i/2, i/2) for i in range(0, 19)]
student = OneToOneField(Student, on_delete=CASCADE)
has_ielts = BooleanField(default=False,)
ielts_listening = FloatField(choices=SCORE_CHOICES, null=True, blank=True, )
ielts_reading = FloatField(choices=SCORE_CHOICES, null=True, blank=True, )
ielts_writing = FloatField(choices=SCORE_CHOICES, null=True, blank=True, )
ielts_speaking = FloatField(choices=SCORE_CHOICES, null=True, blank=True, )
并有这个模型形式:
class StudentIeltsForm(ModelForm):
class Meta:
model = StudentIelts
exclude = ('student')
def clean(self):
cleaned_data = super().clean()
has_ielts = cleaned_data.get("has_ielts")
if has_ielts:
msg = "Please enter your score."
for field in self.fields:
if not self.cleaned_data.get(str(field)):
self.add_error(str(field), msg)
else:
for field in self.fields:
self.cleaned_data[str(field)] = None
self.cleaned_data['has_ielts'] = False
return cleaned_data
我在这里所做的是检查has_ielts 是否为True,然后应填写所有其他字段。如果has_ielts 是True 甚至没有填写一个字段,我会收到错误消息。如果has_ielts 是False,则应保存具有has_ielts=False 和所有其他字段Null 的对象。我现在想在模型级别上做:
class StudentIelts(Model):
SCORE_CHOICES = [(i/2, i/2) for i in range(0, 19)]
student = OneToOneField(Student, on_delete=CASCADE)
has_ielts = BooleanField(default=False,)
ielts_listening = FloatField(choices=SCORE_CHOICES, null=True, blank=True, )
ielts_reading = FloatField(choices=SCORE_CHOICES, null=True, blank=True, )
ielts_writing = FloatField(choices=SCORE_CHOICES, null=True, blank=True, )
ielts_speaking = FloatField(choices=SCORE_CHOICES, null=True, blank=True, )
def clean(self):
# I do not know what to write in here
并有这个模型形式:
class StudentIeltsForm(ModelForm):
class Meta:
model = StudentIelts
exclude = ('student')
在我的模型的 clean 方法中,我想要一些具有这种逻辑的东西(这是伪代码):
def clean(self):
msg = "Please enter your score."
if self.has_ielts:
my_dic = {}
for f in model_fields:
if f is None:
my_dic.update{str(field_name): msg}
raise ValidationError(my_dic)
我该怎么做?
如何在模型级别获得与我的模型表单相同的结果?
【问题讨论】:
-
您需要明确地逐一检查 4 个字段(也在您的表单中),因为您只对以
ielts开头的字段感兴趣。包含其他字段是不好的编码。if not ielts_listening: raise ValidationError(...); .... -
我希望有一个可重用的代码用于其他模型,如 GRE、GMAT、IBT 等,在我当前的模型表单中,我正在遍历所有字段并更改其中一个。在拥有可重用代码的同时,应该有一种简洁的方法。这没有帮助吗? :
for field in self._meta.fields: -
但其中包括“id”、“student”等字段以及您稍后添加的其他字段。您可以将需要非空的字段列表一起定义为类属性并循环浏览该列表。不这样做会给使用您的模型的其他开发人员带来不可预测的结果。
-
@Daniel 我遇到了与此问题相关的问题,可在此处找到:stackoverflow.com/questions/58254333/…
标签: django validation model modelform