Jquery Django forms.MultiValueField,widget设置为widget.MultiWidget;正确的验证方法?
多表单小部件允许我们有一些隐藏字段,如_0 _1等,而不是。在您的forms.MultiValueField需要开始在clean()方法中抛出ValidationError()之前,这一切都非常有效 事实上。。。ValidationError()将表单错误设置为而不是_0或其他任何错误 而不是在每个视图中编写一个“if”包装器来捕获此字段名并将其交换到_0。。。在MultiWidget或MultiValueField中有没有更干净的方法 我尝试在MultiValueField clean()函数中抛出:ValidationError({'myfieldname_0':['my error',]}),但是当它在更高级别被捕获时,它只会将'my_error'保存回self中。\在'myfieldname'散列中的表单错误(没有_0)。在“site packages/django/forms/forms.py”中,它似乎以这种方式得到了清理。无论如何,这种方法的另一个问题是,它需要我硬编码“myfieldname”,而我不想这样做 简言之,我希望使用MultiWidget使表单简单且易于管理,但我希望验证在该字段的哈希响应中添加_0(在字段名称的末尾),以匹配放入的实际输入记录。这使得集成jquery.validation()变得更加容易。我也愿意接受这个糟糕的设计。。。也许我只需要MutilValueField,而不是MutilWidget耸耸肩 下面是设置我的问题的示例代码:Jquery Django forms.MultiValueField,widget设置为widget.MultiWidget;正确的验证方法?,jquery,django,Jquery,Django,多表单小部件允许我们有一些隐藏字段,如_0 _1等,而不是。在您的forms.MultiValueField需要开始在clean()方法中抛出ValidationError()之前,这一切都非常有效 事实上。。。ValidationError()将表单错误设置为而不是_0或其他任何错误 而不是在每个视图中编写一个“if”包装器来捕获此字段名并将其交换到_0。。。在MultiWidget或MultiValueField中有没有更干净的方法 我尝试在MultiValueField clean()函数
from django.forms import MultiWidget
from django.forms import MultiValueField
from django.forms import ModelForm
from django.forms import widgets
class MyWidget(MultiWidget):
"""
"""
def __init__(self, attrs=None, **kwargs):
# Populated once render() is called
self.name = u''
_widgets = (
widgets.TextInput(attrs=attrs),
widgets.HiddenInput(attrs=None),
widgets.HiddenInput(attrs=None),
)
super(MyWidget, self).__init__(_widgets, attrs=None, **kwargs)
def value_from_datadict(self, data, files, name):
return [ widget.value_from_datadict(data, files, name + '_%s' % i)
for i, widget in enumerate(self.widgets)]
class MyFormField(MultiValueField):
"""
Significantly simplified just to show my problem
"""
widget = MyWidget
def clean(self, value):
# I want to some how alter how this exception is thrown so it isn't put in
# the self._errors['<fieldname>'] hash, but instead placed in
# the self._errors['<fieldname>'_0] hash
raise ValidationError(self.error_messages['required'])
class MyForm(ModelForm):
"""
Simple form example of how I'd use the field
"""
class Meta:
model = <some model>
performer = MyFormField(
max_length=100,
required=True,
)
来自django.forms的导入多窗口小部件
从django.forms导入多值字段
从django.forms导入ModelForm
从django.forms导入小部件
类MyWidget(多窗口小部件):
"""
"""
定义初始化(self,attrs=None,**kwargs):
#调用render()后填充
self.name=u“”
_小部件=(
TextInput(attrs=attrs),
widgets.HiddenInput(attrs=None),
widgets.HiddenInput(attrs=None),
)
super(MyWidget,self)。\uuuuu init\uuuuuuu(\uwidgets,attrs=None,**kwargs)
def value_from_datadict(自身、数据、文件、名称):
从\u datadict(数据、文件、名称+')返回[widget.value\u%s'%i]
对于i,枚举中的小部件(self.widgets)]
类别MyFormField(多值字段):
"""
大大简化了我的问题
"""
widget=MyWidget
def清洁(自身,值):
#我想知道如何改变这个异常的抛出方式,以便它不会被放入
#self._errors['']散列,但放在
#self.\u errors[''\u 0]散列
引发ValidationError(self.error\u消息['required'])
类MyForm(ModelForm):
"""
我将如何使用该字段的简单表单示例
"""
类元:
型号=
performer=MyFormField(
最大长度=100,
必需=真,
)
您还可以在MultiValueField的compress方法中捕获异常,这将允许您为整个字段添加异常。我维护了一个扩展多值字段的函数 初始化和压缩部分是:
class FeetAndInchesField(MultiValueField):
widget = FeetAndInchesWidget
def __init__(self, *args, **kwargs):
errors = self.default_error_messages.copy()
if 'error_messages' in kwargs:
errors.update(kwargs['error_messages'])
localize = kwargs.get('localize', False)
fields = (
IntegerField(min_value=0, required=False, localize=localize),
IntegerField(min_value=0, localize=localize),
FloatField()
)
super(FeetAndInchesField, self).__init__(fields, *args, **kwargs)
def compress(self, data_list):
if data_list:
feet = data_list[0]
inches = data_list[1]
fractional_inches = data_list[2]
if feet == inches == fractional_inches == 0:
raise ValidationError(u'Please specify a value for feet or inches')
return sum_feet_inches_fractional_inches(feet, inches, fractional_inches)
return None
这应该允许您为所有字段或字段组合引发异常,而不是一次引发一个异常。希望这对您有所帮助。我通过如下更改MultiWidget的默认操作解决了这个问题:
from django.forms import MultiWidget as DjangoMultiWidget
from django.utils.safestring import mark_safe
class MultiWidget(DjangoMultiWidget):
"""
This widget djusts the extends the existing MultiWidget to not
place an _<index> on the first widget
Hence a list of 3 widgets would look like:
<input name="fieldname"/>
<input name="fieldname_0"/>
<input name="fieldname_1"/>
"""
def __init__(self, *attrs, **kwargs):
# Populated once render() is called
self.name = u''
super(MultiWidget, self).__init__(*attrs, **kwargs)
def render(self, name, value, attrs=None):
"""
We over-ride this so we can correctly extract the name
"""
# Save Name
self.name = name
if self.is_localized:
for widget in self.widgets:
widget.is_localized = self.is_localized
# value is a list of values, each corresponding to a widget
# in self.widgets.
if not isinstance(value, list):
value = self.decompress(value)
output = []
final_attrs = self.build_attrs(attrs)
id_ = final_attrs.get('id', None)
# First Entry is not prefixed with underscore (_)
try:
widget_value = value[0]
except IndexError:
widget_value = None
output.append(self.widgets[0].render(name, widget_value, final_attrs))
# now we process the rest
for i, widget in enumerate(self.widgets[1:]):
try:
widget_value = value[i]
except IndexError:
widget_value = None
if id_:
final_attrs = dict(final_attrs, id='%s_%s' % (id_, i))
output.append(widget.render(name + '_%s' % i, widget_value, final_attrs))
return mark_safe(self.format_output(output))
def format_output(self, rendered_widgets):
"""
Place an error class
"""
return u''.join(rendered_widgets) + \
u'<div class="error" for="id_%s" style="display: none;"></div>' % self.name
def value_from_datadict(self, data, files, name):
return [ self.widgets[0].value_from_datadict(data, files, name) ] + \
[ widget.value_from_datadict(data, files, name + '_%s' % i)
for i, widget in enumerate(self.widgets[1:]) ]
来自django.forms的将多窗口小部件作为DjangoMultiWidget导入
从django.utils.safestring导入标记_safe
类MultiWidget(DjangoMultiWidget):
"""
此小部件将现有多小部件的扩展调整为“不”
在第一个小部件上放置u
因此,包含3个小部件的列表如下所示:
"""
定义初始值(self,*attrs,**kwargs):
#调用render()后填充
self.name=u“”
超级(多窗口小部件,自我)。\uuuuu初始化(*attrs,**kwargs)
def render(自身、名称、值、属性=无):
"""
我们忽略了这一点,以便正确提取名称
"""
#保存名称
self.name=名称
如果self.u已本地化:
对于self.widgets中的小部件:
widget.is_localized=self.is_localized
#value是一个值列表,每个值对应一个小部件
#在self.widgets中。
如果不存在(值,列表):
值=自我解压缩(值)
输出=[]
最终属性=自生成属性(属性)
id=最终属性获取('id',无)
#第一个条目的前缀不带下划线(389;)
尝试:
小部件_值=值[0]
除索引器外:
widget_value=None
output.append(self.widgets[0].render(名称、widget\u值、最终属性))
#现在我们来处理剩下的
对于i,枚举中的小部件(self.widgets[1:]):
尝试:
小部件_值=值[i]
除索引器外:
widget_value=None
如果id u3;:
final\u attrs=dict(final\u attrs,id='%s\u%s'(id\u,i))
output.append(widget.render(name+'.%s'%i,widget\u值,final\u属性))
返回标记\u安全(自格式化\u输出(输出))
def格式_输出(自、渲染_小部件):
"""
放置一个错误类
"""
返回u“”。加入(呈现的_小部件)+\
u''%self.name
def value_from_datadict(自身、数据、文件、名称):
返回[self.widgets[0]。值\u来自\u datadict(数据、文件、名称)]+\
[widget.value_来自_datadict(数据、文件、名称+)u%s“%i)
对于i,枚举中的小部件(self.widgets[1:])]
这里没有什么神奇之处,因为大部分代码都是直接从/django/forms/fields.py中提取出来的
但是,以这种方式使用字段允许您在不使用_0的情况下引发标准异常,但它实际上引用了存储在以下位置的字段内容:
<input name="fieldname"/>
<input name="fieldname_0"/>
<input name="fieldname_1"/>
而不是默认的多窗口小部件样式:
<input name="fieldname_0"/>
<input name="fieldname_1"/>
<input name="fieldname_2"/>
最终结果是Django的框架和错误处理b