How to remove a field from modelform model instance?

人走茶凉 提交于 2019-12-11 15:22:54

问题


I have a question related this one: How to handle the validation of the model form when the model has a clean method if the model form excluded some fields?

This is my model:

class StudentIelts(Model):

    SCORE_CHOICES = [(float(i/2), float(i/2)) for i in range(0, 19)]
    IELTS_TYPE_CHOICES = [('General', 'General'), ('Academic', 'Academic'), ]

    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, )
    ielts_overall = FloatField(choices=SCORE_CHOICES, null=True, blank=True, )
    ielts_exam_type = CharField(max_length=10,  null=True, blank=True, choices=IELTS_TYPE_CHOICES, )
    ielts_exam_date = DateField(null=True, blank=True, )
    ielts_file = FileField(upload_to=student_directory_path, null=True, blank=True, )

    student_ielts_non_empty_fields = \
        {
            'ielts_listening': 'please enter your listening score',
            'ielts_reading': 'please enter your reading score',
            'ielts_writing': 'please enter your writing score',
            'ielts_speaking': 'please enter your speaking score',
            'ielts_overall': 'please enter your overall score',
            'ielts_exam_type': 'please enter your exam type',
            'ielts_exam_date': 'please specify your exam date',
        }

    def clean(self):
        errors = {}
        if self.has_ielts:
            for field_name, field_error in self.student_ielts_non_empty_fields.items():
                if getattr(self, field_name) is None:
                    errors[field_name] = field_error
        if errors:
            raise ValidationError(errors)
class StudentIeltsFilterForm(ModelForm):

    class Meta:
        model = StudentIelts
        fields = ['has_ielts', 'ielts_listening', 'ielts_reading', 'ielts_writing', 'ielts_speaking', 'ielts_overall', 'ielts_exam_type', ]

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.instance.student_ielts_non_empty_fields.pop('ielts_exam_date')

But when I check the has_ielts field and submit the form I see the error below:

Exception Type: KeyError
Exception Value: 'ielts_exam_date'

My view is as below:

def home(request):
    template_name = 'programs/home.html'
    home_context = {}
    if request.POST:
        return HttpResponse('We did not expect a POST request')

    else:
        if request.GET.get('hidden'):
            student_ielts_filter_form = StudentIeltsFilterForm(request.GET)

            if student_ielts_filter_form.is_valid():

                querystring = urlencode(request.GET)
                return redirect(reverse('programs') + '?' + querystring)
        else:

            student_ielts_filter_form = StudentIeltsFilterForm()
    home_context.update({
        'student_ielts_filter_form': student_ielts_filter_form,
    })
    return render(request, template_name, home_context)

回答1:


This is the answer given by @dirkgroten . I am documenting his answer:

class StudentIelts(Model):

    SCORE_CHOICES = [(float(i/2), float(i/2)) for i in range(0, 19)]
    IELTS_TYPE_CHOICES = [('General', 'General'), ('Academic', 'Academic'), ]

    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, )
    ielts_overall = FloatField(choices=SCORE_CHOICES, null=True, blank=True, )
    ielts_exam_type = CharField(max_length=10,  null=True, blank=True, choices=IELTS_TYPE_CHOICES, )
    ielts_exam_date = DateField(null=True, blank=True, )
    ielts_file = FileField(upload_to=student_directory_path, null=True, blank=True, )

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.student_ielts_non_empty_fields = \
            {
                'ielts_listening': 'please enter your listening score',
                'ielts_reading': 'please enter your reading score',
                'ielts_writing': 'please enter your writing score',
                'ielts_speaking': 'please enter your speaking score',
                'ielts_overall': 'please enter your overall score',
                'ielts_exam_type': 'please enter your exam type',
                'ielts_exam_date': 'please specify your exam date',
            }

    def clean(self):
        errors = {}
        if self.has_ielts:
            for field_name, field_error in self.student_ielts_non_empty_fields.items():
                if getattr(self, field_name) is None:
                    errors[field_name] = field_error
        if errors:
            raise ValidationError(errors)

and

class StudentIeltsFilterForm(ModelForm):

    class Meta:
        model = StudentIelts
        fields = ['has_ielts', 'ielts_listening', 'ielts_reading', 'ielts_writing', 'ielts_speaking', 'ielts_overall', 'ielts_exam_type', ]

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.instance.student_ielts_non_empty_fields.pop('ielts_exam_date')

read his explanation: How to handle the validation of the model form when the model has a clean method if the model form excluded some fields?



来源:https://stackoverflow.com/questions/58258213/how-to-remove-a-field-from-modelform-model-instance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!