Django中同配置字段仅其一未显示空白验证消息的问题求助
Django字段验证异常:
to字段未显示空白验证消息 问题描述
两个配置完全相同的CharField字段(to和reason),使用同一类型Widget,但提交空白内容时,to字段未显示空白验证消息,reason字段正常显示。
相关代码
Model
class MagangLetter(models.Model): to=models.CharField(max_length=255) reason=models.CharField(max_length=255) start_date=models.DateField() end_date=models.DateField()
Form
class MagangLetterForm(forms.ModelForm): class Meta: model=MagangLetter fields=['to','reason','start_date','end_date'] widgets={ 'to':forms.Textarea(attrs={'class':'form-control','rows':'3','placeholder':'''#example'''}), 'reason':forms.Textarea(attrs={'class':'form-control','rows':'3','placeholder':'''#example'''}), 'start_date':forms.DateInput(attrs={'class':'form-control','type':'date'}), 'end_date':forms.DateInput(attrs={'class':'form-control','type':'date'}) }
View
class CreateLetterMagang(CreateView): model=MagangLetter form_class=MagangLetterForm template_name_suffix="_create_form" def get_context_data(self, **kwargs): context=super().get_context_data(**kwargs) form:MagangLetter=context['form'] file_template=Template(services.letter.get_html_template('magang.docx')) date=datetime.datetime.now() day=settings.MONTHS[date.strftime('%m')] file_context=Context({ 'letter_number' : '........', 'date_submitted' : f'{date:%d} {day} {date:%Y}', 'to': form['to'], 'name': self.request.user.get_full_name(), 'nim': self.request.user.detail.id_number, 'reason':form['reason'], 'start_date': form['start_date'], 'end_date': form['end_date'], 'nip':'.............', 'dosen':'...............', 'sign': '' }) html=file_template.render(file_context) soup = BeautifulSoup(html, 'html.parser') date_submit=soup.find(string=re.compile("Yogyakarta,")) p=soup.find(string=re.compile("#test")) date_submit.parent.parent['style']='width:15rem;' p.parent['class']='p-0' p=soup.find(string=re.compile("#test")) p.parent['class']='p-0' p=soup.find(string=re.compile("#test")) p.parent['class']='p-0' table=(p.next_element.next_element.next_element) table['class'].append('text-center ms-auto') table['style']='width:fit-content' date_forms=soup.find_all(type='date') for date_form in date_forms: date_form['class'].append('w-25') date_form['style']='min-width:fit-content;' context['docx']=soup.prettify() return context
Template
{% block body %} <div class="row content d-block overflow-auto"> <div class="card p-3" style="width:40rem;"> <form method='post'> {% csrf_token %} {{docx|safe}} <input type='submit' class='btn btn-primary' value='Buat Surat'></input> </form> </div> </div> {% endblock body %}
问题原因
- 表单验证时机错误:在
get_context_data中提前访问form['to']字段,此时表单未完成验证流程,错误信息无法绑定到字段上。 - DOM元素模糊修改:多次通过
#test字符串匹配元素并修改父类属性,误操作了to字段对应的错误提示容器,导致验证消息无法渲染。
解决方案
方案1:调整验证触发+精准定位DOM
修改View的get_context_data方法,确保POST请求时先触发表单验证,同时替换模糊匹配为精准定位字段元素:
class CreateLetterMagang(CreateView): model=MagangLetter form_class=MagangLetterForm template_name_suffix="_create_form" def get_context_data(self, **kwargs): context=super().get_context_data(**kwargs) form = context['form'] # POST请求先触发验证,绑定错误信息 if self.request.method == 'POST': form.is_valid() file_template=Template(services.letter.get_html_template('magang.docx')) date=datetime.datetime.now() day=settings.MONTHS[date.strftime('%m')] file_context=Context({ 'letter_number' : '........', 'date_submitted' : f'{date:%d} {day} {date:%Y}', 'to': form['to'], 'name': self.request.user.get_full_name(), 'nim': self.request.user.detail.id_number, 'reason':form['reason'], 'start_date': form['start_date'], 'end_date': form['end_date'], 'nip':'.............', 'dosen':'...............', 'sign': '' }) html=file_template.render(file_context) soup = BeautifulSoup(html, 'html.parser') date_submit=soup.find(string=re.compile("Yogyakarta,")) date_submit.parent.parent['style']='width:15rem;' # 精准定位to字段容器 to_field = soup.find('textarea', {'name': 'to'}) if to_field: to_field.parent['class'] = 'p-0' # 精准定位reason字段容器及后续表格 reason_field = soup.find('textarea', {'name': 'reason'}) if reason_field: reason_field.parent['class'] = 'p-0' table=(reason_field.next_element.next_element.next_element) table['class'].append('text-center ms-auto') table['style']='width:fit-content' date_forms=soup.find_all(type='date') for date_form in date_forms: date_form['class'].append('w-25') date_form['style']='min-width:fit-content;' context['docx']=soup.prettify() return context
方案2:模板预留错误信息位置
检查docx模板,在to字段的textarea下方添加{{ form.to.errors }}占位,确保验证错误信息能被正确渲染到对应位置。
内容的提问来源于stack exchange,提问作者Fikra Laksana Putra
相关产品推荐
相关产品推荐

