Cristobal Novoa
Cristobal Novoa

Reputation: 49

django foreign key Cannot assign must be a instance error

I have a database with the table cargo_empleado that has an id=1 and cargo_empleado='gerente', I also have an Empleado table, in the Empleado table I want to create an employee, I have a form to create an employee, the employee table has as foreign key cargo_empleado, when I put in the form that the employee belongs to the job id=1, it gives me the error:

models.py

class CargoEmpleado(models.Model):
nombre_cargo = models.CharField(max_length=50, blank=True, null=True)

class Meta:
    managed = False
    db_table = 'Cargo_empleado'


class Empleado(models.Model):
rut = models.CharField(primary_key=True, max_length=9)
nombres = models.CharField(max_length=100, blank=True, null=True)
apellidos = models.CharField(max_length=100, blank=True, null=True)
correo_electronico = models.CharField(max_length=100, blank=True, null=True)
usuario = models.CharField(max_length=50, blank=True, null=True)
contrasena = models.CharField(max_length=255, blank=True, null=True)
activo = models.IntegerField()
cargo_empleado = models.ForeignKey(CargoEmpleado, models.DO_NOTHING, db_column='cargo_empleado')
id_empresa = models.ForeignKey('Empresa', models.DO_NOTHING, db_column='id_empresa', blank=True, null=True)
id_unida = models.ForeignKey('UnidadInterna', models.DO_NOTHING, db_column='id_unida')

class Meta:
    managed = False
    db_table = 'Empleado'

views.py

def crearusuario(request):
if request.method=="POST":
    if request.POST.get('rut') and request.POST.get('nombres') and request.POST.get('apellidos') and request.POST.get('correo_electronico') and request.POST.get('usuario') and request.POST.get('contrasena') and request.POST.get('activo') and request.POST.get('cargo_empleado') and request.POST.get('id_empresa') and request.POST.get('id_unida'):
        usersave= Empleado()
        usersave.rut=request.POST.get('rut')
        usersave.nombres=request.POST.get('nombres')
        usersave.apellidos=request.POST.get('apellidos')
        usersave.correo_electronico=request.POST.get('correo_electronico')
        usersave.usuario=request.POST.get('usuario')
        usersave.contrasena=request.POST.get('contrasena')
        usersave.activo=request.POST.get('activo')
        usersave.cargo_empleado=request.POST.get('cargo_empleado')
        usersave.id_empresa=request.POST.get('id_empresa')
        usersave.id_unida=request.POST.get('id_unida')
        cursor=connection.cursor()
        cursor.execute("call SP_crear_usuario('"+usersave.rut+"','"+usersave.nombres+"', '"+usersave.apellidos+"', '"+usersave.correo_electronico+"', '"+usersave.usuario+"', '"+usersave.contrasena+"', '"+usersave.activo+"', '"+usersave.cargo_empleado+"', '"+usersave.id_empresa+"', '"+usersave.id_unida+"')")
        messages.success(request, "El empleado "+usersave.nombres+" se guardo correctamente ")
        return render(request, 'app/crearusuario.html')
else:
    return render(request, 'app/crearusuario.html')

help me please!!

Upvotes: 2

Views: 588

Answers (1)

little_birdie
little_birdie

Reputation: 5857

Well.. there are a lot of things you should be doing differently here.. for one thing, you should use a ModelForm rather than directly saving POST data...

But, to directly answer your question, since Django's ORM represents rows in the database as objects, if you're assigning a related row, the object representing that row is expected. That's what the error is telling you.

But if you want to set a relationship using the value of the foreign key directly, append _id to the field name, eg:

usersave.cargo_empleado_id=request.POST.get('cargo_empleado')

EDIT: On second look, I see you're calling a stored procedure anyway, something that Django isn't (at least, not in any of the versions I've used) very friendly about. Models want to save themselves using SQL inserts and updates. In your code above, there's really no reason to create the model instance at all or to assign your inputs to it, since you're just passing those same values to the stored procedure.

But you should use a Form to validate the POST data. By passing POST data directly into a SQL string you are opening a huge hole for SQL injection attacks. This code is completely insecure.. someone could execute any SQL command they want to in your database.

To avoid SQL injection attacks, use the params argument to cursor.execute() rather than building the whole SQL string yourself. Documentation here:

https://docs.djangoproject.com/en/4.1/topics/db/sql/#executing-custom-sql-directly

EDIT: In response to your comment, the way you would assign the relation by object rather than by id would be to find the object in the database first, then assign it. Example:

usersave.cargo_emppleado = CargoEmpleado.objects.get(
    pk=request.POST.get('cargo_empleado')
)

This would fetch the CargoEmpleado row from the database, throwing a NotFound exception if the id you are looking for doesn't exist.

Upvotes: 1

Related Questions