ValueError:无法分配对象必须是实例

时间:2019-12-11 01:10:13

标签: python django foreign-keys

我一直在尝试注册一个 ClienteNatural ,它具有两个外键,一个是 Correo ,另一个是 Lugar 。在数据库中进行查询以将 Correo 对象传递给 ClienteNatural 时,如果有人可以帮助我,则会出现此错误。谢谢。      暂时我只是给 Lugar 设置了一个固定值以进行测试,然后将其设置为动态,但是分配给 fk_lugar 的那个 Lugar 对象却没有不会产生错误,只是 fk_correo

错误:

*** ValueError:无法分配“ Correo对象(22)”:“ ClienteNatural.fk_correo”必须是“ Correo”实例。

Models.py

class ClienteNatural(models.Model):
rif = models.CharField(primary_key=True, max_length=12)
carnet_id = models.IntegerField(blank=True, null=True)
complemento_direccion = models.CharField(max_length=25)
puntos_disponibles = models.IntegerField(blank=True, null=True)
cedula = models.CharField(max_length=12)
primer_nombre = models.CharField(max_length=12)
segundo_nombre = models.CharField(max_length=12, blank=True, null=True)
primer_apellido = models.CharField(max_length=12)
segundo_apellido = models.CharField(max_length=12)
fk_lugar = models.ForeignKey('Lugar', db_column='fk_lugar', on_delete=models.CASCADE)
fk_correo = models.ForeignKey('Correo', db_column='fk_correo', on_delete=models.CASCADE)

class Meta:
    managed = False
    db_table = 'cliente_natural'

class Correo(models.Model):
codigo = models.AutoField(primary_key=True)
usuario = models.CharField(unique=True, max_length=30)

class Meta:
    managed = False
    db_table = 'correo'

class Lugar(models.Model):
codigo = models.AutoField(primary_key=True)
nombre = models.CharField(max_length=50)
tipo = models.CharField(max_length=50)
fk_lugar = models.ForeignKey('self', models.DO_NOTHING, db_column='fk_lugar', blank=True, null=True)

class Meta:
    managed = False
    db_table = 'lugar'

forms.py

class Cliente_Natural_Form(forms.ModelForm):
rif = forms.CharField(max_length=12, required=True)
carnet_id = forms.IntegerField
complemento_direccion = forms.CharField(max_length=25, required=True,
                                        validators=[RegexValidator(regex='^[a-zA-Z]*$',
                                                                   message='El apellido solo debe contener letras',
                                                                   code='invalid_last_name')])
puntos_disponibles = forms.IntegerField
cedula = forms.CharField(max_length=12, required=True,
                         validators=[RegexValidator(regex='^[0-9]*$',
                                                    message='La cedula debe contener solo numeros',
                                                    code='invalid_cedula')])
primer_nombre = forms.CharField(max_length=12, required=True,
                                validators=[RegexValidator(regex='^[a-zA-Z]*$',
                                                           message='El nombre solo debe contener letras',
                                                           code='invalid_primer_nombre')])
segundo_nombre = forms.CharField(max_length=12, required=False,
                                 validators=[RegexValidator(regex='^[a-zA-Z]*$',
                                                            message='El segundo nombre solo debe contener letras',
                                                            code='invalid_segundo_nombre')])
primer_apellido = forms.CharField(max_length=12, required=True,
                                  validators=[RegexValidator(regex='^[a-zA-Z]*$',
                                                             message='El primer apellido solo debe contener letras',
                                                             code='invalid_primer_apellido')])
segundo_apellido = forms.CharField(max_length=12, required=True,
                                   validators=[RegexValidator(regex='^[a-zA-Z]*$',
                                                              message='El segundo apellido solo debe contener letras',
                                                              code='invalid_segundo_apellido')])
fk_lugar = forms.IntegerField(widget=forms.HiddenInput())
fk_correo = forms.CharField(widget=forms.HiddenInput())

class Meta:
    model = ClienteNatural
    fields = ('rif', 'carnet_id', 'complemento_direccion', 'puntos_disponibles', 'cedula', 'primer_nombre',
              'segundo_nombre', 'primer_apellido', 'segundo_apellido', 'fk_lugar', 'fk_correo')


class Correo_Form(forms.ModelForm):
usuario = forms.CharField(max_length=30, required=True)

class Meta:
    model = Correo
    fields = ('usuario',)

class Lugar_Form(forms.ModelForm):
nombre = forms.CharField(max_length=50, required=True)
tipo = forms.CharField(max_length=50, required=True)
fk_lugar = forms.IntegerField(required=False)

class Meta:
    model = Lugar
    fields = ('nombre', 'tipo', 'fk_lugar')

views.py

def registroClienteNatural(request):
if request.method == "POST":
    formLugar = forms.Lugar_Form(request.POST)
    formCorreo = forms.Correo_Form(request.POST)
    formClienteNatural = forms.Cliente_Natural_Form(request.POST)
    dataCorreo = {'usuario': request.POST.get('usuario')}
    formCorreo = forms.Correo_Form(dataCorreo)
    if formCorreo.is_valid():
        try:
            formCorreo.save()
        except:
            pass
    dataCliente = {'rif': request.POST.get('rif'),
                   'carnet_id': request.POST.get('carnet_id'),
                   'complemento_direccion': request.POST.get('complemento_direccion'),
                   'puntos_disponibles': request.POST.get('puntos_disponibles'),
                   'cedula': request.POST.get('cedula'),
                   'primer_nombre': request.POST.get('primer_nombre'),
                   'segundo_nombre': request.POST.get('segundo_nombre'),
                   'primer_apellido': request.POST.get('primer_apellido'),
                   'segundo_apellido': request.POST.get('segundo_apellido'),
                   'fk_lugar': Lugar.objects.get(codigo=5),
                   'fk_correo': Correo.objects.get(usuario=request.POST.get('usuario'))
                   }
    formClienteNatural = forms.Cliente_Natural_Form(dataCliente)
    if formClienteNatural.is_valid():
        try:
            formClienteNatural.save()
        except:
            pass
else:
    formUsuario = forms.Usuario_Form()
    formClienteNatural = forms.Cliente_Natural_Form()
    formTelefono = forms.Telefono_Form()
    formCorreo = forms.Correo_Form()
    formLugar = forms.Lugar_Form()
return render(request, 'Home/registroUsuario.html', {'formUsuario': formUsuario,
                                                     'formClienteNatural': formClienteNatural,
                                                     'formTelefono': formTelefono,
                                                     'formCorreo': formCorreo,
                                                     'formLugar': formLugar})

1 个答案:

答案 0 :(得分:0)

您的问题出在您的表格中。这应该起作用:

fk_lugar = forms.IntegerField(widget=forms.HiddenInput())
fk_correo = forms.IntegerField(widget=forms.HiddenInput())

这里的问题是,当您说fk_correoCharField时,django在引擎盖下的某个位置将对象转换为字符串。注意您的错误消息中的三引号表示ValueError是因为您传递的是字符串而不是对象:

*** ValueError: Cannot assign "'Correo object (22)'": "ClienteNatural.fk_correo" must be a "Correo" instance.

当您使用IntegerField时,django会得出结论,当您传递对象时,您隐式地传递了主键。这就是fk_lugar有效但fk_correo不起作用的原因。