Django: display inherited (nested) values โ€‹โ€‹as a list in form.ModelForm

I am trying to display a drop-down list in my form from my TipoDocumento model (I need to display the "nombre_corto" column as a list).

1) My model name is Cocinera, Cocinera inherits my Usuario model.
2) "Usuario" inherits this "documento" field from my "Documento" model.
3) The "Documento" model inherits the "tipo_documento" field from the "TipoDocumento".

But I can not display "tipo_documento" as a list from my Cocinera model through the CocineraForm form. I get an error, described in detail at the end.

All my models are in the 'nucleo' app. Only the form that receives the render is in my other app_administrador application.

========================================

Nucleo - an application called the nucleon

========================================

MODELS:

Model 'TipoDocumento'

from django.db import models class TipoDocumento(models.Model): nombre_corto = models.CharField(blank=False, null=False, max_length=25) nombre_largo = models.CharField(blank=False, null=False, max_length=100) def __str__(self): return self.nombre_corto 

Model 'Documento'

 class Documento(models.Model): def __str__(self): return self.codigo tipo_documento = models.ForeignKey(TipoDocumento, on_delete=models.SET_NULL, null=True) codigo = models.CharField(max_length=25) 

Model "Usuario":

 class Usuario(models.Model): class Meta: abstract = True nombre = models.CharField(blank=False, null=False, max_length=200) apellido_paterno = models.CharField(blank=False, null=False, max_length=100) apellido_materno = models.CharField(blank=True, null=False, max_length=100) fecha_de_nacimiento = models.DateField(blank=False, null=False) documento = models.OneToOneField(Documento, on_delete=models.CASCADE, blank=False, null=True) 

Model 'Cocinera':

 class Cocinera(Usuario): habilidades = models.ForeignKey(Habilidad, blank=True, null=True) experiencia_con_mascotas = models.BooleanField(default=False) def __str__(self): return self.nombre 

========================================

app_administrador

========================================

My form

 class CocineraForm(forms.ModelForm): class Meta: model = Cocinera fields = ['nombre', 'apellido_paterno', 'apellido_materno', 'tipo_documento', 'documento', 'fecha_de_nacimiento', 'direccion', 'telefono_o_celular' , 'latitud_y_longitud', 'genero', 'antecedentes_policiales', 'foto'] widgets = { 'fecha_de_nacimiento': DateInput() } 

Related question: Accordingly, Use the Django ModelChoice field to create a drop-down lookup table?

I added:

 tipo_documento = forms.ModelChoiceField(queryset=TipoDocumento.objects.all(), empty_label=None) 

But still, when I run my application, I get:

 File "/home/ogonzales/Escritorio/web_envs/ cocineras_env/lib/python3.5/site-packages/django/forms/models.py", line 277, in __new__raise FieldError(message) django.core.exceptions.FieldError: Unknown field(s) (tipo_documento) specified for Cocinera 
+8
inheritance django django-forms
source share
2 answers

So, I found the answer: I needed to work with 2 forms, not just 1, and display both in the โ€œtemplateโ€.

Steps:

1.- I needed to create an additional form "DocumentoForm", except for "CocineraForm".

 class CocineraForm(forms.ModelForm): class Meta: model = Cocinera fields = ['nombre', 'apellido_paterno', 'apellido_materno', 'fecha_de_nacimiento', 'direccion', 'telefono_o_celular', 'latitud_y_longitud', 'genero', 'foto'] #New DocumentoForm class DocumentoForm(forms.ModelForm): class Meta: model = Documento fields = ['tipo_documento', 'codigo'] 

2.- I needed to check all the fields of both forms. Create an instance of "Documento" from the form "DocumentoForm" without saving it to the database (commit = "False"). And I needed to add this instance of "Documento" to the "cocinera" model as a field. Here I have to save "CocinerForm" with .save ().

 class RegistroView(View): def get(self, request): cocinera_form = CocineraForm() documento_form = DocumentoForm() context = {'cocinera_form': cocinera_form, 'documento_form': documento_form} return render(request, 'app_administrador/crear-registro-como-secretaria.html', context) def post(self, request): cocinera_form = CocineraForm(request.POST, request.FILES) documento_form = DocumentoForm(request.POST) if all((cocinera_form.is_valid(), documento_form.is_valid())): documento = documento_form.save() cocinera = cocinera_form.save(commit=False) #Don't save it to the DB. Just store the variable for now. cocinera.documento = documento #adding documento to 'Cocinera' model through CocineraForm. cocinera.save() return HttpResponseRedirect('/') 

3.- Work with two forms in the template.

 <form action="" method="post"> {% csrf_token %} {{ cocinera_form }} {{ documento_form }} </form> 
+2
source share

Of course, you can add an additional field to the form, as you have already done.

But you are not allowed to add the model tipo_documento field to the list of fields, as this applies only to the fields defined in your model.

So, you should be fine:

 class CocineraForm(forms.ModelForm): class Meta: model = Cocinera fields = ['nombre', 'apellido_paterno', 'apellido_materno', 'documento', 'fecha_de_nacimiento', 'direccion', 'telefono_o_celular', 'latitud_y_longitud', 'genero', 'antecedentes_policiales', 'foto'] widgets = { 'fecha_de_nacimiento': DateInput() } tipo_documento = forms.ModelChoiceField(queryset=TipoDocumento.objects.all(), empty_label=None) 

Note the missing tipo_documento from the list of fields.

+2
source share

All Articles