Django:在模板中渲染表单字段时添加CSS类

时间:2010-11-08 13:26:01

标签: python django forms

我在像{{ form.first_name }}这样的模板中输出表单的字段,我想在其中添加一个类(例如蓝图的 span-x - 类)。所以我想知道是否有一个很好的现成解决方案(模板过滤器),我可以在时尚{{ form.first_name|add_class:"span-4" }}中使用它? (我只是想知道Django的开发人员或任何人在我自己做之前是否已经想到了这一点)

8 个答案:

答案 0 :(得分:46)

您只需要安装Django widget_tweaks

pip install django-widget-tweaks

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

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

-

阅读所有相关内容here

答案 1 :(得分:22)

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

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

答案 2 :(得分: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&gt; general_tools_app&gt; templatetags&gt; add_class.py

general_tools_app是一个应用程序,它收集我添加到新django项目中的有用功能。

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

在settings.py中,我的INSTALLED_APPS元组包含条目'mydjangoproject.general_tools_app'。

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

{{ myfield|add_class:'delete' }}

答案 3 :(得分:10)

另一种方法是在字段上使用as_widget方法来改变它 - 比正则表达式方法更简单,更安全,并且不需要任何其他依赖项。

定义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" }}

您还可以使用as_widget添加其他属性,例如placeholder等。

答案 4 :(得分:5)

我还在学习Django,但你不能这样做 -

from django import forms

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

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

答案 5 :(得分:3)

关于lazerscience解决方案的另一个注意事项:如果将此应用于&lt; select&gt;没有class属性的元素,else语句中的字符串替换会产生如下内容:

<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)将确保只有“&gt;”的第一个实例将替换为“class =”...“&gt ;,这对于任何表单元素在逻辑上都是正确的。

答案 6 :(得分:0)

您需要明确指定窗口小部件并使用attrs keyword argument添加该类。我不知道其他任何方式。

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

答案 7 :(得分:0)

已针对python3更新

更新很简单,只需要在打印上加上括号,然后将unicode(value)更改为str(value),我也很快将'class =“%s”>'更改为fstring。

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 = str(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('>', f' class="{css_class}">'))
    return value