Django: добавление классов CSS при рендеринге полей формы в шаблоне - PullRequest
32 голосов
/ 08 ноября 2010

Я выводю поля формы в шаблоне, подобном этому {{ form.first_name }}, и я хотел бы добавить к нему класс (например, класс * blueprint span-x ).Поэтому я хотел бы знать, есть ли хорошее готовое решение (шаблонный фильтр) для этого, которое я мог бы использовать в моде {{ form.first_name|add_class:"span-4" }}?(Я просто хочу знать, думали ли разработчики Django или кто-либо еще об этом без моего ведома, прежде чем делать это самостоятельно)

Ответы [ 7 ]

46 голосов
/ 06 сентября 2011

Вам нужно только установить Django widget_tweaks

pip install django-widget-tweaks

После того, как вы сможете сделать что-то подобное в вашем шаблоне:

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

-

Читать всеоб этом здесь .

22 голосов
/ 08 ноября 2010

Чтобы решить эту проблему, я создал собственный шаблонный фильтр, который можно применить к любому тегу, а не только к элементам ввода!

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
12 голосов
/ 07 декабря 2010

Несколько дополнительных заметок о том, как начать работу с очень удобным решением 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> general_tools_app> templatetags> 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' }}
11 голосов
/ 04 декабря 2014

Другой способ - использовать метод as_widget в поле, чтобы изменить его - проще и безопаснее, чем подход регулярных выражений, и не требует никаких дополнительных зависимостей.

Определить пользовательский шаблонный фильтр :

@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 и т. Д.

5 голосов
/ 08 ноября 2010

Я все еще изучаю Джанго, но не мог бы ты сделать что-то вроде этого -

from django import forms

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

Я полагаю, что нет необходимости делать это на уровне шаблона (или использовать фильтры), если у вас нет требований, которые я не понял.

3 голосов
/ 10 февраля 2011

Еще одно замечание о решении lazerscience: если вы примените это к элементу

<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">

I'mУверен, что браузеры отбрасывают эти посторонние определения классов, но это много замен строк, когда вам нужно только одно.Простое решение для этого:

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

Этот последний аргумент (1) обеспечит замену только первого экземпляра ">" на "class =" ... ">, что логически правильнодля любого элемента формы.

0 голосов
/ 08 ноября 2010

Вам необходимо явно указать виджет и добавить класс с помощью ключевого аргумента attrs . Я не знаю другого пути.

Однако, если это слишком громоздко, вы все равно можете просто обернуть поле в другой элемент, такой как div или span, и добавить к нему класс. Затем измените свой CSS соответственно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...