Django ModelForm con campos adicionales que no están en el modelo

He hecho un ModelForm agregando algunos campos adicionales que no están en el modelo. Utilizo estos campos para algunos cálculos al guardar el formulario.

Los campos adicionales aparecen en el formulario y se envían en la solicitud POST al cargar el formulario. El problema es que no se agregan al diccionario cleaned_data cuando valido el formulario. ¿Cómo puedo acceder a ellos?

Es posible extender Django ModelForm con campos adicionales. Imagina que tienes un modelo de usuario personalizado y este ModelForm :

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

Ahora, imagine que desea incluir un campo adicional (no presente en su modelo de usuario, digamos un avatar de imagen). Extiende tu formulario haciendo esto:

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

Finalmente (dado que el formulario tiene un ImageField ), recuerde incluir request.FILES al crear una instancia del formulario en su vista:

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

Espero eso ayude. ¡Buena suerte!

EDITAR:

Recibía un error “solo puedo concatenar tupla (no” lista “) a tupla” en el atributo AvatarProfileForm.Meta.fields. Lo cambié por una tupla y funcionó.

Primero, no deberías tener campos artist_id y artist. Se construyen a partir del modelo. Si necesita algún nombre de artista, agregue el campo artist_name, que es CharField .

Además, está intentando recuperar algo de clean_data dentro de un valor limpio. Puede que no haya datos que necesite; debe usar valores de self.data, donde se encuentran los datos directamente de POST.

Esta respuesta puede ser demasiado tarde para el póster original, pero pensé que podría ayudar a otros. Tuve el mismo problema y noté que se puede acceder a self.cleaned_data (‘artist_id’) mediante el método clean (), pero no en clean_artist ().

Cuando agregué los campos adicionales en la statement de ‘campos’ de Meta, entonces funcionó.

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

Debería poder acceder a self.cleaned_data (‘artist_id’) en clean_artist ().

Ok lo he resuelto. Parece que acceder a los campos adicionales con cleaner_data [‘field_name’] genera un KeyError pero el uso de cleaner_data.get (‘field_name’) funciona. Eso es extraño porque se puede acceder a los campos normales del modelo a través de clean_data [‘field_name’].

Actualización: No, no funciona. Con get () no genera un KeyError, pero establece un valor de Ninguno porque los campos adicionales no están en el diccionario cleaner_data.

Aquí está el código. En las plantillas hay un autocompletado, por lo tanto, en el formulario hay un campo “artista” representado como un campo de acción y un campo entero oculto que se rellenará automáticamente con la identificación del artista dada. En el método clean_artist quiero seleccionar el objeto de artista y almacenarlo en el campo de artista del formulario.

modelos.py

 class Music(models.Model): artist = models.ForeignKey(Artist, related_name='music', blank=True, null=True) # other fields... 

forms.py

 class MusicForm(forms.ModelForm): artist_id = forms.IntegerField(label="", widget=forms.HiddenInput(), required=False) artist = forms.CharField(required=False) # other fields ... class Meta: model = Music def clean_artist(self): if self.cleaned_data.get('artist') == '': artist = None else: artist_id = self.cleaned_data.get('artist_id') # this returns always None because artist_id is not in cleaned_fields (this seemed to work with previous django versions but not with current SVN version) if artist_id != None: artist = Artist.objects.get(id=artist_id) else: artist = None return artist 

Tuve un problema muy similar, excepto que parecía que hice todo lo necesario, pero recibí este error cuando Django estaba empezando:

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

Este fue un error tonto de mi parte, declaré accidentalmente mi campo usando una clase de Widget :

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

En lugar de una clase de campo :

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

No contestaré la pregunta aquí (lo cual ya está bien contestado), pero podría ayudar a otros.

Primero agregue el campo en el formulario

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

Ahora, mientras limpia sus datos, debe recuperar el campo adicional de self.data NOT self.cleaned_data

Correcto :

  self.data.get('extra_field') 

Mal

  self.cleaned_data.get('extra_field')