如何在Django中设置必填字段提示仅在提交失败时显示
解决思路
1. 移除手动添加的required属性
你在表单widget里手动给字段加了required='True',这会触发浏览器原生的即时验证提示。Django会根据模型字段的必填性自动处理表单验证,不需要手动添加该属性。修改form.py:
class ElderFlowerChampFormAdmin(ModelForm): fieldsets=[ ("Look",{'fields':[('look_colour','look_clarity','look_effervescence')]}), ] # 修正原代码中的语法错误(多余闭合符) widgets = { 'user': forms.Select(attrs={'class':'form-control'}), 'look_colour':forms.Select(attrs={'class':'form-control'}), # 移除所有手动添加的required属性 }
2. 控制模板中错误信息的显示时机
默认情况下Django表单会渲染所有字段的错误信息,哪怕是首次加载页面。你需要在模板里判断表单是否已经被提交(form.is_bound),只有提交后才显示错误提示。修改ElderFlowerReview.html中的表单渲染部分:
{% for field in form %} <div class="form-group"> {{ field.label_tag }} {{ field }} <!-- 仅当表单已提交且字段有错误时显示提示 --> {% if form.is_bound and field.errors %} <div class="text-danger"> {% for error in field.errors %} {{ error }} {% endfor %} </div> {% endif %} </div> {% endfor %}
3. 修正视图中的表单初始化逻辑
你的视图在GET请求时直接把表单类赋值给form变量,而非实例化,会导致模板渲染异常;同时全局变量ChampageRating覆盖了模型类,会引发逻辑错误,需要修正:
def elderflowerchamp(request, product_id): # 删除全局变量声明,避免覆盖模型类 product = Product.objects.get(pk=product_id) url = request.META.get('HTTP_REFERER') submitted = False try: if request.method == "POST": reviews = ChampageRating.objects.get(pk=product_id) if request.user.is_superuser: form = ElderFlowerChampFormAdmin(request.POST, instance=reviews) if form.is_valid(): form.save() return redirect('home') else: form = ElderFlowerChampForm(request.POST, instance=reviews) if form.is_valid(): # 用新变量名代替ChampageRating,避免覆盖模型类 champ_rating = form.save(commit=False) champ_rating.user = request.user champ_rating.save() return redirect('home') else: # GET请求时实例化表单,而非传入类 reviews = ChampageRating.objects.get(pk=product_id) if request.user.is_superuser: form = ElderFlowerChampFormAdmin(instance=reviews) else: form = ElderFlowerChampForm(instance=reviews) if 'submitted' in request.GET: submitted = True except: reviews = None form = None if request.method == "POST": if request.user.is_superuser: form = ElderFlowerChampFormAdmin(request.POST) if form.is_valid(): data = ChampageRating() data.rating = form.cleaned_data['rating'] data.look_colour = form.cleaned_data['look_colour'] data.ip = request.META.get('REMOTE_ADDR') data.product_id = product_id data.user_id = request.user.id data.save() messages.success(request, 'Thank you! Your review has been submitted.') return redirect('home') else: form = ElderFlowerChampForm(request.POST) if form.is_valid(): data = ChampageRating() data.rating = form.cleaned_data['rating'] data.look_colour = form.cleaned_data['look_colour'] data.ip = request.META.get('REMOTE_ADDR') data.product_id = product_id data.user_id = request.user.id data.save() messages.success(request, 'Thank you! Your review has been submitted.') return redirect('home') else: # GET请求时初始化空表单 if request.user.is_superuser: form = ElderFlowerChampFormAdmin() else: form = ElderFlowerChampForm() return render(request,"main/ElderFlowerReview.html", {'form':form, 'submitted':submitted,'reviews':reviews, 'product':product})
4. 禁用浏览器原生验证(可选)
如果想完全屏蔽浏览器的原生提示,只使用Django的错误信息,可以在表单标签中添加novalidate属性:
<form method="post" novalidate> {% csrf_token %} <!-- 表单内容 --> <button type="submit">提交</button> </form>
内容的提问来源于stack exchange,提问作者PhilM
相关产品推荐
相关产品推荐

