【问题标题】:Adding a conditional class to a Django field's label将条件类添加到 Django 字段的标签
【发布时间】:2018-07-31 11:42:18
【问题描述】:

我正在尝试重构手动呈现字段的 Django 模板(参见https://docs.djangoproject.com/en/2.0/topics/forms/#rendering-fields-manually)。标签生成如下:

  <label for="{{ field.id_for_label }}"
      class="{% if field.value %}active{% endif %} {% if field.errors %}invalid{% endif %}">
  </label>

field 使用 {% for field in form %} ... {% endfor %} 循环。

我正在尝试通过编写自定义过滤器来重构它(参见https://docs.djangoproject.com/en/2.0/howto/custom-template-tags/#writing-custom-template-filters)。到目前为止,我已经想出了以下内容。在templatetags 目录中,我添加了一个label_with_classes.py,其内容为

from django import template

register = template.Library()

@register.filter(is_safe=True)
def label_with_classes(value, arg):
    return value.label_tag(attrs={'class': arg})

我用它来替换上面的 HTML

  {{ field|label_with_classes:"active"}}

问题是这实际上并没有做原始模板所做的事情;它总是用 "active" 类标记它,并且不实现条件逻辑。

我的问题:是否可以使用过滤器来实现此逻辑?过滤函数的value 输入参数实际上代表什么,是field.value(顾名思义)还是field 本身?

【问题讨论】:

    标签: python html django django-templates django-template-filters


    【解决方案1】:

    通过在开发服务器运行时进入调试器并刷新页面,我发现value 实际上是BoundField 的一个实例,它有一个value() 方法和一个errors 属性:

    > /Users/kurtpeek/Documents/Dev/lucy/lucy-web/dashboard/templatetags/label_with_classes.py(8)label_with_classes()
          7     import ipdb; ipdb.set_trace()
    ----> 8     return value.label_tag(attrs={'class': arg})
          9 
    
    ipdb> value
    <django.forms.boundfield.BoundField object at 0x113957eb8>
    ipdb> dir(value)
    ['__bool__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__html__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__module__', '__ne__', '__new__', '__nonzero__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'as_hidden', 'as_text', 'as_textarea', 'as_widget', 'auto_id', 'build_widget_attrs', 'css_classes', 'data', 'errors', 'field', 'form', 'help_text', 'html_initial_id', 'html_initial_name', 'html_name', 'id_for_label', 'initial', 'is_hidden', 'label', 'label_tag', 'name', 'subwidgets', 'value']
    ipdb> value.errors
    []
    ipdb> value.value
    <bound method BoundField.value of <django.forms.boundfield.BoundField object at 0x113957eb8>>
    ipdb> value.value()
    4
    

    我对变量value 的使用有点困惑,并改名为虚拟变量bound_field

    以下是我实现条件类的自定义过滤器的方法(templatetags/label_with_classes.py):

    from django import template
    
    register = template.Library()
    
    
    @register.filter(is_safe=True)
    def label_with_classes(bound_field):
        classes = f"{'active' if bound_field.value() else ''} {'invalid' if bound_field.errors else ''}"
        return bound_field.label_tag(attrs={'class': classes.strip()})
    

    之后,&lt;label&gt; 元素可以在模板中替换为

    {% load label_with_classes %}
    
    {% for field in form %}
      {{ field|label_with_classes }}
    {% endfor %}
    

    【讨论】:

      猜你喜欢
      • 2021-06-21
      • 2018-05-31
      • 2014-04-26
      • 2020-12-21
      • 2012-10-22
      • 2012-02-17
      • 1970-01-01
      • 1970-01-01
      • 2018-07-12
      相关资源
      最近更新 更多