2010-09-09 19 views

Respuesta

13

Puede anular el constructor con el fin de modificar todos los widgets TextInput:

from django import forms 

class MyForm(forms.ModelForm): 
    def __init__(self, *args, **kwargs): 
     super(MyForm, self).__init__(*args, **kwargs) 
     for name, field in self.fields.items(): 
      if field.widget.__class__ == forms.widgets.TextInput: 
       if 'class' in field.widget.attrs: 
        field.widget.attrs['class'] += ' my-class' 
       else: 
        field.widget.attrs.update({'class':'my-class'}) 
    class Meta: 
     model = MyModel 

puede usted anular init con un decorador? Además, debería haber una declaración if antes de attrs.update() porque quiero establecer un valor predeterminado en lugar de anular lo que ya puede estar allí. - Kevin

No comprobado, pero supongo que puedes heredar de MyForm si usas esto mucho.

+0

¿puedes anular init con un decorador? Además, debería haber una declaración if antes de attrs.update() porque quiero establecer un valor predeterminado en lugar de anular lo que ya puede estar allí. – Kevin

+0

Creo que los decoradores están destinados a ser utilizados con callables, anulando el constructor se debe hacer a través del mecanismo de herencia normal. En django no es raro tener algunas funciones que devuelven clases, estas funciones se suelen llamar 'fábricas'. Actualizado con la condición "if" (no probado). –

3

Crear un nuevo widget con su clase CSS:

class PrettyWidget(forms.TextInput): 
    class Media: 
     css = { 
      'all': ('pretty.css',) 
     } 

En su forma de uso de su nuevo widget en todos sus campos:

class ContactForm(forms.Form): 
    subject = TextField(widget=PrettyWidget) 
+2

Esto se siente como el camino más Djangonic para realizar la tarea, pero no parece que se le parezca lo que Kevin es después de que me ... – codekoala

4

Una cosa que he hecho en el pasado es crear una función lambda que devuelve los campos a menudo uso:

from django import forms 

fancy = lambda: forms.TextInput(attrs={'class': 'derp'}) 

class MyForm(forms.Form): 
    attr1 = fancy() 
    attr2 = fancy() 
    attr3 = fancy() 

no recuerdo exactamente por qué he optado por utilizar una función t o manejar mi situación, pero sospecho que tiene algo que ver con la creación de instancias independientes del objeto forms.TextInput para cada campo de formulario ....

+0

Esto es lo que hago ahora. Es necesario crear instancias separadas de formularios. Seleccionar. – Kevin

1

permite utilizar las siguientes:

def set_attrs_for_fields(fields, default_attrs): 
    for field_name in fields: 
     field = fields[field_name] 

     try: 
      default_widget_attr = default_attrs[field.widget.__class__] 
      field.widget.attrs = default_widget_attr 
     except KeyError: 
      pass 


class DefaultAttrForm(forms.Form): 

    def __init__(self, *args, **kwargs): 

     super(DefaultAttrForm, self).__init__(*args, **kwargs) 

     set_attrs_for_fields(self.fields, self.get_default_attrs()) 


    def get_default_attrs(self): 
     ''' 
     Child class should overwrite this method and return dict with example format 

     {forms.TextInput: {'class': 'my_value'}} 

     where keys, are widget classes for which default attrs will be set. 
     ''' 
     raise NotImplementedError() 


class DefaultAttrModelForm(ModelForm): 

    def __init__(self, *args, **kwargs): 

     super(DefaultAttrModelForm, self).__init__(*args, **kwargs) 

     set_attrs_for_fields(self.fields, self.get_default_attrs()) 


    def get_default_attrs(self): 
     ''' 
     Child class should overwrite this method and return dict with example format 

     {forms.TextInput: {'class': 'my_value'}} 

     where keys, are widget classes for which default attrs will be set. 
     ''' 
     raise NotImplementedError() 

Ahora, cada vez que quiera usar attrs predeterminados para algún widget, solo necesita crear una clase que herede de DefaultAttrForm o DefaultAttrModelForm y sobreescribir el método get_default_attrs. Ejemplo de Formulario de Django normales:

class MyForm(DefaultAttrForm): 
    my_field1 = forms.CharField(widget=forms.TextInput()) 
    my_field2 = forms.CharField(widget=forms.PasswordInput(attrs={'my_non_default': 'Non default'})) 

    def get_default_attrs(self): 
     # all fields with widget TextInput will have 
     # default attrs set to {'class': 'my_value'} 

     return {forms.TextInput: {'class': 'my_value'}, 
       } 


In [1]: form = MyForm() 

In [2]: form.fields['my_field1'].widget.attrs 
Out[2]: {'class': 'my_value'} 

In [3]: form.fields['my_field2'].widget.attrs 
Out[3]: {'my_non_default': 'Non default'} 

Para El modelo de formulario utilización siguiente:

class MyModelForm(DefaultAttrModelForm): 

    class Meta: 
     model = my_model 

    def get_default_attrs(self): 
     # all fields with widget TextInput will have 
     # default attrs set to {'class': 'my_value'} 

     return {forms.TextInput: {'class': 'my_value'}, 
       } 


In [1]: form = MyModelForm() 

In [2]: form.fields['my_field1'].widget.attrs 
Out[2]: {'class': 'my_value'} 

In [3]: form.fields['my_field2'].widget.attrs 
Out[3]: {'my_non_default': 'Non default'} 
0

Para ModelForm podemos usar esto.

from django import forms 
from django.contrib.auth.models import User 

class UserForm(forms.ModelForm): 
    def __init__(self, *args, **kwargs): 
     super(UserForm, self).__init__(*args, **kwargs) 

     # change a widget attribute: 
     self.fields['user_permissions'].widget.attrs["size"] = 5 
     self.fields['user_permissions'].widget.attrs["class"] = 'form-control required' 

    class Meta: 
     model = User 
Cuestiones relacionadas