Стиль CSS в формах Django

как мне стилизовать следующее:

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

например, как установить класс или идентификатор для темы, электронной почты, сообщения для предоставления внешней таблицы стилей? Спасибо

13 ответов



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

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

форма.субъект-это экземпляр 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>

форма.затем объекты будут отображаться с помощью css " MyClass класс.

надеюсь, что это поможет.


Если вы не хотите, чтобы добавить любой код к форме (как указано в комментариях к ответу @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, Джанго:

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

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


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

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

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

Игнас


Per этой сообщение в блоге, вы можете добавить классы 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"}}

вы можете использовать эту библиотеку: 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" }}

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

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

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


возможно, Вам не нужно переопределять класс формы'__init__, потому что Django устанавливает name & id атрибуты в HTML inputs. Вы можете иметь CSS следующим образом:

form input[name='subject'] {
    font-size: xx-large;
}

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

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

одним из решений является использование 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>

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


есть очень простой в установке и отличный инструмент для Django, который я использую для укладки, и его можно использовать для каждой фреймворка, как Bootstrap, материализовать, фундамент и т. д. Он называется widget-tweaks Documentation:Виджет Настроек

  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-подобный способ стилизации, как в этом примере:

шаблон.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>

эта библиотека дает вам возможность хорошо отделить передний конец yout от вашего бэкэнда


в Django 1.10 (возможно и раньше) вы можете сделать это следующим образом.

модель:

class Todo(models.Model):
    todo_name = models.CharField(max_length=200)
    todo_description = models.CharField(max_length=200, default="")
    todo_created = models.DateTimeField('date created')
    todo_completed = models.BooleanField(default=False)

    def __str__(self):
        return self.todo_name

форма:

class TodoUpdateForm(forms.ModelForm):
    class Meta:
        model = Todo
        exclude = ('todo_created','todo_completed')

шаблон:

<form action="" method="post">{% csrf_token %}
    {{ form.non_field_errors }}
<div class="fieldWrapper">
    {{ form.todo_name.errors }}
    <label for="{{ form.name.id_for_label }}">Name:</label>
    {{ form.todo_name }}
</div>
<div class="fieldWrapper">
    {{ form.todo_description.errors }}
    <label for="{{ form.todo_description.id_for_label }}">Description</label>
    {{ form.todo_description }}
</div>
    <input type="submit" value="Update" />
</form>

Edit: другой (немного лучший) способ сделать то, что я предлагаю, отвечает здесь: Django форма ввода поля стиль

все вышеперечисленные варианты потрясающие, просто подумал, что я бы бросил этот, потому что он отличается.

если вы хотите пользовательских стилей, классов и т. д. в формах можно ввести html-код в шаблон, соответствующий полю формы. Например, для CharField (виджет по умолчанию TextInput), допустим, вы хотите загрузочный текстовый ввод. Вы бы сделали что-то вроде этого:

<input type="text" class="form-control" name="form_field_name_here">

и пока вы ставите имя поля формы соответствует html name attribue, (и виджет, вероятно, также должен соответствовать типу ввода) Django будет запускать все те же валидаторы в этом поле при запуске validate или form.is_valid() и

стилизация других вещей, таких как метки, сообщения об ошибках и текст справки, не требует много обходного пути, потому что вы можете сделать что-то вроде form.field.error.as_text и стиль их, как вы хотите. Фактические поля-это те, которые требуют некоторой скрипки.

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

вот полезное пошаговое руководство по стилизации форм и включает в себя большинство ответов, перечисленных на SO (например, с помощью attr на виджеты и виджет хитрости.) https://simpleisbetterthancomplex.com/article/2017/08/19/how-to-render-django-form-manually.html