Suppose que j'ai un formulaire
class SampleClass(forms.Form):
name = forms.CharField(max_length=30)
age = forms.IntegerField()
Django_hacker = forms.BooleanField(required=False)
Existe-t-il un moyen pour moi de définir des classes CSS sur chaque champ de sorte que je puisse ensuite utiliser jQuery en fonction de la classe dans ma page rendue?
J'espérais ne pas avoir à construire manuellement le formulaire.
Répondu à ma propre question. Soupir
http://docs.djangoproject.com/en/dev/ref/forms/widgets/#Django.forms.Widget.attrs
Je n'avais pas réalisé que cela avait été transmis au constructeur du widget.
Encore une autre solution qui ne nécessite aucune modification du code python et qui est donc préférable pour les concepteurs et les modifications de présentation uniques: Django-widget-tweaks . J'espère que quelqu'un le trouvera utile.
Voici une autre solution pour ajouter des définitions de classe aux widgets après avoir déclaré les champs de la classe.
def __init__(self, *args, **kwargs):
super(SampleClass, self).__init__(*args, **kwargs)
self.fields['name'].widget.attrs['class'] = 'my_class'
Utilisez Django-widget-tweaks , il est facile à utiliser et fonctionne plutôt bien.
Sinon, vous pouvez utiliser un filtre de modèle personnalisé.
En considérant que vous rendez votre formulaire de cette façon:
<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 est une instance de BoundField qui a la méthode as_widget.
vous pouvez créer un filtre personnalisé "addcss" dans "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})
Et ensuite appliquez votre filtre:
{% 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 sera ensuite rendu avec la classe css "MyClass".
J'espère que cette aide.
EDIT 1
Mise à jour du filtre en fonction de la réponse de dimyG
Ajouter un lien Django-widget-Tweak
EDIT 2
En développant la méthode indiquée sur docs.djangoproject.com:
class MyForm(forms.Form):
comment = forms.CharField(
widget=forms.TextInput(attrs={'size':'40'}))
Je pensais qu'il était gênant de connaître le type de widget natif pour chaque champ et je trouvais amusant de remplacer le paramètre par défaut simplement pour mettre un nom de classe sur un champ de formulaire. Cela semble fonctionner pour moi:
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'
Cela me semble un peu plus propre.
Si vous souhaitez que tous les champs du formulaire héritent d'une certaine classe, vous devez simplement définir une classe parent héritant de forms.ModelForm
, puis en hériter
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
Cela m'a aidé à ajouter la classe 'form-control'
à tous les champs de tous les formulaires de mon application automatiquement, sans ajouter de réplication de code.
Voici un moyen simple de changer de vue. ajouter ci-dessous dans la vue juste avant de le passer dans le modèle.
form = MyForm(instance = instance.obj)
form.fields['email'].widget.attrs = {'class':'here_class_name'}
Ajoutez simplement les classes à votre formulaire comme suit.
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'
}
))
Voici une variante de ce qui précède qui donnera la même classe à tous les champs (par exemple, jquery Nice coins arrondis).
# 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'
Vous pouvez essayer ça ..
class SampleClass(forms.Form):
name = forms.CharField(max_length=30)
name.widget.attrs.update({'class': 'your-class'})
...
Vous pouvez voir plus d'informations dans: Django Widgets
Si vous souhaitez ajouter une classe au champ d'un formulaire dans un modèle (pas dans view.py ou form.py), par exemple dans le cas où vous souhaitez modifier des applications tierces sans redéfinir leurs vues, Le filtre de modèle décrit dans Charlesthkanswer est très pratique. Mais dans cette réponse, le filtre de modèle remplace toutes les classes existantes du champ.
J'ai essayé d'ajouter ceci en tant que montage mais il a été suggéré d'écrire comme une nouvelle réponse.
Donc, voici une balise template qui respecte les classes existantes du champ:
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})
Comme vous le savez, vous pouvez le faire dans le constructeur de formulaire ( init function) ou après l’initiation de la classe de formulaire. Ceci est parfois nécessaire si vous n’écrivez pas votre propre formulaire et que ce formulaire vient d’ailleurs -
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})
Vous pouvez également utiliser Django Crispy Forms , c’est un excellent outil pour définir des formulaires au cas où vous souhaiteriez utiliser un framework CSS comme Bootstrap ou Foundation. Et il est facile de spécifier des classes pour vos champs de formulaire.
Votre classe de formulaire aimerait ceci alors:
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'),
)
)