Определите css-класс в django Forms
-
03-07-2019 - |
Вопрос
Предположим, у меня есть форма
class SampleClass(forms.Form):
name = forms.CharField(max_length=30)
age = forms.IntegerField()
django_hacker = forms.BooleanField(required=False)
Есть ли у меня способ определить css-классы для каждого поля таким образом, чтобы я мог затем использовать jQuery на основе class на моей отображаемой странице?
Я надеялся, что мне не придется вручную создавать форму.
Решение 2
Ответил на мой собственный вопрос. Вздох
http://docs.djangoproject.com/en/dev/ref/forms/widgets/#django.forms .Виджет.ссылки
Я не понимал, что это было передано в конструктор виджетов.
Другие советы
Еще одно решение, которое не требует изменений в коде Python и поэтому лучше подходит для дизайнеров и разовых изменений в презентации: django-виджет-настройки.Надеюсь, кому-нибудь это покажется полезным.
Вот еще одно решение для добавления определений классов к виджетам после объявления полей в классе.
def __init__(self, *args, **kwargs):
super(SampleClass, self).__init__(*args, **kwargs)
self.fields['name'].widget.attrs['class'] = 'my_class'
Использование django-виджет-настройки, он прост в использовании и работает довольно хорошо.
В противном случае это можно сделать с помощью пользовательского фильтра шаблона.
Учитывая, что вы таким образом отображаете свою форму :
<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 - это экземпляр Граничное поле который обладает как_виджет способ.
вы можете создать пользовательский фильтр "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 будут отрисованы с помощью css-класса MyClass.
Надеюсь, это поможет.
ПРАВКА 1
Обновите фильтр в соответствии с димиГвот ответ
Добавить ссылку django-widget-tweak
ПРАВКА 2
- Обновите фильтр в соответствии с Бхидкомментарий автора
Расширяя информацию о методе, на который указывает at 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'
Мне это кажется немного чище.
Если вы хотите, чтобы все поля в форме наследовали определенный класс, вы просто определяете родительский класс, который наследуется от 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'
класс для всех полей во всех формах моего приложения создается автоматически, без добавления репликации кода.
Вот простой способ изменить представление.добавьте ниже в поле зрения непосредственно перед передачей его в шаблон.
form = MyForm(instance = instance.obj)
form.fields['email'].widget.attrs = {'class':'here_class_name'}
Просто добавьте классы в свою форму следующим образом.
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'
}
))
Вот вариант вышеизложенного, который присвоит всем полям один и тот же класс (напримерjquery красиво закруглил углы).
# 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'
В случае, если вы хотите добавить класс в поле формы в шаблоне (не в view.py или form.py) например, в случаях, когда вы хотите изменять сторонние приложения без переопределения их представлений, используйте шаблон фильтра, как описано в Чарльстонк ответ это очень удобно.Но в этом ответе фильтр шаблона переопределяет все существующие классы, которые могут быть у поля.
Я попытался добавить это в качестве правки, но было предложено записать как новый ответ.
Итак, вот тег шаблона, который учитывает существующие классы поля:
from django import template
register = template.Library()
@register.filter(name='addclass')
def addclass(field, given_class):
existing_classes = field.field.widget.attrs.get('class', None)
if existing_classes:
if existing_classes.find(given_class) == -1:
# if the given class doesn't exist in the existing classes
classes = existing_classes + ' ' + given_class
else:
classes = existing_classes
else:
classes = given_class
return field.as_widget(attrs={"class": classes})
Вы можете попробовать вот это..
class SampleClass(forms.Form):
name = forms.CharField(max_length=30)
name.widget.attrs.update({'class': 'your-class'})
...
Вы можете ознакомиться с более подробной информацией в разделе: Виджеты Django
Как оказалось, вы можете сделать это в конструкторе формы (инициализация функция) или после того, как был инициирован класс формы.Иногда это требуется, если вы не пишете свою собственную форму и эта форма поступает откуда-то еще -
def some_view(request):
add_css_to_fields = ['list','of','fields']
if request.method == 'POST':
form = SomeForm(request.POST)
if form.is_valid():
return HttpResponseRedirect('/thanks/')
else:
form = SomeForm()
for key in form.fields.keys():
if key in add_css_to_fields:
field = form.fields[key]
css_addition = 'css_addition '
css = field.widget.attrs.get('class', '')
field.widget.attrs['class'] = css_addition + css_classes
return render(request, 'template_name.html', {'form': form})
Вы также могли бы использовать Хрустящие формы Django, это отличный инструмент для определения форм на случай, если вы захотите использовать какой-нибудь CSS-фреймворк, такой как Bootstrap или Foundation.И там легко указать классы для полей вашей формы.
Тогда вашему классу form это понравилось бы:
from django import forms
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Div, Submit, Field
from crispy_forms.bootstrap import FormActions
class SampleClass(forms.Form):
name = forms.CharField(max_length=30)
age = forms.IntegerField()
django_hacker = forms.BooleanField(required=False)
helper = FormHelper()
helper.form_class = 'your-form-class'
helper.layout = Layout(
Field('name', css_class='name-class'),
Field('age', css_class='age-class'),
Field('django_hacker', css-class='hacker-class'),
FormActions(
Submit('save_changes', 'Save changes'),
)
)