在 Django 中仅渲染 MultiWidget 的一部分
Posted
技术标签:
【中文标题】在 Django 中仅渲染 MultiWidget 的一部分【英文标题】:Render only one part of a MultiWidget in Django 【发布时间】:2014-09-12 01:36:21 【问题描述】:我有一个带有 MultiWidget 的 Django 表单字段,它由两个 TextInputs 组成。
在模板中呈现表单时,有方便的表示法
formname.fieldname
用于渲染单个字段。当我将它用于带有 MultiWidget 的字段时,它将显示两个 html 输入元素。是否对仅显示第一个 HTML 输入元素的表示法进行了轻微修改? ( formname.fieldname.0
不起作用。)
【问题讨论】:
【参考方案1】:Philipp Zedler 的回答令人惊叹,但不适用于 Django 3.1,因为渲染的工作方式发生了变化。不幸的是,Django 3.1 的 MultiWidget
似乎有点损坏,所以通过子小部件进行迭代仍然不能正常工作,但幸运的是修复要简单得多。
MultiWidget
似乎缺少以下方法覆盖:
def subwidgets(self, name, value, attrs=None):
context = self.get_context(name, value, attrs)
return context['widget']['subwidgets']
如果您将此方法添加到您自己的MultiWidget
子类中,您将能够按如下方式遍历子小部件:
<h2> form.myfield.label </h2>
<ul>
% for w in form.myfield.subwidgets %
<li> w </li>
% endfor %
</ul>
【讨论】:
【参考方案2】:我找到了解决这个问题的方法,需要两段代码。
第一
将MultiWidget转成字符串的render
方法比较长。我们需要复制并粘贴它,在最后一行稍作修改,使其改为返回数组。
class OurMultiWidget(forms.MultiWidget):
...
def render(self, name, value, attrs=None):
"""Copy and past from original render method"""
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)
for i, widget in enumerate(self.widgets):
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))
# Original:
# return mark_safe(self.format_output(output))
# Only this line was written by myself:
return [mark_safe(self.format_output(x)) for x in output]
第二
在模板中写入 formname.fieldname
会自动调用字段的unicode方法,并将结果视为字符串。因为我们想要一个数组,所以我们需要绕过 unicode 方法并直接访问它将返回的内容。这就是方法as_widget
。因此,要调用OurMultiWidget
的第一部分,我们需要在模板中使用以下代码:
formname.fieldname.as_widget.0
【讨论】:
天哪,我已经找了好几个小时了。谢谢!以上是关于在 Django 中仅渲染 MultiWidget 的一部分的主要内容,如果未能解决你的问题,请参考以下文章