[python] Definieren Sie die CSS-Klasse in Django-Formularen


5 Answers

Beantwortete meine eigene Frage. Seufzer

docs.djangoproject.com/en/dev/ref/forms/widgets/…

Ich habe nicht bemerkt, dass es in den Widget-Konstruktor übernommen wurde.

Question

Angenommen, ich habe ein Formular

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

Gibt es eine Möglichkeit für mich, CSS-Klassen für jedes Feld zu definieren, so dass ich dann jQuery basierend auf der Klasse in meiner gerenderten Seite verwenden kann?

Ich hatte gehofft, das Formular nicht manuell erstellen zu müssen.




Sie können auch Django Crispy Forms verwenden , es ist ein großartiges Werkzeug, um Formulare zu definieren, falls Sie ein CSS-Framework wie Bootstrap oder Foundation verwenden möchten. Und es ist einfach, dort Klassen für Ihre Formularfelder anzugeben.

Ihre Formularklasse würde das dann gerne haben:

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'),
        )
    )



Verwenden Sie django-widget-tweaks , es ist einfach zu bedienen und funktioniert sehr gut.

Andernfalls kann dies mit einem benutzerdefinierten Vorlagenfilter erfolgen.

Wenn man bedenkt, dass Sie Ihre Form so darstellen:

<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 ist eine Instanz von BoundField mit der Methode as_widget .

Sie können einen benutzerdefinierten Filter "addcss" in "my_app / templatetags / myfilters.py" erstellen

from django import template

register = template.Library()

@register.filter(name='addcss')
def addcss(value, arg):
    css_classes = value.field.widget.attrs.get('class', None).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})

Und dann wende deinen Filter an:

{% 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 wird dann mit der CSS-Klasse "MyClass" gerendert.

Ich hoffe das hilft.

BEARBEITEN

  • Aktualisiere den Filter gemäß der Antwort von dimyG

  • Fügen Sie den Django-Widget-Tweak-Link hinzu




Wenn Sie möchten, dass alle Felder im Formular eine bestimmte Klasse erben, definieren Sie einfach eine übergeordnete Klasse, die von forms.ModelForm erbt und dann von ihr erbt

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

Dies hat mir geholfen, die Klasse 'form-control' automatisch allen Feldern in allen Formen meiner Anwendung hinzuzufügen, ohne die Code-Replikation hinzuzufügen.




Fügen Sie die Klassen einfach wie folgt in Ihr Formular ein.

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'
        }
    ))



Falls Sie eine Klasse zu einem Formularfeld in einer Vorlage (nicht in view.py oder form.py) hinzufügen möchten, zum Beispiel in Fällen, in denen Sie Apps von Drittanbietern ändern möchten, ohne ihre Ansichten zu überschreiben, dann verwenden Sie einen Vorlagenfilter wie beschrieben in Charlesthk ist die answer sehr bequem. In dieser Antwort überschreibt der Vorlagenfilter jedoch alle vorhandenen Klassen, die das Feld möglicherweise aufweist.

Ich habe versucht, dies als eine Bearbeitung hinzuzufügen, aber es wurde vorgeschlagen, als eine neue Antwort geschrieben zu werden.

Also, hier ist ein Template-Tag, das die vorhandenen Klassen des Feldes respektiert:

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



Related