Dynamically changing a form widget in Django

My Django app uses Django Suit as a tool for the Django admin app theme. One of the things that Suit can do is add and add widgets to create widgets, such as:

class PropertyForm(ModelForm): class Meta: model = Property widgets = { 'amount': EnclosedInput(prepend = "GBP"), } 

Effect:

enter image description here

Although this is a nice feature, it would be more useful if I could add it dynamically, like (in pseudocode):

 'amount': EnclosedInput(prepend = my_model_instance.currency) 

I tried to override the init form as follows:

 class PropertyForm(ModelForm): def __init__(self, *args, **kwargs): inst = kwargs["instance"] self._meta.widgets["amount"] = EnclosedInput(prepend = inst.currency) super(PropertyForm, self).__init__(*args, **kwargs) 

It is strange that it only works when I set a breakpoint in the init method. There seem to be some time issues.

So my question is, what would be the best way (if at all possible) to implement this?

+4
source share
2 answers

The problem is this:

 self._meta.widgets["amount"] = EnclosedInput(prepend = inst.currency) 

It turns out _meta cached. When I modify the above line (which is also a nicer solution like _meta is probably private):

 self.fields['amount'].widget = EnclosedInput(prepend = inst.currency) 

... it works flawlessly

+8
source

An easy way would be to set up the form class every time you need it:

 def make_property_form(currency): class PropertyForm(forms.Form): # ... widgets = { 'amount': EnclosedInput(prepend=currency), } return PropertyForm def view_that_uses_my_form(request): # ... form_class = make_property_form(model.currency) form = form_class(the_usual_form_initialization) 
+1
source

Source: https://habr.com/ru/post/1468934/


All Articles