Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Django ModelForm, how can I modify a form fields before rendering it depending on the model

Tags:

forms

django

Using a ModelForm, the model contains a value of a field I should render in the form :

class MyClass(models.Model):
    my_field = models.CharField(max_length=256) # this contains the type of the form's field for example a CharField or a DateTimeField

My view :

class MyView(FormView):
    form_class = CustomForm
    model = MyClass

And the form class:

class MyForm(forms.ModelForm):
    class Meta:
        model = MyClass
        fields = ?

How can I dynamically set my form's field type?

like image 277
aze Avatar asked Nov 19 '25 20:11

aze


1 Answers

I'd list out all the possible fields you may need in fields = () then you can remove fields you don't want, change if fields are required etc, based on the value of the model field like this;

class MyForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        if self.instance:
            if self.instance.my_field == 'value':
                del self.fields['my_field']  # remove 'my_field'
                self.fields['name'].required = False  # change required value

    class Meta:
        model = MyClass
        fields = (
            'name',
            'address',
            'my_field',
            'some_other_field'
        )

So from your view, if you want to get a value to your form you can do something like;

my_object = MyClass.objects.first()
form = MyForm(instance=my_object)
context['form'] = form
# etc, etc

Then you can get values from fields on that object like I suggested above.

You could also just pass arbitrary args/kwargs to your forms if you need to (say you don't actually have an object to check the values from, but instead want to just pass something based on other data;

# in a view;
form = MyForm(my_var='something')

# in the form;
class MyForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        my_var = kwargs.pop('my_var')
        super(MyForm, self).__init__(*args, **kwargs)
        if my_var == 'value':
            del self.fields['my_field']  # remove 'my_field'
like image 154
markwalker_ Avatar answered Nov 21 '25 08:11

markwalker_



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!