Question

Supposons que j'ai un formulaire

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

Puis-je 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 à créer manuellement le formulaire.

Était-ce utile?

La solution 2

a répondu à ma propre question. Soupir

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

Je ne savais pas que cela avait été passé dans le constructeur du widget.

Autres conseils

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 ponctuelles: 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 la déclaration des 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 le rendu de votre formulaire de la manière suivante:

<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 utilise 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 seront alors rendus avec le "MyClass". classe css.

J'espère que cela vous aidera.

MODIFIER 1

  • Mettez le filtre à jour en fonction de la réponse de dimyG

  • Ajouter un lien Django-widget-tweak

EDIT 2

Développement de 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 devoir connaître le type de widget natif pour chaque champ et le 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 définissez simplement une classe parent héritant de forms.ModelForm , puis en héritant

.
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 automatiquement la classe 'form-control' à tous les champs de tous les formulaires de mon application, sans ajouter de réplication de code.

Voici un moyen simple de changer de vue. ajoutez ci-dessous la vue juste avant de la passer au 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 de jolis 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'

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 les cas où vous souhaitez modifier des applications tierces sans Un filtre de modèle, décrit dans Charlesthk answer , 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 modification, mais il a été suggéré de l'écrire en tant que nouvelle réponse.

Alors, voici une balise de modèle 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})

Vous pouvez essayer ceci.

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

Vous pouvez voir plus d'informations dans: Widgets Django

Vous pouvez le faire dans le constructeur de formulaire (fonction init ) ou après le lancement de la classe de formulaire. Cela est parfois nécessaire si vous n'écrivez pas votre propre formulaire et que ce formulaire provient 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 les Django Crispy Forms , un excellent outil pour définir des formulaires au cas où vous souhaiteriez utiliser un framework CSS tel que Bootstrap ou Foundation. Et il est facile de spécifier des classes pour vos champs de formulaire ici.

Votre classe de formulaire aimerait ceci:

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'),
        )
    )
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top