I have done a ModelForm adding some extra fields that are not in the model. I use these fields for some calcualtions when saving the form.
The extra fields appear on the form and they are sent in the POST request when uploading the form. The problem is they are not added to the cleaned_data
dictionary when I validate the form. How can I access them?
Set the exclude attribute of the ModelForm 's inner Meta class to a list of fields to be excluded from the form.
In a nutshell: Make a form for each model, submit them both to template in a single <form> , using prefix keyarg and have the view handle validation. If there is dependency, just make sure you save the "parent" model before dependant, and use parent's ID for foreign key before commiting save of "child" model.
The main difference between the two is that in forms that are created from forms. ModelForm , we have to declare which model will be used to create our form. In our Article Form above we have this line " model = models. Article " which basically means we are going to use Article model to create our form.
Every field comes in with built-in validations from Django validators. One can also add more built-in field validations for applying or removing certain constraints on a particular field. editable=False will make the field disappear from all forms including admin and ModelForm i.e., it can not be edited using any form.
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']
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 forms class 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.
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