Django ModelForm with extra fields that are not in the model Django ModelForm with extra fields that are not in the model python python

Django ModelForm with extra fields that are not in the model


EDIT 2020 (Django 2 or higher)

In Django 2+ you can add the extra fields like this:

class ProfileForm(forms.ModelForm):        extra_field = forms.ImageField()    class Meta:        model = User        fields = ['username', 'country', 'website', 'biography']

Original answer (Django 1)

It's possible to extend Django ModelForm with extra fields. Imagine you have a custom User model and this ModelForm:

class ProfileForm(forms.ModelForm):    class Meta:        model = User        fields = ['username', 'country', 'website', 'biography']

Now, imagine you want to include an extra field (not present in your User model, lets say an image avatar). Extend your form by doing this:

from django import formsclass AvatarProfileForm(ProfileForm):    profile_avatar = forms.ImageField()    class Meta(ProfileForm.Meta):        fields = ProfileForm.Meta.fields + ('profile_avatar',)

Finally (given that the form has an ImageField), remember to include request.FILES when instantiating the form in your view:

# (view.py)def edit_profile(request):    ...    form = AvatarProfileForm(        request.POST or None,         request.FILES or None,         instance=request.user    )    ...

Hope it helps. Good luck!

EDIT:

I was getting a "can only concatenate tuple (not "list") to tuple" error in AvatarProfileForm.Meta.fields attribute. Changed it to a tuple and it worked.


I had a very similar problem except it looked like I did all the required thing, but I was getting this error when Django was starting:

django.core.exceptions.FieldError: Unknown field(s) (my_new_field) specified for MyModel

This was a silly mistake from me, I accidentally declared my field using a Widget class:

class MyForm(forms.ModelForm):    my_new_field = forms.HiddenInput()

Instead of a Field class:

class MyForm(forms.ModelForm):    my_new_field = forms.CharField(widget=forms.HiddenInput())

Not answering the question at hand here (which is answered well already), but might help others.


First add the field in the form

class CreateForm(forms.ModelForm):extra_field     = forms.CharField(label = 'extra_field', required = False)

Now while cleaning you data, you need to retrive the extra field from self.data NOT self.cleaned_data

Correct:

 self.data.get('extra_field')

Wrong:

 self.cleaned_data.get('extra_field')