Python 模型形式初始问题
我试图修改Django ModelFormPython 模型形式初始问题,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方法被注释掉,则更新工作正常 有没有想过我可能会错过什
\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我能看看你的观点吗