我正在使用 HTMX 和 Django 提交联系表单,而无需刷新页面。当表单出现错误时,我的后端会正确返回 contact_messages.html 模板,但请求后页面中不会出现错误。
我可以在“网络”选项卡中看到正确的响应,并且 contact_messages.html 包含预期的验证消息。但是,HTMX 不会更新我的 contact.html 文件中的 div#contact-messages。
在尝试使用 HTMX 之前,Django 内置的表单验证工作得很好。但是,众所周知,这个过程是同步的,我想用 HTMX 将其变成异步的。
这是我的观点:
class ContactView(FormView):
template_name = 'contact/contact.html'
form_class = ContactForm
success_url = reverse_lazy('contact')
def form_valid(self, form):
messages.success(self.request, "Your message has been sent. We will be in touch with you as soon as possible.")
return redirect(self.success_url + '#contact-section')
def form_invalid(self, form):
messages.error(
self.request,
"There were some errors in your submission. Please review the highlighted fields and try again",
extra_tags="danger")
if self.request.headers.get("HX-Request"):
return render(self.request, "contact/contact_messages.html", {"form": form}, content_type="text/html", status=400)
return super().form_invalid(form)
这是我在 contact.html 中的表格:
<form id="contact-form" method="post" hx-post="{% url 'contact' %}"
hx-target="#contact-messages" hx-swap="innerHTML" novalidate>
{% csrf_token %}
<div id='contact-messages'>
{% include 'contact/contact_messages.html' %}
</div>
<div class="form-group mb-0">
<button class=" btn btn-primary w-100">
<span>Send Message</span>
</button>
</div>
</form>
这是我的辅助模板 contact_messages.html:
% if messages %}
{% for message in messages %}
<div class="alert alert-{{ message.tags }}" role="alert">
{{ message }}
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span></button>
</div>
{% endfor %}
{% endif %}
{% for field in form %}
<div class="form-group">
{{ field }}
{% if form.errors %}
<div class="invalid-feedback d-block">
{% for error in field.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
{% endfor %}
在这里您可以看到 Django 返回了正确的响应,但我无法让它反映在 contact.html 中。
根据设计,当返回错误响应(4xx)时,HTMX 不会交换内容。
这是解决这个问题的一种方法:
HTMX - 允许 HTTP 错误 400 和 422 交换内容以显示验证错误
另一种方法是简单地返回
200
而不是400
。