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'}
¿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
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). –