如何从modelform模型实例中删除字段? [英] How to remove a field from modelform model instance?

查看:82
本文介绍了如何从modelform模型实例中删除字段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个与此相关的问题:

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?

这是我的模特

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')

但是当我检查has_ielts字段并提交表单时,我看到以下错误:

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'

我的看法如下:

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)

推荐答案

这是@dirkgroten给出的答案.我正在记录他的答案:

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)

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')

阅读他的解释: 查看全文

登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