I am using django-crispy-forms to render the form of a model in django. django-crispy-forms already integrates very well with Twitter Bootstrap and has defined a layout object for the AppendedText
widget:
I have the following model in my django models.py
class Historia(models.Model):
persona = models.ForeignKey('Persona',
blank=False,
null=True,
related_name='historias')
fecha = models.DateTimeField(unique=True,
auto_now_add=True)
motivo = models.TextField()
peso = models.DecimalField(blank=True,
max_digits=5, decimal_places=2)
talla = models.IntegerField(blank=True)
tension = models.CharField(max_length=15)
pulso = models.IntegerField()
diagnostico = models.TextField()
tratamiento = models.TextField()
pendiente = models.TextField(blank=True)
and I define the following modelform
in forms.py
:
class HistoriaForm(django.forms.ModelForm):
class Meta:
model = models.Historia
def __init__(self, *args, **kwargs):
super(HistoriaForm, self).__init__(*args, **kwargs)
self.helper = FormHelper(self)
self.helper.form_class = 'form-horizontal'
self.helper.form_tag = True
self.helper.form_id = 'nueva_historia_form'
self.helper.form_action = 'nueva_historia'
self.helper.form_show_errors = True
self.helper.error_text_inline = False
self.helper.add_input(Submit('crear', 'Crear'))
My question is how can I change the widget of the peso
field without having to create a new widget
subclass since django-crispy-forms
already defines a layout object. Please also note that I do not want to enumerate all other fields in order to do this like:
self.helper.layout = Layout(
Fieldset(
'Legend',
'nombre',
'apellido',
AppendedText('peso', 'kg')
),
ButtonHolder(
Submit('submit', 'Submit', css_class='button white')
)
)
since I will have to keep editing the helper layout if I decide to add new fields in my model from which standard widgets are already very useful.
Edit: I have also seen the methods to access the layouts in a helper like self.helper.layout[0] = AppendedText('peso', 'kg')
but I do not know the index of the field I would like to change and it would be much nicer if I could just write self.helper.layout['peso'] = AppendedText('peso', 'kg')
django-crispy-forms does have an API for these kind of things: http://django-crispy-forms.readthedocs.org/en/latest/dynamic_layouts.html
You could simply do:
form.helper['peso'].wrap(AppendedText, "kg")
Ok, this is what worked for me without having to be too verbose and keeping it simple. In the __init__
method just do the following:
for i, field in enumerate(self.helper.layout):
if field == 'peso':
self.helper.layout[i] = AppendedText('peso', 'kg')
This works perfectly fine if the field you are looking for is in the first level of hierarchy in the layout
object, otherwise you would have to be more specific about what you are looking. For example if your field is in a DIV
container you would first will have to check whether field.__class__ == DIV
and then introspect into the DIV
field which is not as easy as it seems.
It would be nice, however, to have the API of the layout
object to support filter queries
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With