栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

在Django模板中将CheckboxSelectMultiple分组

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

在Django模板中将CheckboxSelectMultiple分组

你必须编写自定义

CheckboxSelectMultiple
窗口小部件。通过使用代码段,我尝试通过将
CheckboxSelectMultiplefield category_name
作为属性添加到字段中以使字段可迭代
attrs
。这样我以后可以
regroup
在模板中使用标记。

下面的代码根据你的需要从代码段中进行了修改,显然可以使此代码更简洁,更通用,但是目前还不是通用的。

forms.py

from django import formsfrom django.forms import Widgetfrom django.forms.widgets import SubWidgetfrom django.forms.util import flatattfrom django.utils.html import conditional_escapefrom django.utils.encoding import StrAndUnipre, force_uniprefrom django.utils.safestring import mark_safefrom itertools import chainimport astfrom mysite.models import Widget as wid # your model name is conflicted with django.forms.Widgetfrom mysite.models import Featureclass CheckboxInput(SubWidget):    """    An object used by CheckboxRenderer that represents a single    <input type='checkbox'>.    """    def __init__(self, name, value, attrs, choice, index):        self.name, self.value = name, value        self.attrs = attrs        self.choice_value = force_unipre(choice[1])        self.choice_label = force_unipre(choice[2])        self.attrs.update({'cat_name': choice[0]})        self.index = index    def __unipre__(self):        return self.render()    def render(self, name=None, value=None, attrs=None, choices=()):        name = name or self.name        value = value or self.value        attrs = attrs or self.attrs        if 'id' in self.attrs: label_for = ' for="%s_%s"' % (self.attrs['id'], self.index)        else: label_for = ''        choice_label = conditional_escape(force_unipre(self.choice_label))        return mark_safe(u'<label%s>%s %s</label>' % (label_for, self.tag(), choice_label))    def is_checked(self):        return self.choice_value in self.value    def tag(self):        if 'id' in self.attrs: self.attrs['id'] = '%s_%s' % (self.attrs['id'], self.index)        final_attrs = dict(self.attrs, type='checkbox', name=self.name, value=self.choice_value)        if self.is_checked(): final_attrs['checked'] = 'checked'        return mark_safe(u'<input%s />' % flatatt(final_attrs))class CheckboxRenderer(StrAndUnipre):    def __init__(self, name, value, attrs, choices):        self.name, self.value, self.attrs = name, value, attrs        self.choices = choices    def __iter__(self):        for i, choice in enumerate(self.choices): yield CheckboxInput(self.name, self.value, self.attrs.copy(), choice, i)    def __getitem__(self, idx):        choice = self.choices[idx] # Let the IndexError propogate        return CheckboxInput(self.name, self.value, self.attrs.copy(), choice, idx)    def __unipre__(self):        return self.render()    def render(self):        """Outputs a <ul> for this set of checkbox fields."""        return mark_safe(u'<ul>n%sn</ul>' % u'n'.join([u'<li>%s</li>'     % force_unipre(w) for w in self]))class CheckboxSelectMultipleIter(forms.CheckboxSelectMultiple):    """    Checkbox multi select field that enables iteration of each checkbox    Similar to django.forms.widgets.RadioSelect    """    renderer = CheckboxRenderer    def __init__(self, *args, **kwargs):        # Override the default renderer if we were passed one.        renderer = kwargs.pop('renderer', None)        if renderer: self.renderer = renderer        super(CheckboxSelectMultipleIter, self).__init__(*args, **kwargs)    def subwidgets(self, name, value, attrs=None, choices=()):        for widget in self.get_renderer(name, value, attrs, choices): yield widget    def get_renderer(self, name, value, attrs=None, choices=()):        """Returns an instance of the renderer."""        choices_ = [ast.literal_eval(i[1]).iteritems() for i in self.choices]        choices_ = [(a[1], b[1], c[1]) for a, b, c in choices_]        if value is None: value = ''        str_values = set([force_unipre(v) for v in value]) # Normalize to string.        if attrs is None: attrs = {}        if 'id' not in attrs: attrs['id'] = name        final_attrs = self.build_attrs(attrs)        choices = list(chain(choices_, choices))        return self.renderer(name, str_values, final_attrs, choices)    def render(self, name, value, attrs=None, choices=()):        return self.get_renderer(name, value, attrs, choices).render()    def id_for_label(self, id_):        if id_: id_ += '_0'        return id_class WidgetForm(forms.ModelForm):    features = forms.ModelMultipleChoiceField(        queryset=Feature.objects.all().values('id', 'name', 'category__name'),        widget=CheckboxSelectMultipleIter,        required=False    )    class meta:        model = wid

然后在模板中:

{% for field in form %}{% if field.name == 'features' %}     {% regroup field by attrs.cat_name as list %}    <ul>    {% for el in list %}        <li>{{el.grouper}}        <ul> {% for e in el.list %}     {{e}} <br /> {% endfor %}        </ul>        </li>    {% endfor %}    </ul>{% else %}    {{field.label}}: {{field}}{% endif %}{% endfor %}

结果:我在类别表中添加了国家名称,在功能表中添加了城市名称,因此在模板中,我能够根据国家(类别)对城市(功能)进行重新分组



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/432121.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号