ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

python – 自定义小部件仅在第一次不验证

2019-07-09 09:56:00  阅读:170  来源: 互联网

标签:python django django-forms django-widget


我已经创建了一个自定义小部件OrderedCheckboxSelectMultiple,我只是替换了< ul>对于< ol>并将一些类添加到< label>,< li>等:

class OrderedCheckboxSelectMultiple(forms.CheckboxSelectMultiple):

    def render(self, name, value, attrs=None, choices=()):
        if value is None: value = []
        has_id = attrs and 'id' in attrs
        final_attrs = self.build_attrs(attrs, name=name)
        output = [u'<ol class="numeric">']
        # Normalize to strings
        str_values = set([force_unicode(v) for v in value])
        for i, (option_value, option_label) in enumerate(chain(self.choices, choices)):
            # If an ID attribute was given, add a numeric index as a suffix,
            # so that the checkboxes don't all have the same ID attribute.
            if has_id:
                final_attrs = dict(final_attrs, id='%s_%s' % (attrs['id'], i))
                label_for = u' for="%s"' % final_attrs['id']
            else:
                label_for = ''

            cb = forms.CheckboxInput(final_attrs, check_test=lambda value: value in str_values)
            option_value = force_unicode(option_value)
            rendered_cb = cb.render(name, option_value)
            option_label = conditional_escape(force_unicode(option_label))
            output.append(u'<li class="liAll"><label%s class="checkbox inline">%s <span class="spanLabel">%s</span></label></li>' % (
                label_for, rendered_cb, option_label))
        output.append(u'</ol>')
        return mark_safe(u'\n'.join(output))

我在两个不同的字段中使用此窗口小部件:

class SomeForm(forms.Form):
    # more fields here

    alert1 = forms.MultipleChoiceField(choices=[(a.id, a.description) for a in SomeModel.objects.filter(a=True)],
                                             widget=OrderedCheckboxSelectMultiple())
    alert2 = forms.MultipleChoiceField(choices=[(a.id, a.description) for a in SomeModel.objects.filter(b=True)],
                                             widget=OrderedCheckboxSelectMultiple())

问题是,当我第一次提交表单时,我收到验证错误:

Select a valid choice. is not one of the available choices.

然后,当我再次勾选选项时,它会毫无问题地验证.我迷失在这里.有什么建议?

注意:

如果我使用forms.CheckboxSelectMultiple作为alert1和alert2的小部件,也会发生同样的事情.

编辑:

在调试时,我可以看到alert1和alert2在我第一次提交时没有出现在request.POST上.

对不起,我搞错了. alert1和alert2出现在request.POST上,但是尽管被勾选,它们都是你的.

编辑2:

使用Chrome的“Inspect元素”,我可以看到第一次正确渲染表单:

<ol class="numeric">
    <li class="liAll">
        <label for="id_alert1_0" class="checkbox inline">
            <div class="checker" id="uniform-id_alert1_0">
                <span>
                    <input value="1" type="checkbox" class="check" name="alert1" id="id_alert1_0" style="opacity: 0;">
                </span>
            </div>
        </label>
    </li>
    <li class="liAll">
        <label for="id_alert1_1" class="checkbox inline">
            <div class="checker" id="uniform-id_alert1_1">
                <span>
                    <input id="id_alert1_1" type="checkbox" class="check" value="2" name="alert1" style="opacity: 0;">
                </span>
            </div>
        </label>
    </li>
</ol>

然后再次显示验证消息,但渲染的表单看起来相同:

<ol class="numeric">
    <li class="liAll">
        <label for="id_alert1_0" class="checkbox inline">
            <div class="checker" id="uniform-id_alert1_0">
                <span>
                    <input value="1" type="checkbox" class="check" name="alert1" id="id_alert1_0" style="opacity: 0;">
                </span>
            </div>
        </label>
    </li>
    <li class="liAll">
        <label for="id_alert1_1" class="checkbox inline">
            <div class="checker" id="uniform-id_alert1_1">
                <span>
                    <input id="id_alert1_1" type="checkbox" class="check" value="2" name="alert1" style="opacity: 0;">
                </span>
            </div>
        </label>
    </li>
</ol>

我正在使用提交按钮提交帖子:

<button type="submit" class="btn btn-primary">Send</button>

解决方法:

我在快速的django应用程序中复制并粘贴了您的代码.工作对我来说很好.错误可能还有其他地方吗? OS x上的Django 1.4.

views.py

class OrderedCheckboxSelectMultiple(CheckboxSelectMultiple):
    def render(self, name, value, attrs=None, choices=()):
        if value is None: value = []
        has_id = attrs and 'id' in attrs
        final_attrs = self.build_attrs(attrs, name=name)
        output = [u'<ol class="numeric">']
        # Normalize to strings
        str_values = set([force_unicode(v) for v in value])
        for i, (option_value, option_label) in enumerate(chain(self.choices, choices)):
            # If an ID attribute was given, add a numeric index as a suffix,
            # so that the checkboxes don't all have the same ID attribute.
            if has_id:
                final_attrs = dict(final_attrs, id='%s_%s' % (attrs['id'], i))
                label_for = u' for="%s"' % final_attrs['id']
            else:
                label_for = ''

            cb = CheckboxInput(final_attrs, check_test=lambda value: value in str_values)
            option_value = force_unicode(option_value)
            rendered_cb = cb.render(name, option_value)
            option_label = conditional_escape(force_unicode(option_label))
            output.append(u'<li class="liAll"><label%s class="checkbox inline">%s <span class="spanLabel">%s</span></label></li>' % (
            label_for, rendered_cb, option_label))
            output.append(u'</ol>')
        return mark_safe(u'\n'.join(output))

class SomeForm(forms.Form):
    alert1 = MultipleChoiceField(choices=[(a.id, a.name) for a in Widget.objects.filter(a=False)],
                                         widget=OrderedCheckboxSelectMultiple())
    alert2 = MultipleChoiceField(choices=[(a.id, a.name) for a in Widget.objects.filter(a=False)],
                                         widget=OrderedCheckboxSelectMultiple())

def index(request):
    if request.method =="POST":
        form = SomeForm(request.POST)
        print(request.POST.keys())
        if form.is_valid():
            print("trying to save")
    else:
        form = SomeForm()
    return render_to_response('publichome.html', locals(), context_instance=RequestContext(request))

标签:python,django,django-forms,django-widget
来源: https://codeday.me/bug/20190709/1411908.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有