Определить класс CSS в формах Django - PullRequest
173 голосов
/ 30 декабря 2008

Предположим, у меня есть форма

class SampleClass(forms.Form):
    name = forms.CharField(max_length=30)
    age = forms.IntegerField()
    django_hacker = forms.BooleanField(required=False)

Есть ли способ для меня определить классы CSS для каждого поля, чтобы я мог затем использовать jQuery на основе класса в моей отрисованной странице?

Я надеялся, что вам не придется вручную создавать форму.

Ответы [ 13 ]

174 голосов
/ 13 января 2011

Еще одно решение, которое не требует изменений в коде Python и поэтому лучше для дизайнеров и разовых презентационных изменений: django-widget-tweaks . Надеюсь, кто-нибудь найдет это полезным.

85 голосов
/ 30 декабря 2008

ответил на мой вопрос. Вздох

http://docs.djangoproject.com/en/dev/ref/forms/widgets/#django.forms.Widget.attrs

Я не знал, что это было передано в конструктор виджетов.

72 голосов
/ 30 декабря 2008

Вот еще одно решение для добавления определений классов в виджеты после объявления полей в классе.

def __init__(self, *args, **kwargs):
    super(SampleClass, self).__init__(*args, **kwargs)
    self.fields['name'].widget.attrs['class'] = 'my_class'
41 голосов
/ 23 сентября 2013

Используйте django-widget-tweaks , он прост в использовании и работает довольно хорошо.

В противном случае это можно сделать с помощью пользовательского фильтра шаблонов.

Учитывая, что вы визуализируете свою форму следующим образом:

<form action="/contact/" method="post">
    {{ form.non_field_errors }}
    <div class="fieldWrapper">
        {{ form.subject.errors }}
        <label for="id_subject">Email subject:</label>
        {{ form.subject }}
    </div>
</form>

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

вы можете создать собственный фильтр "addcss" в "my_app / templatetags / myfilters.py"

from django import template

register = template.Library()

@register.filter(name='addcss')
def addcss(value, arg):
    css_classes = value.field.widget.attrs.get('class', '').split(' ')
    if css_classes and arg not in css_classes:
        css_classes = '%s %s' % (css_classes, arg)
    return value.as_widget(attrs={'class': css_classes})

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

{% load myfilters %}
<form action="/contact/" method="post">
    {{ form.non_field_errors }}
    <div class="fieldWrapper">
        {{ form.subject.errors }}
        <label for="id_subject">Email subject:</label>
        {{ form.subject|addcss:'MyClass' }}
    </div>
</form>

form.subjects затем будут отображаться с классом "MyClass".

Надеюсь, эта помощь.

РЕДАКТИРОВАТЬ 1

  • Обновление фильтра в соответствии с dimyG ответом

  • Добавить ссылку на django-widget-tweak

РЕДАКТИРОВАТЬ 2

  • Обновление фильтра в соответствии с комментариями Bhyd
31 голосов
/ 25 ноября 2010

Расширение метода, указанного на docs.djangoproject.com:

class MyForm(forms.Form): 
    comment = forms.CharField(
            widget=forms.TextInput(attrs={'size':'40'}))

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

class MyForm(forms.Form): 
    #This instantiates the field w/ the default widget
    comment = forms.CharField()

    #We only override the part we care about
    comment.widget.attrs['size'] = '40'

Это кажется мне чище.

27 голосов
/ 13 декабря 2013

Если вы хотите, чтобы все поля в форме наследовали определенный класс, вы просто определяете родительский класс, который наследует от forms.ModelForm, а затем наследует от него

class BaseForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(BaseForm, self).__init__(*args, **kwargs)
        for field_name, field in self.fields.items():
            field.widget.attrs['class'] = 'someClass'


class WhateverForm(BaseForm):
    class Meta:
        model = SomeModel

Это помогло мне автоматически добавить класс 'form-control' во все поля всех форм моего приложения, не добавляя репликацию кода.

15 голосов
/ 12 января 2011

Вот простой способ изменить вид. добавьте ниже в поле зрения перед передачей в шаблон.

form = MyForm(instance = instance.obj)
form.fields['email'].widget.attrs = {'class':'here_class_name'}
13 голосов
/ 13 августа 2017

Просто добавьте классы в форму следующим образом.

class UserLoginForm(forms.Form):
    username = forms.CharField(widget=forms.TextInput(
        attrs={
        'class':'form-control',
        'placeholder':'Username'
        }
    ))
    password = forms.CharField(widget=forms.PasswordInput(
        attrs={
        'class':'form-control',
        'placeholder':'Password'
        }
    ))
4 голосов
/ 04 марта 2010

Вот вариант выше, который даст всем полям один и тот же класс (например, jquery nice закругленные углы).

  # Simple way to assign css class to every field
  def __init__(self, *args, **kwargs):
    super(TranslatedPageForm, self).__init__(*args, **kwargs)
    for myField in self.fields:
      self.fields[myField].widget.attrs['class'] = 'ui-state-default ui-corner-all'
2 голосов
/ 24 октября 2018

Вы можете попробовать это ..

class SampleClass(forms.Form):
  name = forms.CharField(max_length=30)
  name.widget.attrs.update({'class': 'your-class'})
...

Вы можете увидеть больше информации в: Виджеты Django

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