CSS-стилизация в формах Django - PullRequest
121 голосов
/ 29 апреля 2011

Мне бы хотелось написать следующее:

forms.py:

from django import forms

class ContactForm(forms.Form):
    subject = forms.CharField(max_length=100)
    email = forms.EmailField(required=False)
    message = forms.CharField(widget=forms.Textarea)

contact_form.html:

<form action="" method="post">
  <table>
    {{ form.as_table }}
  </table>
  <input type="submit" value="Submit">
</form>

Например, как мне установить class или ID для subject, email, message, чтобы предоставить внешнюю таблицу стилей для?

Ответы [ 14 ]

154 голосов
/ 29 апреля 2011

Взято из моего ответа на: Как разметить поля формы с помощью

class MyForm(forms.Form):
    myfield = forms.CharField(widget=forms.TextInput(attrs={'class' : 'myfieldclass'}))

или

class MyForm(forms.ModelForm):
    class Meta:
        model = MyModel

    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        self.fields['myfield'].widget.attrs.update({'class' : 'myfieldclass'})

или

class MyForm(forms.ModelForm):
    class Meta:
        model = MyModel
        widgets = {
            'myfield': forms.TextInput(attrs={'class': 'myfieldclass'}),
        }

--- РЕДАКТИРОВАТЬ ---
Вышеуказанное является самым простым изменением в исходном коде вопроса, которое выполняет то, что было задано. Это также удерживает вас от повторения, если вы повторно используете форму в других местах; ваши классы или другие атрибуты просто работают, если вы используете методы формы Django as_table / as_ul / as_p. Если вам нужен полный контроль для полностью настраиваемого рендеринга, это четко задокументировано

- РЕДАКТИРОВАТЬ 2 ---
Добавлен новый способ указания виджета и атрибутов для ModelForm.

86 голосов
/ 23 сентября 2013

Это можно сделать с помощью пользовательского шаблона фильтра.Рассмотрите возможность визуализации вашей формы следующим образом:

<form action="/contact/" method="post">
  {{ form.non_field_errors }}
  <div class="fieldWrapper">
    {{ form.subject.errors }}
    {{ form.subject.label_tag }}
    {{ form.subject }}
    <span class="helptext">{{ form.subject.help_text }}</span>
  </div>
</form>

form.subject является экземпляром BoundField, который имеет метод as_widget().

Вы можете создатьпользовательский фильтр addclass в my_app / templatetags / myfilters.py :

from django import template

register = template.Library()

@register.filter(name='addclass')
def addclass(value, arg):
    return value.as_widget(attrs={'class': arg})

А затем примените свой фильтр:

{% load myfilters %}

<form action="/contact/" method="post">
  {{ form.non_field_errors }}
  <div class="fieldWrapper">
    {{ form.subject.errors }}
    {{ form.subject.label_tag }}
    {{ form.subject|addclass:'MyClass' }}
    <span class="helptext">{{ form.subject.help_text }}</span>
  </div>
</form>

form.subjects будетвизуализируется с помощью MyClass CSS-класса.

28 голосов
/ 09 мая 2011

Если вы не хотите добавлять любой код в форму (как упомянуто в комментариях к ответу @ shadfc), это, безусловно, возможно, здесь есть два варианта.

Во-первых, вы просто ссылаетесь на поля индивидуально в HTML, а не на всю форму сразу:

<form action="" method="post">
    <ul class="contactList">
        <li id="subject" class="contact">{{ form.subject }}</li>
        <li id="email" class="contact">{{ form.email }}</li>
        <li id="message" class="contact">{{ form.message }}</li>
    </ul>
    <input type="submit" value="Submit">
</form>

(Обратите внимание, что я также изменил его на несортированный список .)

Во-вторых, обратите внимание в документах на вывод форм в виде HTML , Django:

Идентификатор поля, генерируется добавляя 'id_' к имени поля. Атрибуты id и теги включен в вывод по умолчанию.

Все ваши поля формы уже имеют уникальный id . Таким образом, вы должны ссылаться на id_subject в вашем CSS-файле, чтобы стилизовать поле subject . Должен отметить, что вот как ведет себя форма, когда вы берете по умолчанию HTML, для которого требуется просто распечатать форму, а не отдельные поля:

<ul class="contactList">
    {{ form }}  # Will auto-generate HTML with id_subject, id_email, email_message 
    {{ form.as_ul }} # might also work, haven't tested
</ul>

Смотрите предыдущую ссылку для других опций при выводе форм (вы можете создавать таблицы и т. Д.).

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

#id_subject, #id_email, #email_message 
{color: red;}
11 голосов
/ 11 октября 2015

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

from django import template
register = template.Library()

@register.filter(name='addcss')
def addcss(field, css):
    return field.as_widget(attrs={"class":css})

