将字段值传递给自定义 layout.Field
Pass field value to custom layout.Field
我正在定义自定义布局对象:
Field('slider', template="custom-slider.html")
如 documentation 所示:
我的自定义滑块是:
<div class="slider slider-green" data-prefix="€ " data-postfix=",-" data-min="0" data-max="1800" data-value="223"></div>
但我想参数化这些值。我怎样才能做到这一点?使用 layout.Field 时如何将值传递给模板?如何从相关的表单域中获取 min/max 值?
slider = forms.IntegerField(label="slider", min_value=3, max_value=50)
如果我理解正确,custom-slider.html 是一个功能齐全的 django 模板。上下文是什么?它是否有权访问相关的表单字段?如何?我找不到示例。
有 field
上下文变量传递给包含 FormField
对象的模板。所以你应该能够做到这一点:
<div class="slider slider-green" data-prefix="€ " data-postfix=",-"
data-min="{{ field.field.min_value }}" data-max="{{ field.field.max_value }}"
data-value="{{ field.value }}"></div>
您必须执行 field.field
的原因是传递给模板的 field
是 BoundField
object, rather than the IntegerField
that you defined in your form class. That object is stored in BoundField.field
- 因此 field.field
.
BoundField
有一个 value()
方法,这就是 field.value
起作用的原因。
我将把我目前的进展放在这里,尽管这还没有解决(但我希望我越来越接近)。我尝试了以下方法来解决这个问题:
已使用 django-debug-toolbar:很好,但是复杂模板的上下文转储不可读。这只是一个巨大的 __repr__
转储,根本无法浏览,并且缺少信息(因为 __repr__
必须缩短)
在模板中使用了 {% debug %}
:更糟。我看不懂。它可能对小型模板有帮助,但如果您有一个包含 5 个字段和三个其他模板标签的表单,祝您阅读顺利。
used a pdb
breakpoint 访问上下文。 pdb
为您提供上下文的交互界面,但使用起来并不容易。
- 使用了
ipdb
断点。这样好一点,但不是possible to use magic functions(虽然都列出来了)。
- 使用了 embedded ipython shell。这是一个游戏规则改变者。突然之间,您可以轻松浏览上下文、相关函数、代码,自动漂亮地打印所有内容,使用制表符完成,...
我的 templatetags
是(文件 templatetags/debug.py
):
from django.template import Library, Node
register = Library()
class PdbNode(Node):
def render(self, context):
import pdb as pdb_module
pdb_module.set_trace()
return ''
class IPdbNode(Node):
def render(self, context):
import ipdb as ipdb_module
ipdb_module.set_trace()
return ''
class EmbedIPythonNode(Node):
def render(self, context):
from IPython import embed
embed()
return ''
@register.tag
def pdb(parser, token):
return PdbNode()
@register.tag
def ipdb(parser, token):
return IPdbNode()
@register.tag
def ipython(parser, token):
return EmbedIPythonNode()
您可以在模板中使用它,例如:
{% load debug %}
{% ipython %}
{% pdb %}
{% ipdb %}
<row>
<div class="col-lg-6""></div>
<div class="col-lg-6"">
<div class="slider {{field.extra_class}}" data-prefix="{{field.prefix}}" data-postfix="{{field.postfix}}" data-min="{{widget.min}}" data-max="{{widget.max}}" data-value="{{field.value}}"></div>
</div>
</row>
(你需要 pip install
ipython
和 ipdb
)
这是一个示例会话:
In [15]: dir(context.dicts[5]['field'])
Out[15]:
['__class__',
'__delattr__',
'__dict__',
'__doc__',
'__format__',
'__getattribute__',
'__getitem__',
'__hash__',
'__html__',
'__init__',
'__iter__',
'__len__',
'__module__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__setattr__',
'__sizeof__',
'__str__',
'__subclasshook__',
'__unicode__',
'__weakref__',
'_initial_value',
'as_hidden',
'as_text',
'as_textarea',
'as_widget',
'auto_id',
'css_classes',
'data',
'errors',
'field',
'form',
'help_text',
'html_initial_id',
'html_initial_name',
'html_name',
'id_for_label',
'is_hidden',
'label',
'label_tag',
'name',
'value']
感谢 ipython
shell,我能够发现最大值在 {{field.field.max_value}}
中。不知道为什么需要双字段说明符,但它有效。
我正在定义自定义布局对象:
Field('slider', template="custom-slider.html")
如 documentation 所示:
我的自定义滑块是:
<div class="slider slider-green" data-prefix="€ " data-postfix=",-" data-min="0" data-max="1800" data-value="223"></div>
但我想参数化这些值。我怎样才能做到这一点?使用 layout.Field 时如何将值传递给模板?如何从相关的表单域中获取 min/max 值?
slider = forms.IntegerField(label="slider", min_value=3, max_value=50)
如果我理解正确,custom-slider.html 是一个功能齐全的 django 模板。上下文是什么?它是否有权访问相关的表单字段?如何?我找不到示例。
有 field
上下文变量传递给包含 FormField
对象的模板。所以你应该能够做到这一点:
<div class="slider slider-green" data-prefix="€ " data-postfix=",-"
data-min="{{ field.field.min_value }}" data-max="{{ field.field.max_value }}"
data-value="{{ field.value }}"></div>
您必须执行 field.field
的原因是传递给模板的 field
是 BoundField
object, rather than the IntegerField
that you defined in your form class. That object is stored in BoundField.field
- 因此 field.field
.
BoundField
有一个 value()
方法,这就是 field.value
起作用的原因。
我将把我目前的进展放在这里,尽管这还没有解决(但我希望我越来越接近)。我尝试了以下方法来解决这个问题:
已使用 django-debug-toolbar:很好,但是复杂模板的上下文转储不可读。这只是一个巨大的
__repr__
转储,根本无法浏览,并且缺少信息(因为__repr__
必须缩短)在模板中使用了
{% debug %}
:更糟。我看不懂。它可能对小型模板有帮助,但如果您有一个包含 5 个字段和三个其他模板标签的表单,祝您阅读顺利。used a
pdb
breakpoint 访问上下文。pdb
为您提供上下文的交互界面,但使用起来并不容易。- 使用了
ipdb
断点。这样好一点,但不是possible to use magic functions(虽然都列出来了)。 - 使用了 embedded ipython shell。这是一个游戏规则改变者。突然之间,您可以轻松浏览上下文、相关函数、代码,自动漂亮地打印所有内容,使用制表符完成,...
我的 templatetags
是(文件 templatetags/debug.py
):
from django.template import Library, Node
register = Library()
class PdbNode(Node):
def render(self, context):
import pdb as pdb_module
pdb_module.set_trace()
return ''
class IPdbNode(Node):
def render(self, context):
import ipdb as ipdb_module
ipdb_module.set_trace()
return ''
class EmbedIPythonNode(Node):
def render(self, context):
from IPython import embed
embed()
return ''
@register.tag
def pdb(parser, token):
return PdbNode()
@register.tag
def ipdb(parser, token):
return IPdbNode()
@register.tag
def ipython(parser, token):
return EmbedIPythonNode()
您可以在模板中使用它,例如:
{% load debug %}
{% ipython %}
{% pdb %}
{% ipdb %}
<row>
<div class="col-lg-6""></div>
<div class="col-lg-6"">
<div class="slider {{field.extra_class}}" data-prefix="{{field.prefix}}" data-postfix="{{field.postfix}}" data-min="{{widget.min}}" data-max="{{widget.max}}" data-value="{{field.value}}"></div>
</div>
</row>
(你需要 pip install
ipython
和 ipdb
)
这是一个示例会话:
In [15]: dir(context.dicts[5]['field'])
Out[15]:
['__class__',
'__delattr__',
'__dict__',
'__doc__',
'__format__',
'__getattribute__',
'__getitem__',
'__hash__',
'__html__',
'__init__',
'__iter__',
'__len__',
'__module__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__setattr__',
'__sizeof__',
'__str__',
'__subclasshook__',
'__unicode__',
'__weakref__',
'_initial_value',
'as_hidden',
'as_text',
'as_textarea',
'as_widget',
'auto_id',
'css_classes',
'data',
'errors',
'field',
'form',
'help_text',
'html_initial_id',
'html_initial_name',
'html_name',
'id_for_label',
'is_hidden',
'label',
'label_tag',
'name',
'value']
感谢 ipython
shell,我能够发现最大值在 {{field.field.max_value}}
中。不知道为什么需要双字段说明符,但它有效。