【问题标题】:ValueError: Cannot assign object must be a instanceValueError:无法分配对象必须是实例
【发布时间】:2020-04-04 06:00:20
【问题描述】:

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

错误:

*** ValueError: Cannot assign "'Correo object (22)'": "ClienteNatural.fk_correo" 必须是 "Correo" 实例。

模型.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})

【问题讨论】:

    标签: python django foreign-keys


    【解决方案1】:

    你的问题在于你的形式。这应该有效:

    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 不能工作的原因。

    【讨论】:

      猜你喜欢
      • 2018-06-03
      • 1970-01-01
      • 1970-01-01
      • 2019-11-14
      • 2021-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多