Поместите это в папку templatetags / вашего приложения, и вытеперь можно сделать

{{field|addcss:"form-control"}}
11 голосов
/ 29 апреля 2011

Вы можете сделать так:

class ContactForm(forms.Form):
    subject = forms.CharField(max_length=100)
    subject.widget.attrs.update({'id' : 'your_id'})

Надеюсь, что это работает.

Игнас

7 голосов
/ 22 марта 2013

Вы можете использовать эту библиотеку: https://pypi.python.org/pypi/django-widget-tweaks

Это позволяет вам делать следующее:

{% load widget_tweaks %}
<!-- add 2 extra css classes to field element -->
{{ form.title|add_class:"css_class_1 css_class_2" }}
5 голосов
/ 29 апреля 2011

Вы можете сделать:

<form action="" method="post">
    <table>
        {% for field in form %}
        <tr><td>{{field}}</td></tr>
        {% endfor %}
    </table>
    <input type="submit" value="Submit">
</form>

Затем вы можете добавить классы / идентификаторы, например, к тегу <td>. Конечно, вы можете использовать любые другие теги, которые вы хотите. Отметьте Работа с формами Django в качестве примера того, что доступно для каждого field в форме (например, {{field}} просто выводит входной тег, а не метку и т. Д.).

3 голосов
/ 04 апреля 2015

Не видел этого на самом деле ...

https://docs.djangoproject.com/en/1.8/ref/forms/api/#more-granular-output

Более гранулированный выход

Методы as_p (), as_ul () и as_table () - это просто ярлыки для ленивых разработчиков - они не единственный способ отображения объекта формы.

класс BoundField Используется для отображения HTML или доступа к атрибутам для одного поля экземпляра формы.

Метод этого объекта str () ( unicode на Python 2) отображает HTML-код для этого поля.

Чтобы получить один BoundField, используйте синтаксис поиска по словарю в форме, используя имя поля в качестве ключа:

>>> form = ContactForm()
>>> print(form['subject'])
<input id="id_subject" type="text" name="subject" maxlength="100" />

Чтобы получить все объекты BoundField, выполните итерацию формы:

>>> form = ContactForm()
>>> for boundfield in form: print(boundfield)
<input id="id_subject" type="text" name="subject" maxlength="100" />
<input type="text" name="message" id="id_message" />
<input type="email" name="sender" id="id_sender" />
<input type="checkbox" name="cc_myself" id="id_cc_myself" />

Вывод для конкретного поля учитывает параметр auto_id объекта формы:

>>> f = ContactForm(auto_id=False)
>>> print(f['message'])
<input type="text" name="message" />
>>> f = ContactForm(auto_id='id_%s')
>>> print(f['message'])
<input type="text" name="message" id="id_message" />
2 голосов
/ 13 апреля 2017

Существует очень простой в установке и прекрасный инструмент, созданный для Django, который я использую для стилей, и его можно использовать для любого фреймворка, такого как Bootstrap, Materialize, Foundation и т. Д. Он называется widget-tweaks Документация: Настройки виджета

  1. Вы можете использовать его с общими представлениями Django
  2. Или с вашими собственными формами:

из форм импорта Django

class ContactForm(forms.Form):
    subject = forms.CharField(max_length=100)
    email = forms.EmailField(required=False)
    message = forms.CharField(widget=forms.Textarea)

Вместо использования по умолчанию:

{{ form.as_p }} or {{ form.as_ul }}

Вы можете редактировать его по-своему, используя атрибут render_field, который дает вам более html-подобный стиль его оформления, как в этом примере:

template.html

{% load widget_tweaks %}

<div class="container">
   <div class="col-md-4">
      {% render_field form.subject class+="form-control myCSSclass" placeholder="Enter your subject here" %}
   </div>
   <div class="col-md-4">
      {% render_field form.email type="email" class+="myCSSclassX myCSSclass2" %}
   </div>
   <div class="col-md-4">
      {% render_field form.message class+="myCSSclass" rows="4" cols="6" placeholder=form.message.label %}
   </div>
</div>

Эта библиотека дает вам возможность хорошо отделить свой внешний интерфейс от вашего внутреннего интерфейса

2 голосов
/ 28 января 2017

Одним из решений является использование JavaScript для добавления необходимых классов CSS после того, как страница готова.Например, стилизация вывода формы django с помощью классов начальной загрузки (для краткости используется jQuery):

<script type="text/javascript">
    $(document).ready(function() {
        $('#some_django_form_id').find("input[type='text'], select, textarea").each(function(index, element) {
            $(element).addClass("form-control");
        });
    });
</script>

Это позволяет избежать уродства смешения спецификаций стиля с вашей бизнес-логикой.

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