我正在运行Django 2.2,并编写了一个简单的购物车。我希望同时验证两个字段,以确保两个字段不能同时为空。在我的forms.py中,
from django import forms
class CartAddProductForm(forms.Form):
cc_handle = forms.CharField(required=False, label='CC Handle', empty_value='')
lc_handle = forms.CharField(required=False, label='LC Handle', empty_value='')
def clean(self):
cleaned_data = super().clean()
if cleaned_data.get('cc_handle') == '' and cleaned_data.get('lc_handle') == '':
print("issue detected")
raise forms.ValidationError('Either cc or lc handle is required.')
return cleaned_data
这是遵循官方Django docs进行的清洁和验证彼此依赖的字段的操作。上面的print()语句让我知道已检测到问题,即两个字段均为空。在运行Django服务器时,我发现确实已检测到该问题,但是在原始页面顶部未显示任何验证错误消息。原始页面是包含产品和将产品添加到购物车的链接的产品页面。通常,验证错误消息会显示在页面顶部。
根据文档,验证是在调用is_valid()时完成的。所以我把自己的views.py
打印出来from django.shortcuts import render, redirect, get_object_or_404
from django.views.decorators.http import require_POST
from shop.models import Product
from .cart import Cart
from .forms import CartAddProductForm
@require_POST
def cart_add(request, product_id):
cart = Cart(request)
product = get_object_or_404(Product, id=product_id)
form = CartAddProductForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
cart.add(product=product,
cc_handle=cd['cc_handle'],
lc_handle=cd['lc_handle'])
else:
print('invalid form')
return redirect('cart:cart_detail')
确实出现了“无效表格”字样。然后,代码将我带到购物车。相反,我想要的是在产品页面上并显示验证错误,通知读者两个字段不能为空。有简单的方法吗?
对于表单中的required = True字段,如果我将其保留为空白,则会弹出一条消息,提示我需要填写。所以我想做类似的事情,除了验证要求两个字段都不能空的。
这与Stackoverflow answer不同,因为这是注册表格。您可以将其重定向到相同的表单,在这种情况下,CartAddProductForm嵌入在站点上的所有产品页面中。如果可能的话,我希望验证与使用required = True选项的字段在同一阶段进行。
product / detail.html模板如下所示。
{% extends "shop/base.html" %}
{% load static %}
{% block title %}
{{ product.name }}
{% endblock %}
{% block content %}
<div class="product-detail">
<img src="{% if product.image %}{{ product.image.url }}{% else %}{% static "img/no_image.png" %}{% endif %}">
<h1>{{ product.name }}</h1>
<h2><a href="{{ product.category.get_absolute_url }}">{{ product.category }}</a></h2>
<p class="price">${{ product.price }}</p>
<form action="{% url "cart:cart_add" product.id %}" method="post">
{{ cart_product_form }}
{% csrf_token %}
<input type="submit" value="Add to cart">
</form>
{{ product.description|linebreaks }}
</div>
{% endblock %}
答案 0 :(得分:2)
在表单模板中添加此行已清除您的问题。
{{ cart_product_form.non_field_errors }}
product / detail.html:
{% extends "shop/base.html" %}
{% load static %}
{% block title %}
{{ product.name }}
{% endblock %}
{% block content %}
<div class="product-detail">
<img src="{% if product.image %}{{ product.image.url }}{% else %}{% static "img/no_image.png" %}{% endif %}">
<h1>{{ product.name }}</h1>
<h2><a href="{{ product.category.get_absolute_url }}">{{ product.category }}</a></h2>
<p class="price">${{ product.price }}</p>
<form action="{% url "cart:cart_add" product.id %}" method="post">
{{ cart_product_form }}
{% csrf_token %}
{{ cart_product_form.non_field_errors }} // This line will raise validation errors
<input type="submit" value="Add to cart">
</form>
{{ product.description|linebreaks }}
</div>
{% endblock %}
文档:(从官方文档复制)
请注意,您的Form.clean()覆盖引发的任何错误都不会 尤其与任何领域相关联。他们进入特殊 “字段”(称为 all ),您可以通过 如果需要,可以使用non_field_errors()方法。如果您要附加错误 到表单中的特定字段,您需要调用add_error()。
答案 1 :(得分:0)
您的视图将无条件地重定向到cart_details
,因此您不会看到验证错误也就不足为奇了-您必须为此呈现无效的表单。您仅应在发布成功后重定向。