1

This is my method save on my form.py file.

This is the ErroValue:

Exception Type: ValueError
Exception Value:    
"<Nana: E>" needs to have a value for field "id" before this many-to-many relationship can be used.

1.-I understand that I'm saving my Nana not at the correct time. What Am I doing wrong?

2.-'habilidades' and 'especiliades' are select mutiple fields in html. I need to save that data to the "Nana" model.

  @transaction.atomic()
    def save(self):
        valid_data = self.cleaned_data
        documento_codigo = valid_data.pop('documento')
        documento_tipo_id = valid_data.pop('tipo_documento')
        documento = Documento(codigo=documento_codigo, tipo_documento_id=documento_tipo_id)
        documento.save()
        #habilidad
        habilidades_nombre = valid_data.pop('habilidades')
        habilidades_habilidades = Habilidad(habilidades_nombre)
        habilidades_habilidades.save()
        nana = Nana(documento=documento, **valid_data)
        nana.save()
        nana.habilidades.add(habilidades_habilidades)
        return nana

My form (without method save):

class NanaForm(forms.Form):
    nombre = forms.CharField(label='Nombre', max_length=200)
    apellido_paterno = forms.CharField(label='Apellido paterno', max_length=100)
    apellido_materno = forms.CharField(label='Apellido materno', max_length=100)
    fecha_de_nacimiento = forms.DateField(label='Fecha de nacimiento')
    documento = forms.CharField(label='Documento', max_length=60, required=True)
    tipo_documento = forms.CharField(label='Tipo de documento', max_length=100)
    direccion = forms.CharField(label='Dirección', max_length=100)
    telefono_o_celular = forms.CharField(label='Teléfono o celular', max_length=14)
    latitud = forms.CharField(label='Latitud', max_length=100)
    longitud = forms.CharField(label='Longitud', max_length=100)
    genero = forms.CharField(label='Género', max_length=100)
    habilidades = forms.CharField(label='Habilidades', max_length=100)
    especialidades = forms.CharField(label='Especialidades', max_length=100)
    # habilidades = forms.MultipleChoiceField(label="Habilidades", required=False, widget=forms.SelectMultiple)
    # especialidades = forms.MultipleChoiceField(label="Especialidades", required=False, widget=forms.SelectMultiple)

    foto = forms.ImageField(required=False)

UPDATE 1 (MODELS):

class Especialidad(models.Model):
    nombre = models.CharField(max_length=250)

    def __str__(self):
        return self.nombre


class Habilidad(models.Model):
    nombre = models.CharField(max_length=250)

    def __str__(self):
        return self.nombre


class Nana(Usuario):
    habilidades = models.ManyToManyField(Habilidad)
    especialidades = models.ManyToManyField(Especialidad)
    experiencia_con_mascotas = models.BooleanField(default=False)
    foto = models.ImageField(upload_to='nanas_fotos',
                            default='media/nana-default.png', null=True, blank=False)
    # antecedentes_policiales = models.FileField(upload_to='nanas_antecedentes_policiales')


    def __str__(self):
        return self.nombre

Base Usuario model

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)
    #documento = models.CharField(blank=False, null=False, max_length=100)
    #Se añadió tipo_documento como campo dentro de usuario. Solo así permite llamarlo como parte del modelo Nana.
    # tipo_documento = models.ForeignKey(TipoDocumento, on_delete=models.SET_NULL, null=True)
    telefono_o_celular = models.CharField(max_length=14)
    esta_activo = models.BooleanField(default=False)
    genero = models.CharField(blank=False, null=False, choices=GENERO, max_length=1, default='f')
    direccion = models.CharField(blank=False, null=False, max_length=160, default='')
    latitud = models.CharField(blank=False, null=False, max_length=60, default='')
    longitud = models.CharField(blank=False, null=False, max_length=60, default='')

Added view

class RegistroView(View):
    def get(self, request):
        nana_form = NanaForm()
        ls_tipos_de_documento = TipoDocumento.objects.values_list('id', 'nombre_corto')
        ls_habilidades = Habilidad.objects.values_list('id', 'nombre')
        ls_especialidades = Especialidad.objects.values_list('id', 'nombre')
        context = {'nana_form': nana_form, 'ls_tipos_de_documento': ls_tipos_de_documento, 'ls_especialidades': ls_especialidades, 'ls_habilidades': ls_habilidades, }
        return render(request, 'app_administrador/crear-registro-como-secretaria.html', context)

    def post(self, request):
        nana_form = NanaForm(request.POST, request.FILES)
        if nana_form.is_valid():
            nana_form.save()
        else:
            print(nana_form.errors)
            print(nana_form['habilidades'])
        return HttpResponseRedirect('/')
Omar Gonzales
  • 3,806
  • 10
  • 56
  • 120

1 Answers1

0

But I think what your problem is that you are trying to to use a many-to-many when you should be using a 1-to-many.

If only a 1-to-1 or 1-to-many is needed to access the info then python will not let you use a many-to-many here.

Please try re-evaluate your logic and ensure you are using the right type of DB relationship. After trying those, if you are certain that you need a Many-to-Many then I will work my way though the Spanish and help you out.

Somosfeer
  • 72
  • 8
  • Using a Many to Many relationship, a Nana can have many "habilidades" associated, and the "habilidades" can be associated to many Nanas. If we were to use a "One to Many" relationship, if a Nana gets "habilidades 1" no other Nana could use this ability. – Omar Gonzales Dec 01 '17 at 19:21
  • This goes like this: "Nana" is a employee that takes care of a baby, but can also cook, clean, etc. So "Nana" may have a lot of abilities ("habilidades"), as well as specialities ("especialidades") like "Spanish food", "See food", etc. Talking to a coworker to confirm this, he told me: A "Nana" can have multiple "habilidades" (abilities), and 1 "habilidades" can have a lot of "Nana" objects asociated. Thank you for your time. – Omar Gonzales Dec 01 '17 at 19:22
  • Ok so I'm still thinking you want a many-to-one. Because you want one Nana with many abilities, or one ability with many Nanas. " a Nana gets "habilidades 1" no other Nana could use this ability" in the ability table each ability will have rows for each of the Nanas that the ability is attached to . so "sweeping" will have user_id 1, 2 and one for as many where added with that nana. And then you reverse your query to get the skills and nana has. Once again please try this with the one-to-many. If it does not work, post again and I will work it out this evening and post tomorrow for you – Somosfeer Dec 01 '17 at 19:45
  • Also I found this. https://stackoverflow.com/questions/25386119/whats-the-difference-between-a-onetoone-manytomany-and-a-foreignkey-field-in-d – Somosfeer Dec 01 '17 at 19:51
  • Have you made progress? – Somosfeer Dec 02 '17 at 16:14
  • 1
    Yep. Will post solution as soon as I can. – Omar Gonzales Dec 02 '17 at 16:28