About Model Form Fields

It's not recommendable to use the exclude attribute for model form meta, because with big projects, you will likely forget to add new model fields that need to be excluded. Instead, you should have the boring list of fields.

DON'T:

1
2
3
4
class MyModelForm(forms.ModelForm):
    class Meta:
        model = MyModel
        exclude = [...]

DO:

1
2
3
4
class MyModelForm(forms.ModelForm):
    class Meta:
        model = MyModel
        fields = [...]

Here is a utility function that lists all the names of editable fields, but excludes the excluded ones:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
def get_modelform_fields(form_class):
    model_fields = set(
        field.name
        for field in form_class._meta.model._meta.get_fields()
        if not (field.auto_created) and getattr(field, "editable", True)
    )

    excluded_fields = (
        set(form_class._meta.exclude) if form_class._meta.exclude else set()
    )

    default_fields = set(form_class.base_fields.keys())

    form_fields = (model_fields - excluded_fields) | default_fields

    return sorted(form_fields)

Use this function in Django Shell and then replace the exclude attribute with the fields attribute in your code.

1
2
3
>>> from utils import get_modelform_fields
>>> get_modelform_fields(MyModelForm)
[...]

Tips and Tricks Programming Django 5.x Django 4.2 Django 3.2 Python 3 django-crispy-forms