Pergunta

Suponha que eu tenho um formulário

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

Existe uma maneira para eu definir classes css em cada campo de modo que eu possa, em seguida, usar jQuery com base na classe na minha página processada?

Eu estava esperando para não ter que construir manualmente o formulário.

Foi útil?

Solução 2

respondi minha própria pergunta. Sigh

http: //docs.djangoproject .com / en / dev / ref / formulários / widgets / # django.forms.Widget.attrs

Eu não percebi que foi passado para o construtor Widget.

Outras dicas

No entanto, outra solução que não requer alterações no código python e por isso é melhor para os designers e one-off mudanças de apresentação: rel django-widget-tweaks . Espero que alguém vai encontrá-lo útil.

Aqui está uma outra solução para adicionar definições de classe para os widgets depois de declarar os campos na classe.

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

Use django-widget-tweaks , é fácil de usar e funciona muito bem.

Caso contrário, isso pode ser feito usando um filtro de modelo personalizado.

Considerando você processar seu formulário desta forma:

<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 é uma instância de BoundField que as_widget método.

Você pode criar um filtro personalizado "addcss" em "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, em seguida, aplicar o 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>

form.subjects será então processado com o "MyClass" classe css.

Espero que isso ajuda.

Editar 1

  • filtro de atualização de acordo resposta s para dimyG '

  • Adicionar Link django-widget-ajuste

EDIT 2

  • filtro de atualização de acordo com a Bhyd 's comentário

Expandindo o método apontado no docs.djangoproject.com:

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

Eu pensei que era problemático ter que saber o tipo de widget nativo para todos os campos, e pensei que engraçado para substituir o padrão apenas para colocar um nome de classe em um campo de formulário. Isso parece funcionar para mim:

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'

Isto parece um pouco mais limpo para mim.

Se você quiser todos os campos do formulário de herdar uma certa classe, você apenas definir uma classe pai, que herda de forms.ModelForm, e depois herdar it

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

Isso me ajudou a adicionar a classe 'form-control' para todos os campos em todas as formas de meu aplicativo automaticamente, sem a adição de replicação de código.

Aqui é a maneira simples de alterar em vista. adicione a seguir tendo em vista pouco antes de passá-lo em modelo.

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

Basta adicionar as classes para o seu formulário da seguinte forma.

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

Aqui está uma variação no exposto, que dará todos os campos da mesma classe (por exemplo jquery bom cantos arredondados).

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

No caso que você deseja adicionar uma classe para o campo de um formulário em um modelo (e não em view.py ou form.py), por exemplo, nos casos em que você deseja modificar 3o partido apps sem substituindo seus pontos de vista, em seguida, um filtro de modelo como descrito no Charlesthk responder é muito conveniente. Mas nesta resposta do filtro modelo substitui quaisquer classes existentes que a força de campo tem.

Eu tentei adicionar isso como uma edição, mas foi sugerido para ser escrito como uma nova resposta.

Então, aqui está uma etiqueta modelo que respeite as classes existentes de 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})

Você pode tentar isso ..

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

Você pode ver mais informações em: Django Widgets

Como se vê que você pode fazer isso no construtor forma (init função ) ou após a classe de formulário foi iniciada. Isso às vezes é necessário se você não está escrevendo sua própria forma e que forma está vindo de outro lugar -

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

Você também pode usar Django Crispy Formas , é um grande ferramenta para definir formas no caso de você gostaria de usar alguma estrutura CSS como Bootstrap ou Foundation. E é fácil para especificar classes para os campos do formulário lá.

A sua classe de formulário gostaria que esta então:

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'),
        )
    )
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top