Django ModelForm with extra fields that are not in the model

后端 未结 7 407
甜味超标
甜味超标 2021-01-31 02:00

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 fie

相关标签:
7条回答
  • 2021-01-31 02:32

    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.

    0 讨论(0)
  • 2021-01-31 02:32

    In Django 2 you can just add the fields as it was a normal form

    class CreateCompanyForm(forms.ModelForm):
    
        password_confirmation = forms.CharField(
            label=translate('Password confirmation'),
            max_length=70,
            widget=forms.PasswordInput(),
            required=True,
        )
        company_name = forms.CharField(
            label="Nombre de la Compañía",
            max_length=90,
            widget=forms.TextInput(),
            required=True,
        )
    
        class Meta:
            model = AppUser
            fields = (
                "email",
                "first_name",
                "last_name",
                "password",
            )
    
    0 讨论(0)
  • 2021-01-31 02:39

    First, you shouldn't have artist_id and artist fields. They are build from the model. If you need some artist name, add artist_name field, that is CharField.

    Furthermore, you are trying to retrieve something from cleaned_data inside clean value. There might not be data you need - you should use values from self.data, where is data directly from POST.

    0 讨论(0)
  • 2021-01-31 02:40

    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')
    
    0 讨论(0)
  • 2021-01-31 02:41

    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.

    0 讨论(0)
  • 2021-01-31 02:44

    This answer may be too late for the original poster, but I thought it might help others. I had the same problem and I did notice that self.cleaned_data('artist_id') can be accessed in the clean() method, but not in the clean_artist().

    When I added the extra fields in the 'fields' declaration of Meta, then it worked.

        class Meta:
            model = Music
            fields=[..., 'artist_id']
    

    You should be able to access the self.cleaned_data('artist_id') in clean_artist().

    0 讨论(0)
提交回复
热议问题