So I have these models in my app:
from django.db import models
from accounts.models import Vendedor
class Comissao(models.Model):
porcentagem = models.FloatField()
def __str__(self):
return str(self.porcentagem)
class Venda(models.Model):
vendedor = models.ForeignKey(Vendedor, on_delete=models.DO_NOTHING)
comissao_venda = models.ForeignKey(Comissao, on_delete=models.DO_NOTHING)
data_venda = models.DateField(auto_now_add=True)
valor_venda = models.FloatField()
descricao_venda = models.CharField(max_length=60)
@property
def valor_a_receber(self):
return self.comissao_venda.porcentagem * self.valor_venda
def __str__(self):
return str(self.vendedor)
and my problem is when I try to delete Comissao
object I get this error:
FOREIGN KEY constraint failed
I´ve been hours stuck in this error, hope can someone help me...XD
This is due to the DO_NOTHING
: ForeignKey
s are enforced at the database level: that means that a commissao_venda
needs to refer to a valid Comissao
, but if you remove the Commisao
, then that is no longer the case, hence the database rejects this. Or, as is documented:
Take no action. If your database backend enforces referential integrity, this will cause an
IntegrityError
unless you manually add an SQLON DELETE
constraint to the database field.
Often DO_NOTHING
is not a good idea anyway. The question is what do you want to do with the Venda
in case the Comissao
it refers to is removed? Two popular options are:
CASCADE
, in that case the Venda
(s) that refer to that Comissao
are removed as well. This can trigger other removals, and thus a single Comissao
can eventually trigger removing a lot of records from several tables; or
SET_NULL
, you will have to make your field NULLable, by setting null=True
[Django-doc]. In that case the commissao_venda
will be set to NULL
/None
. The field thus then looks like:
comissao_venda = models.ForeignKey(Comissao, null=True, on_delete=models.SET_NULL)
Other options are PROTECT
, RESTRICT
, SET_DEFAULT
, and SET(…)
. It of course all depends on what you want to happen in that case.