ModelForm __init__问题

时间:2014-04-11 18:45:26

标签: python django django-forms

我试图修改我的Django ModelForm __init__构造函数,以便接受传递的变量(' admin'),查看是否admin == True,以及如果是这样,请将几个字段(' applicant_affirmation'&' applicant_interest_stmt')显示为不可修改的字段。根据需要,字段显示为不可修改,但.update()函数不会发生,因为它没有通过if form.is_valid检查。我已经检查了form.non_field_errorsform.errors,但没有任何内容。如果__init__方法被注释掉,则更新可以正常工作。

对我可能缺少什么的任何想法?诚然,我还没有对构建构造函数有深刻的理解。非常感谢帮助。

class ApplicationForm(ModelForm):

    class Meta:
        model = Application
        fields = ('program', 'status', 'applicant_affirmation', 'applicant_interest_stmt', 'applicant_school', 'applicant_major', 'applicant_school_2', 'applicant_major_2', 'gpa_univ', 'estimated_grad_semester')
        widgets = {
            'applicant_interest_stmt': Textarea(attrs={'class': 'form-control', 'rows': 5}),
            'estimated_grad_semester': Select(),
        }

    def __init__(self, admin, *args, **kwargs):
        super(ApplicationForm, self).__init__(*args, **kwargs)
        if admin:
            self.fields['applicant_interest_stmt'].widget.attrs['disabled'] = 'disabled'
            self.fields['applicant_affirmation'].widget.attrs['disabled'] = 'disabled'


    def clean(self):
        from django.core.exceptions import ValidationError
        cleaned_data = super(ApplicationForm, self).clean()
        applicant_interest_stmt = cleaned_data.get('applicant_interest_stmt')
        applicant_affirmation = cleaned_data.get('applicant_affirmation')
        if not applicant_interest_stmt:
            msg = u'Please provide an interest statement.'
            self._errors["applicant_interest_stmt"] = self.error_class([msg])
        if not applicant_affirmation:
            msg = u'Please check the affirmation checkbox.'
            self._errors["applicant_affirmation"] = self.error_class([msg])
        return cleaned_data

应用程序模型:

class Application(models.Model):
    id = models.AutoField(primary_key=True)
    program = models.ForeignKey(Program, verbose_name="certificate program")
    status = models.ForeignKey(Status, verbose_name="application status")
    applicant = models.ForeignKey(Person)
    applicant_affirmation = models.BooleanField()
    applicant_interest_stmt = models.TextField(verbose_name="In a few sentences, briefly explain why you are interested in this program and what you expect to get out of it")
    applicant_school = models.CharField(max_length=100, verbose_name="school (primary)")
    applicant_major = models.CharField(max_length=100, verbose_name="major (primary)")
    applicant_school_2 = models.CharField(blank=True, max_length=100, verbose_name="school (secondary)")
    applicant_major_2 = models.CharField(blank=True, max_length=100, verbose_name="major (secondary)")
    gpa_univ = models.DecimalField(max_digits=3, decimal_places=2, verbose_name="GPA (university)")
    estimated_grad_semester = models.CharField(max_length=5, verbose_name="estimated graduation semester")
    _created = models.DateTimeField(editable=False, blank=False)
    _created_by = models.CharField(max_length=150)
    _updated = models.DateTimeField(editable=False, blank=False)
    _updated_by = models.CharField(max_length=150)

    def clean(self):
        from django.core.exceptions import ValidationError
        cleaned_data = super(Application, self).clean()
        if not self.applicant_affirmation:
            raise ValidationError('Please check the affirmation checkbox.')
        if self.applicant_school_2 == '/':
            self.applicant_school_2 = ''
        if self.applicant_major_2 == '/':
            self.applicant_major_2 = ''

    def save(self, *args, **kwargs):
        """ On save, update both timestamps """

        self._created = datetime.datetime.now()
        self._updated = datetime.datetime.now()

        return super(Application, self).save(*args, **kwargs)
    #end save

    def update(self, *args, **kwargs):
        """ On update, update only _updated timestamps """

        self._updated = datetime.datetime.now()

        return super(Application, self).save(*args, **kwargs)
    #end update

    def __unicode__(self):
        return unicode(self.id)
    #end unicode

    class Meta:
        db_table = u'certs_application'
    #end meta

来自views.py的片段:

