我有一个表单,如果所有字段无效,都会引发验证错误。但是,如果选定的 ModelChoiceField 中没有选项,则表单既不会提交(这很好),也不会在模板中引发任何 ValidationError。
如果提交时未选择类别,if request.method == 'POST':
似乎会返回 False
。
# Form
class PollersForm(forms.Form):
# Poller Category
poller_category = forms.ModelChoiceField(widget=forms.RadioSelect(attrs={
'class': 'poller-category-radio',
}), queryset=Category.objects.all().order_by('category'), label='Select a Category', required=True)
# View
def raise_poller(request):
"""
creates a new Poller object according to user inputs and redirects to it
"""
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = PollersForm(request.POST)
# check whether it's valid:
if form.is_valid():
# process the remaining data in form.cleaned_data as required
poller_category = form.cleaned_data['poller_category']
# Get the user
created_by = request.user
# Save the poller to the database
p = Poller(
poller_category=poller_category,
)
p.save()
# Get the created object and its id to redirect to the single poller view
created_poller = Poller.objects.get(created_by=created_by, id=p.pk)
created_poller_id = created_poller.pk
created_poller_slug = created_poller.slug
poller_url = '/poller/' + str(created_poller_id) + '/' + str(created_poller_slug)
# redirect to a new URL:
return redirect(poller_url, request, created_poller_id)
# if a GET (or any other method) we'll create a blank form
else:
form = PollersForm()
return render(request, 'pollinator/raise_poller.html', {'form': form})
<!-- Template -->
<form action="/raisepoller/" method="post">
{% csrf_token %}
{{ form.non_field_errors }}
{{ form.errors }}
<!-- Poller Categories -->
<div class="fieldWrapper">
<div class="label">{{ form.poller_category.label_tag }}</div>
<div class="category-ctn">
{% for category in form.poller_category %}
<div class="category-wrapper">{{ category }}</div>
{% endfor %}
</div>
</div>
<!-- Submit Button -->
<button type="submit" value="Publish Poller" id="raise-poller-button">
<div class="button-wrapper">
<div class="button-icon"><img id="button-image" src="{% static 'images/send.png' %}"></div>
<div class="button-text">Publish Poller</div>
</div>
</button>
</form>
...呈现:
<div class="category-wrapper"><label for="id_poller_category_1"><input type="radio" name="poller_category" value="5" class="poller-category-radio" id="id_poller_category_1" required="">
Environment</label></div>
/* CSS */
.category-wrapper input {
position: fixed;
visibility: hidden;
}
.category-wrapper label {
display: inline-block;
background-color: #fdfdfd;
color: var(--main-darkblue-color);
padding: 0.2vw 0.5vw;
font-size: 1vw;
border: 2px solid #444;
border-radius: 4px;
margin-bottom: 0;
}
最佳答案
It seems that
if request.method == 'POST':
returnsFalse
if no category is selected on submit.
浏览器甚至不发送请求,因为 HTML5 验证失败。
由于输入
上的可见性:隐藏
,因此未显示验证消息。
.category-wrapper input {
position: fixed;
visibility: hidden;
}
...这会导致浏览器控制台中显示此错误:
❗An invalid form control with name='category' is not focusable.
相反,使其透明、无宽度且无边距:
.category-wrapper input {
margin: 0;
opacity: 0;
width: 0;
}
关于html - 如果未选择任何选项,带有 ModelChoiceField(required=True) 的表单不会引发 ValidationError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69465326/