【问题标题】:how to add <div> tag instead of <li>如何添加 <div> 标签而不是 <li>
【发布时间】:2013-09-06 16:18:21
【问题描述】:

forms.py

class TypeSelectionForm(forms.Form):
    checkbox_field = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple(), label="", required=False)

def __init__(self, type_id, *args, **kwargs):
    super(TypeSelectionForm, self).__init__(*args, **kwargs)

    _type_checkbox = self.fields['checkbox_field']       
    MY_CHOICES=((type.id, type.title) for type in type)
    _type_checkbox.choices = MY_CHOICES
    initial_val = []
    type_selection = Types.objects.filter(parent_type_id=type_id,is_active=True)
    for type_selection in type_selection:
        initial_val.append(type_selection.id)
    _type_checkbox.initial = initial_val

views.py

def types(method):
    """"""""""""
    types = TypeSelectionForm(type_id)
    return render(request,'types.html',{'types':types})

在模板中,我正在渲染这样的字段,

types.html

    {% for field in types.checkbox_field %}                                 
     <div class="deletelist">
     {{field}}<br />
    </div>
   {% endfor %}

它正在生成这样的html,

<ul>
<li><label for="id_checkbox_field_0"><input checked="checked" type="checkbox" name="checkbox_field" value="597" id="id_checkbox_field_0" /> comp lab</label></li>
<li><label for="id_checkbox_field_1"><input checked="checked" type="checkbox" name="checkbox_field" value="598" id="id_checkbox_field_1" /> phy lab</label></li>
<li><label for="id_checkbox_field_2"><input checked="checked" type="checkbox" name="checkbox_field" value="599" id="id_checkbox_field_2" /> chem lab</label></li>
</ul>

我想用&lt;div class="class-name"&gt; 替换&lt;ul&gt;&lt;li&gt; 标签

需要帮助。

【问题讨论】:

  • MY_CHOICES=((type.id, type.title) for type in type),这将显示类型对象的 id 和标题。在该类上添加一个 unicode 方法来回答您希望显示的内容,然后只需使用 MY_CHOICES=(type for type in type),这在编程上看起来很奇怪。另外,你为什么不使用 ModelMultipleChoiceField?
  • @professorDante 在模板中显示正确,我手动添加了一个复选框字段,当尝试保存它时它没有被保存所以检查并且在视图中它给出了这个错误“类型对象不可迭代“。但是根据 django doc 1.4,如果我们迭代 form.fieldname,它应该显示带有值的复选框以及添加的 div。现在我使用的是 django 1.4.1,那么为什么我的应用程序不支持它

标签: python django django-models django-forms django-templates


【解决方案1】:

为什么不使用 Django 模板标签的强大功能?

from django import template
from django.utils.safestring import mark_safe
register = template.Library()


@register.filter("as_div")
def as_div(form):
    form_as_div = form.as_ul().replace("<ul", "<div").replace("</ul", "</div")
    form_as_div = form_as_div.replace("<li", "<div").replace("</li", "</div")
    return mark_safe(form_as_div)

把它放在模板标签中,然后在你的模板中简单地做这个

{% load ad_div %}