if request.POST:
    app_form = ApplicationForm(request.POST)
    app_form.fields['estimated_grad_semester'].widget.choices = build_semester_list('', 12)

    if app_form.is_valid():
        print 'form is valid...'
        app_instance = get_object_or_404(Application, id=app_id)
        fields = {'program': app_form.cleaned_data['program'],
                  'status': app_form.cleaned_data['status'],
                  'applicant_id': application.applicant_id,
                  'applicant_affirmation': app_form.cleaned_data['applicant_affirmation'],
                  'applicant_interest_stmt': app_form.cleaned_data['applicant_interest_stmt'],
                  'applicant_school': app_form.cleaned_data['applicant_school'],
                  'applicant_major': app_form.cleaned_data['applicant_major'],
                  'applicant_school_2': app_form.cleaned_data['applicant_school_2'],
                  'applicant_major_2': app_form.cleaned_data['applicant_major_2'],
                  'gpa_univ': app_form.cleaned_data['gpa_univ'],
                  'estimated_grad_semester': app_form.cleaned_data['estimated_grad_semester'],
                  '_created_by': app_instance._created_by,
                  '_created': app_instance._created,
                  '_updated_by': user.eid,
                  }
        try:
            application = Application(pk=app_id, **fields)
            application.update()
        except Exception, exception:
            return HttpResponse('Error: ' + str(exception))

        return redirect('application_view', app_id=app_id)

    else:
        print 'app_form is NOT valid'
else:
    # -------------------------------------------
    # render the application using GET
    # -------------------------------------------
    app_form = ApplicationForm(admin=admin_user, instance=application)
    app_form.fields['estimated_grad_semester'].widget.choices = build_semester_list('', 12)

最终修改导致了所需的修复:

views.py

if request.POST:
    app_form = ApplicationForm(admin=admin_user, data=request.POST)

forms.py

def __init__(self, admin, *args, **kwargs):
    super(ApplicationForm, self).__init__(*args, **kwargs)
    self.admin = admin
    if self.admin:
        self.fields['applicant_interest_stmt'].widget.attrs['readonly'] = True
        self.fields['applicant_affirmation'].widget.attrs['readonly'] = True


def clean(self):
    from django.core.exceptions import ValidationError
    cleaned_data = super(ApplicationForm, self).clean()
    if not self.admin:
        applicant_interest_stmt = cleaned_data.get('applicant_interest_stmt')
        applicant_affirmation = cleaned_data.get('applicant_affirmation')
        if not applicant_interest_stmt:
            msg = u'Please provide an interest statement.'
            self._errors["applicant_interest_stmt"] = self.error_class([msg])
        if not applicant_affirmation:
            msg = u'Please check the affirmation checkbox.'
            self._errors["applicant_affirmation"] = self.error_class([msg])
    return cleaned_data

注意:在applicant_affirmation布尔字段上获取不可修改的设置仍然存在问题,但我会将此问题与此问题分开修复。

1 个答案:

答案 0 :(得分:1)

你可能想让管理员成为班级的全局

class ApplicationForm(ModelForm):

class Meta:
    model = Application
    fields = ('program', 'status', 'applicant_affirmation', 'applicant_interest_stmt', 'applicant_school', 'applicant_major', 'applicant_school_2', 'applicant_major_2', 'gpa_univ', 'estimated_grad_semester')
    widgets = {
        'applicant_interest_stmt': Textarea(attrs={'class': 'form-control', 'rows': 5}),
        'estimated_grad_semester': Select(),
    }

def __init__(self, admin, *args, **kwargs):
    super(ApplicationForm, self).__init__(*args, **kwargs)
    self.admin = admin
    if self.admin:
        self.fields['applicant_interest_stmt'].widget.attrs['disabled'] = 'disabled'
        self.fields['applicant_affirmation'].widget.attrs['disabled'] = 'disabled'


def clean(self):
    from django.core.exceptions import ValidationError
    cleaned_data = super(ApplicationForm, self).clean()
    if not self.admin:
        applicant_interest_stmt = cleaned_data.get('applicant_interest_stmt')
        applicant_affirmation = cleaned_data.get('applicant_affirmation')
        if not applicant_interest_stmt:
            msg = u'Please provide an interest statement.'
            self._errors["applicant_interest_stmt"] = self.error_class([msg])
        if not applicant_affirmation:
            msg = u'Please check the affirmation checkbox.'
            self._errors["applicant_affirmation"] = self.error_class([msg])
    return cleaned_data