Как сделать проверку пользовательского поля на уровне модели в Django? - PullRequest
1 голос
/ 01 октября 2019

У меня есть эта модель:

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

Как видите, если у студента есть ielts, то он / она должен указать его/ ее баллы в модельной форме. Теперь я хочу сделать это на уровне модели. Поэтому мне нужно настроить метод сохранения модели, метод очистки или метод full_clean, я не уверен, я думаю.

Как мне это сделать?

Будет ли мое поведение StudentIeltsForm таким же, как и раньше, если я изменю его, как показано ниже?

class StudentIeltsForm(ModelForm):

    class Meta:
        model = StudentIelts
        exclude = ('student')

Я прочитал это: https://docs.djangoproject.com/en/2.2/ref/models/instances/#validating-objects

и это: https://kite.com/python/docs/django.db.models.Model.clean

и я знаю, что для итерации по полю модели я должен использовать

for field in self._meta.fields:

Но я еще не достиг решения этого вопроса.

...