Python 模型形式初始问题

Python 模型形式初始问题,python,django,django-forms,Python,Django,Django Forms,我试图修改Django ModelForm\uuuu init\uuuu构造函数,使其接受传递的变量(“admin”),查看admin==True,如果是,则使两个字段(“申请人确认”和“申请人兴趣”)显示为不可修改。根据需要,字段显示为不可修改,但是.update()函数没有执行,因为它没有通过if表单。是否有效检查。我已经检查了form.non\u field\u错误和form.errors,但什么都没有。如果\uuuu init\uuu方法被注释掉,则更新工作正常 有没有想过我可能会错过什

我试图修改Django ModelForm
\uuuu init\uuuu
构造函数,使其接受传递的变量(“admin”),查看
admin==True
,如果是,则使两个字段(“申请人确认”和“申请人兴趣”)显示为不可修改。根据需要,字段显示为不可修改,但是
.update()
函数没有执行,因为它没有通过
if表单。是否有效
检查。我已经检查了
form.non\u field\u错误
form.errors
,但什么都没有。如果
\uuuu init\uuu
方法被注释掉,则更新工作正常

有没有想过我可能会错过什么?诚然,我对构建构造函数还没有很强的理解。非常感谢您的帮助

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

注意:在申请者确认布尔字段上获取不可修改的设置仍然存在一个挥之不去的问题,但我将与此问题分开解决。

您可能希望将管理员设置为类的golobal

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

这里有一个解决您的用例的方法。在我看来,这可能是最好的解决办法。当然,您的
clean
方法也需要调整,以涵盖禁用它们时的情况。不确定这是否会导致其他角落案例问题(如
update
)。谢谢@Two Bitalchest…这肯定表明了希望。然而,我在理解如何使用作者作为示例给出的单个字段级清理方法时遇到了困难。什么叫他们?也许是一种全面的清洁方法?我不确定。想法?最上面的几段描述通话顺序。简而言之,是的,它们由
clean
单独调用
clean\uuu
方法可能存在或不存在,并且应该返回所述字段的“已清理”数据,或者引发
ValidationError
。感谢您提供的信息,但我仍然无法为我实现这一点。感谢您的想法,但实际上我在上一次迭代中已经有了这一点。不过我又试了一次,更确切地说是你在这里提供的,但是,唉……没有运气。表单仍未通过“是否有效”检查。@Keith您如何插入“创建人”和“更新人”,因为它们是必填字段……我直接从视图中传递这些字段。py@KeithE您可能需要执行created=models.DateTimeField(auto\u now\u add=True)modified=models.DateTimeField(auto\u now=True)然后可以在中删除覆盖save@KeithE我能看看你的观点吗