Vous pouvez utiliser ce qui suit:
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()
Maintenant, Chaque fois que vous voulez utiliser l'attr par défaut pour un widget, vous devez simplement créer une classe qui hérite de DefaultAttrForm ou DefaultAttrModelForm et remplacer la méthode get_default_attrs
. Exemple pour la forme normale Django:
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'}
Pour une utilisation du formulaire modèle suivant:
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'}
pouvez-vous remplacer init avec un décorateur? aussi, il devrait y avoir une instruction if avant l'attrs.update() parce que je veux définir un défaut plutôt que de surcharger ce qui peut déjà être là. – Kevin
Je pense que les décorateurs sont destinés à être utilisés avec des callables, le remplacement du constructeur devrait être fait par le mécanisme d'héritage normal. Dans django, il n'est pas rare que certaines fonctions renvoient des classes, ces fonctions sont généralement appelées «usines». Mise à jour avec la condition "si" (non testée). –