Domanda

Supponi di avere un modulo

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

Esiste un modo per definire le classi css su ciascun campo in modo da poter usare jQuery in base alla classe nella mia pagina renderizzata?

Speravo di non dover compilare manualmente il modulo.

È stato utile?

Soluzione 2

Ha risposto alla mia domanda. Sigh

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

Non mi ero reso conto che fosse passato al costruttore del widget.

Altri suggerimenti

Ancora un'altra soluzione che non richiede cambiamenti nel codice Python ed è quindi migliore per i progettisti e le modifiche di presentazione una tantum: django-widget-ritocchi . Spero che qualcuno lo trovi utile.

Ecco un'altra soluzione per aggiungere definizioni di classe ai widget dopo aver dichiarato i campi nella classe.

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

Usa django-widget-tweaks , è facile da usare e funziona abbastanza bene.

Altrimenti ciò può essere fatto usando un filtro template personalizzato.

Considerando che rendi il tuo modulo in questo modo:

<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 è un'istanza di BoundField che ha il metodo as_widget .

puoi creare un filtro personalizzato " addcss " in " 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})

E quindi applicare il filtro:

{% 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>

i form.subjects verranno quindi resi con la "MyClass" classe css.

Spero che questo aiuto.

MODIFICA 1

  • Aggiorna filtro in base alla dimyG la risposta

  • Aggiungi il link django-widget-tweak

MODIFICA 2

Espandere il metodo indicato in docs.djangoproject.com:

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

Ho pensato che fosse problematico conoscere il tipo di widget nativo per ogni campo e ho pensato che fosse divertente ignorare il valore predefinito solo per inserire un nome di classe in un campo modulo. Questo sembra funzionare per me:

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'

Questo mi sembra un po 'più pulito.

Se vuoi che tutti i campi del modulo ereditino una determinata classe, devi semplicemente definire una classe genitore, che eredita da form.ModelForm , e quindi eredita da essa

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

Questo mi ha aiutato ad aggiungere automaticamente la classe 'form-control' a tutti i campi su tutti i moduli della mia applicazione, senza aggiungere la replica del codice.

Ecco un modo semplice per modificare in vista. aggiungi sotto in vista poco prima di passarlo nel modello.

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

Aggiungi semplicemente le classi al tuo modulo come segue.

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

Ecco una variazione di quanto sopra che darà a tutti i campi la stessa classe (ad es. jquery bei angoli arrotondati).

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

Nel caso in cui si desideri aggiungere una classe al campo di un modulo in un modello (non in view.py o form.py), ad esempio nel caso in cui si desideri modificare app di terze parti senza sovrascrivendo le loro opinioni, quindi un filtro modello come descritto in Charlesthk rispondi è molto conveniente. Ma in questa risposta il filtro template sostituisce tutte le classi esistenti che il campo potrebbe avere.

Ho provato ad aggiungere questo come una modifica ma mi è stato suggerito di essere scritto come una nuova risposta.

Quindi, ecco un tag modello che rispetta le classi esistenti del campo:

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

Puoi provare questo ..

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

Puoi trovare maggiori informazioni in: Django Widgets

A quanto pare puoi farlo nel costruttore di moduli ( init ) o dopo che è stata avviata la classe del modulo. Questo a volte è necessario se non stai scrivendo il tuo modulo e quel modulo proviene da qualche altra parte -

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

Puoi anche usare Django Crispy Forms , è un ottimo strumento per definire i moduli nel caso in cui desideri utilizzare alcuni framework CSS come Bootstrap o Foundation. Ed è facile specificare le classi per i campi del modulo lì.

La tua classe di modulo vorrebbe quindi:

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'),
        )
    )
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top