{# some Code #}

{{ form|as_div }}

{# some other code #} 

=============================

其他方法(更好的清洁剂)

另一种方法是扩展 django 表单模型

如下

from django.forms.forms import BaseForm

Class AsDiv(BaseForm):

def as_div(self):
        return self._html_output(
            normal_row = u'<div%(html_class_attr)s>%(errors)s%(label)s %(field)s%(help_text)s</div>',
            error_row = u'<div>%s</div>',
            row_ender = '</div>',
            help_text_html = u' <span class="helptext">%s</span>',
            errors_on_separate_row = False)

那么你可以这样做是你的模板

{{ form.as_div }} 

【讨论】:

  • 您的解决方案看起来很简单,我要试试这个。在模板标记方法中,我应该使用我的表单名称,而不是表单,在我的案例中,表单被替换为“TypeSelectionForm”是否正确。跨度>
  • 是的,你必须用持有表单对象的变量名替换它
  • 您的模板标签解决方案运行良好,我可以将通用类应用于所有 div。我需要更多帮助,我需要为 div 内的所有表单字段提供一个按钮。每个 div 都有一个按钮。可以在这里做吗。谢谢。
  • 你可以还是不能?我不明白。您想为每个 div 添加不同的类还是为所有 div 添加相同的类。如果不同,那么定义哪个 div 采用哪个类的标准是什么
  • 我可以对所有 div 应用相同的类,我要问的是是否可以在该 div 中包含/添加一个输入按钮。
【解决方案2】:

来自documentation

Django 1.4 中的新功能。

要对生成的标记进行更精细的控制,您可以循环 模板中的单选按钮。假设表格myform 带有 使用RadioSelect 作为其小部件的字段beatles

{% for radio in myform.beatles %}
<div class="myradio">
    {{ radio }}
</div>
{% endfor %}

在你的模板中,你应该有这个:

{% for radio in types.checkbox_field %}
   <input style="margin: 8px -3px;float: left;" type="button" class="delete_types" id="delete_name"/>{{ radio }}
{% endfor %}

您还应该使用ModelMultipleChoiceField

class TypeSelectionForm(forms.Form):
    checkbox_field = forms.ModelMultipleChoiceField(label="",
                                                    queryset=Types.objects.none(),
                                                    required=False)

    def __init__(self, *args, **kwargs):
        qs = kwargs.pop('queryset')
        super(TypeSelectionForm, self).__init__(*args, **kwargs)
        self.fields['checkbox_field'].queryset = qs

从你的角度出发:

def types(method):
    """"""""""""
    qs = Types.objects.filter(parent_type_id=type_id,is_active=True)
    types = TypeSelectionForm(queryset=qs)
    return render(request,'types.html',{'types':'types'})

【讨论】:

  • 我试过这个我得到这个错误“__init__() 需要至少 2 个非关键字参数(1 个给定)”在 views.py “types = TypeSelectionForm(queryset=qs)”中表示这一行.我可以知道如何解决这个问题。
  • 很抱歉,因为这不是针对所有复选框呈现给定图像,而是仅显示一个图像。我在问题中添加了当前输出,我想将该圆形图像添加到所有动态创建的复选框字段。请帮助我执行此操作。
  • 如果你只是复制粘贴的模板代码,那么它是行不通的;你能更新你正在使用的代码吗?
  • 从我更正的文档中,我可以看到添加的所有复选框的图像,但它没有显示复选框及其标签。我更新了有问题的当前输出。请告诉我我可能是什么问题。
  • 删除.field.choices
【解决方案3】:

小部件采用 attrs 属性,该属性应将该属性添加到每个输入。试试这个:

checkbox_field = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple(attrs={'class': 'my-image-class', }), label="", required=False)

更新:

所以看起来上面提到的细粒度方法只适用于单选按钮小部件。但你想要的其实很简单。像往常一样输出你的复选框:

{% for field in types.checkbox_field %}                                 
 {{field}}
{% endfor %}

这将根据需要输出您的复选框列表。然后只需使用一点 CSS 来设置每个列表项的背景图像的样式:

form ul li {
background:url("<my-image>") no-repeat center;
width:20px;
height:20px;

}

更新

如果您想以不同的方式呈现复选框,您需要一个自定义小部件类,因为这是小部件的工作。这样的事情会让你继续前进。我个人会使用小部件上的 attrs 选项来添加一个类,但我在这里对其进行了硬编码,以向您展示您所要求的是可能的,只是不漂亮:

class CheckboxDivSelectMultiple(CheckboxSelectMultiple):
'''renders the checkboxes as divs with a hard coded class'''

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'<div>']
    # 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'<div class="%s"><label%s>%s %s</label></div>' % ('new-class', label_for, rendered_cb, option_label))
    output.append(u'</div>')
    return mark_safe(u'\n'.join(output))

在您的表单中使用它:

checkbox_field = forms.MultipleChoiceField(widget=forms.CheckboxDivSelectMultiple(), label="", required=False)

【讨论】:

  • 这不起作用,这会将 css 类添加到该复选框。
  • 我很困惑 - 这不是你需要的吗?你能显示这是生成的标记吗?
  • 嘿,它正在生成没有复选框的字段。从此文档docs.djangoproject.com/en/1.5/ref/forms/widgets/… 现在正在显示图像,但该字段显示有他们的 ID。请查看我当前的输出有问题。请参阅“我得到的输出”有问题,需要带有所有带有图像的复选框字段的类型。
  • 因为您没有在模板中打印完整的复选框,所以您打印的是:{% for field in types.checkbox_field.field.choices %}。只需使用 {%for field in types %}{{field}}{%endfor%}
  • 您的解决方案很好。再次抱歉再次提出疑问,我的应用程序流程是单击该图像时会显示一个隐藏按钮。您现在给出的解决方案是否可行。如果是,请更新您的回答。现在我了解了实际要求并以明确的要求更新了问题。抱歉没有给出正确的要求。
【解决方案4】:

这类似于@bhappy 的解决方案。整体解决方案是定义一个自定义 as_div 方法并将其用作模板中的模板过滤器。看看这个 django sn-ps 帖子:Custom Form Example: Forms for Bootstrap Html - CSS Toolkit

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-21
    • 2021-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多