python hidden - Definieren Sie die CSS-Klasse in Django-Formularen




field widget (11)

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.


Answers

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.


Wie Sie sehen, können Sie dies im Formularkonstruktor ( Init- Funktion) oder nach dem Start der Formularklasse tun. Dies ist manchmal erforderlich, wenn Sie nicht Ihr eigenes Formular schreiben und dieses Formular von woanders kommt -

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

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

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


Hier ist eine Variation der oben genannten, die allen Feldern die gleiche Klasse geben wird (zB jquery schöne abgerundete Ecken).

  # 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'

Hier ist eine weitere Lösung zum Hinzufügen von Klassendefinitionen zu den Widgets nach dem Deklarieren der Felder in der Klasse.

def __init__(self, *args, **kwargs):
    super(SampleClass, self).__init__(*args, **kwargs)
    self.fields['name'].widget.attrs['class'] = 'my_class'

Erweiterung der Methode, auf die unter docs.djangoproject.com verwiesen wird:

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

Ich dachte, es wäre problematisch, den nativen Widget-Typ für jedes Feld kennen zu müssen, und fand es lustig, den Standard zu überschreiben, nur um einen Klassennamen in ein Formularfeld zu schreiben. Dies scheint für mich zu funktionieren:

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'

Das scheint mir ein bisschen sauberer zu sein.



Hier ist einfache Möglichkeit, in Sicht zu ändern. fügen Sie unten in der Ansicht hinzu, bevor Sie es in die Vorlage übergeben.

form = MyForm(instance = instance.obj)
form.fields['email'].widget.attrs = {'class':'here_class_name'}

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

class Foo(object):
     pass

some_global_variable = Foo()

Module werden nur einmal importiert, alles andere überdenkt. Verwenden Sie keine Singletons und versuchen Sie nicht, Globals zu verwenden.





python django django-forms