代码之家  ›  专栏  ›  技术社区  ›  Bernhard Vallant

Django:在模板中呈现表单字段时添加CSS类

  •  32
  • Bernhard Vallant  · 技术社区  · 14 年前

    我在这样的模板中输出表单的字段 {{ form.first_name }} 我想增加一个类(如蓝图 斯潘-X -类)到它。所以我想知道是否有一个很好的现成的解决方案(模板过滤器),我可以在时尚中使用。 {{ form.first_name|add_class:"span-4" }} ?(我只想知道Django的开发人员或任何人在我自己动手之前是否在我不知情的情况下考虑过这个问题)

    7 回复  |  直到 10 年前
        1
  •  46
  •   Paul Fleming    12 年前

    您只需要安装django小部件

    pip install django-widget-tweaks
    

    在您可以在模板上执行类似的操作之后:

    {{ form.search_query|attr:"type:search" }}
    

    ——

    阅读所有相关内容 here .

        2
  •  22
  •   Paul Fleming    12 年前

    为了解决这个问题,我制作了自己的模板过滤器,您可以将它应用于任何标记,而不仅仅是输入元素!

    class_re = re.compile(r'(?<=class=["\'])(.*)(?=["\'])')
    @register.filter
    def add_class(value, css_class):
        string = unicode(value)
        match = class_re.search(string)
        if match:
            m = re.search(r'^%s$|^%s\s|\s%s\s|\s%s$' % (css_class, css_class, 
                                                        css_class, css_class), 
                                                        match.group(1))
            print match.group(1)
            if not m:
                return mark_safe(class_re.sub(match.group(1) + " " + css_class, 
                                              string))
        else:
            return mark_safe(string.replace('>', ' class="%s">' % css_class))
        return value
    
        3
  •  12
  •   Paul Fleming    12 年前

    关于如何使用Lazerscience非常方便的解决方案的一些额外说明。以下是使用依赖项导入时文件的外观:

    import re
    from django.utils.safestring import mark_safe
    from django import template
    register = template.Library()
    
    class_re = re.compile(r'(?<=class=["\'])(.*)(?=["\'])')
    @register.filter
    def add_class(value, css_class):
        string = unicode(value)
        match = class_re.search(string)
        if match:
            m = re.search(r'^%s$|^%s\s|\s%s\s|\s%s$' % (css_class, css_class, 
                                                        css_class, css_class), 
                                                        match.group(1))
            print match.group(1)
            if not m:
                return mark_safe(class_re.sub(match.group(1) + " " + css_class, 
                                              string))
        else:
            return mark_safe(string.replace('>', ' class="%s">' % css_class))
        return value
    

    我把它粘贴到一个名为add_class.py的文件中。目录结构为: mydjangoproject>通用工具&u app>模板标签>添加&u class.py

    通用工具应用程序是一个应用程序,它收集像这样有用的功能,我添加到新的Django项目中。

    (General_tools_app和templateTags目录都有一个空的 __init__.py 文件以便正确注册)

    在settings.py中,我安装的_-apps tuple包含条目“mydjangoproject.general_-tools_-app”。

    为了在模板中使用过滤器,我添加了一行 {% load add_class %} 在文件的顶部。如果我想将类“delete”添加到字段中,我会这样做。

    {{ myfield|add_class:'delete' }}
    
        4
  •  10
  •   user85461    10 年前

    另一种方法是使用 as_widget 方法来改变它——比regex方法更简单、更安全,并且不需要任何额外的依赖项。

    定义 custom template filter :

    @register.filter
    def add_class(field, class_name):
        return field.as_widget(attrs={
            "class": " ".join((field.css_classes(), class_name))
        })
    

    在模板中:

    {{ form.first_name|add_class:"span-4" }}
    

    您也可以使用 作为\小部件 添加其他属性,例如 placeholder 等。

        5
  •  5
  •   Paul Fleming    12 年前

    我还在学姜戈,但你不能这样做吗?-

    from django import forms
    
    class SomeForm(forms.Form):
        f = forms.CharField(label='x',widget=forms.TextInput(attrs={'class':'name'}))
    

    我想在模板级别(或者使用过滤器)没有必要这样做,除非您有一些我不理解的需求。

        6
  •  3
  •   Paul Fleming    12 年前

    关于Lazerscience解决方案的另一个注意事项:如果您将此应用于没有class属性的<select>元素,则在其他情况下,字符串替换将产生如下结果:

    <select name="state" id="id_state" class="class1 class2">
        <option value="AL" class="class1 class2">Alabama</option class="class1 class2">
        <option value="AK" class="class1 class2">Alaska</option class="class1 class2">
        <option value="AZ" class="class1 class2">Arizona</option class="class1 class2">
    </select class="class1 class2">
    

    我敢肯定浏览器会废弃那些无关的类定义,但当您只需要一个类定义时,这是大量的字符串替换。一个简单的补救方法:

    return mark_safe(string.replace('>', ' class="%s">' % css_class, 1))
    

    最后一个参数(1)将确保仅将“>!”的第一个实例替换为“class=”..“>,这在逻辑上对任何表单元素都是正确的。

        7
  •  0
  •   Deniz Dogan    14 年前

    您需要显式指定小部件并使用 attrs keyword argument . 我知道没有别的办法。

    但是,如果这太麻烦了,您仍然可以将字段包装在另一个元素中,比如DIV或SPAN,并向其中添加一个类。然后相应地修改您的CSS。