如何访问,如果现场有)的错误在控件的水平?
使用默认我想:
{% if widget.attributes.has_errors %} or {% if widget.has_errors %}
但不工作。
我使用自定义窗口小部件的模板,我想使用自定义表单字段,并覆盖默认的字段。
我知道clean
方法存在,但我不知道该怎么推到插件的动态(非默认)数据/属性我想要的。
我试过了:
class AWidget(forms.Widget):
def get_context(self, name, value, attrs):
context = super().get_context(name, value, attrs)
has_errors = context['widget']['attrs'].pop('has_errors', None)
context['widget']['has_errors'] = has_errors
它适用于errors
,但我不知道是否是最佳的选择再加上我想通过其他值从表格字段/属性,我认为将是更好的尝试覆盖表单域,但我完全不知道怎么样。
还访问使用各个属性:
{{ widget.attrs.maxlength }} or {{ widget.attrs.items.maxlength }}
即使在入世背景for循环工程
我知道我可以添加父DIV一类错误:
<div class="{% if form.field.errors %}pass_error{% endif %}">
{{ form.field }}
</div>
但是,这意味着在CSS级别大的变化。
我已经覆盖所有Django的部件与自定义部件,对错误我不需要只是改变边框颜色,而是要显示或不widget模板的不同元素和它们中的一些改变位置。
我已经修改了基于小部件添加的错误,但我希望通过从现场路过给小窗口以做一个更优雅的方式在外地,根据错误类型参数。
所以我的问题是我需要覆盖从现场传递给小部件错误和其他变量?
不知道,这是否可以在您的具体使用情况下帮助......但为了以防万一,请注意,当您在视图中建立自己的表单,您可以添加额外的参数可以根据需要,再通过他们到您的自定义窗口小部件。
工作示例:
文件“forms.py”
from django import forms
def build_ingredient_form(unit):
"""
Ingredient form factory
Here we build the form class dynamically, in order to acces 'unit' via closure.
References:
http://stackoverflow.com/questions/622982/django-passing-custom-form-parameters-to-formset#623030
"""
class IngredientForm(forms.Form):
#quantity = forms.DecimalField(max_digits=10)
quantity = UnitField(unit, required=False)
...
return IngredientForm
文件“fields.py”
from django import forms
from .fields import UnitField
class UnitField(forms.CharField):
"""
Custom field to support UnitWidget
References:
- http://tothinkornottothink.com/post/10815277049/django-forms-i-custom-fields-and-widgets-in
"""
def __init__(self, unit, *args, **kwargs):
self.unit = unit
super(UnitField, self).__init__(*args, **kwargs)
self.widget = UnitWidget(unit)
...
文件“widgets.py”
from django import forms
from .models import Unit
class UnitWidget(forms.TextInput):
def __init__(self, unit, attrs=None):
if unit is None:
self.unit = Unit()
else:
self.unit = unit
...
好一个widget是你将如何呈现的字段的数据/值到HTML呈现模板,这就是小部件的唯一功能,目光从文档采取下面的例子:
>>> name = forms.TextInput(attrs={'required': True})
>>> name.render('name', 'A name')
'<input name="name" type="text" value="A name" required>'
>>>
>>> name = forms.TextInput(attrs={'required': False})
>>> name.render('name', 'A name')
'<input name="name" type="text" value="A name">'
所以,窗口小部件不知道数据是否有效(有错误),或者也不应该保持这种方式。
是不是要处理的部件级别的任何数据错误/验证一个好主意,你愿意,我可以保证,如果你改变你的领域的样子(小部件),您的验证继续工作。
说...
当你渲染的形式由现场客户可以通过例如采取这种形式,你可以做到这一点现场:
class LoginForm(forms.Form):
username = forms.CharField(max_length=255)
password = forms.CharField(widget=forms.PasswordInput)
您可以写信给模板:
<form action="." method="get">
<p>{{ loginform.username.label }}: {{ loginform.username }}</p>
<p>{{ loginform.password.label }}: {{ loginform.password}}</p>
<button type="submit">submit</button>
</form>
而这将使得类似如下:
现在,假设你的表单不会少于8个字符的密码承认:
class LoginForm(forms.Form):
username = forms.CharField(max_length=255)
password = forms.CharField(widget=forms.PasswordInput)
def clean_password(self):
password = self.cleaned_data['password']
if len(password) < 8:
raise forms.ValidationError(
"Password must have at least 8 characters, it has only %(password_length)s",
code='invalid password',
params={'password_length': len(password)}
)
return password
你可以像这样访问密码错误:
<form action="." method="get">
{% csrf_token %}
<p>{{ form.username.label }}: {{ form.username }}</p>
<p>{{ form.password.label }}: {{ form.password}}</p>
<ul>
{% for error in form.password.errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
<button type="submit">submit</button>
</form>
现在,如果你键入一个短密码...
如果有错误,只是在你的模板代码使用{% if ... %}
您可以添加一些样式:
<p>
{{ form.password.label }}:
<span class="{% if form.password.errors %}pass_error{% endif %}">
{{ form.password }}
</span>
</p>
使用CSS:
<style>
.pass_error input {
border-color: red;
}
</style>
这是结果:
验证并在窗体或使用validators处理数据错误,使用小部件用于显示数据,当然,你可以自定义数据的显示方式,因为你可以为你的widget指定自定义模板。
我还建议django-widget-twaeks如果你想将属性添加到模板代码中的小部件。该应用程序允许你写的代码一样(例如,从应用程序文档):
{% load widget_tweaks %}
<!-- change input type (e.g. to HTML5) -->
{% render_field form.search_query type="search" %}
<!-- add/change several attributes -->
{% render_field form.text rows="20" cols="20" title="Hello, world!" %}
<!-- append to an attribute -->
{% render_field form.title class+="css_class_1 css_class_2" %}
<!-- template variables can be used as attribute values -->
{% render_field form.text placeholder=form.text.label %}