Reputation: 79
This is a database for use in Brazil, so the language is Portuguese. Translation:
I use this database to keep track of vehicles in a parking lot with monthly vehicle records.
My problem is one of permutations: Each person could have many vehicles, but each vehicle belongs to only one person.
I'm using the SqlLite 3 from Django
Foreign key in the database
Models.py
class Pessoa(models.Model):
nome = models.CharField(max_length=50, blank=False)
email = models.EmailField(blank=False)
cpf = models.CharField(max_length=11, unique=True, blank=False)
endereco = models.CharField(max_length=50)
numero = models.CharField(max_length=10)
bairro = models.CharField(max_length=30)
telefone = models.CharField(max_length=20, blank=False)
cidade = models.CharField(max_length=20)
estado = models.CharField(max_length=2, choices=STATE_CHOICES)
class Veiculo(models.Model):
marca = models.ForeignKey(Marca, on_delete=models.CASCADE, blank=False)
modelo = models.CharField(max_length=20, blank=False)
ano = models.CharField(max_length=7)
placa = models.CharField(max_length=7)
proprietario = models.ForeignKey(
Pessoa, on_delete=models.CASCADE, blank=False, )
cor = models.CharField(max_length=15, blank=False)
observacoes = models.TextField(blank=False)
class Mensalista(models.Model):
veiculo = models.ForeignKey(Veiculo, on_delete=models.CASCADE,
blank=False)
inicio = models.DateField(blank=False)
validade = models.DateField(blank=False)
proprietario = models.ForeignKey(
Pessoa, blank=False, on_delete=models.CASCADE)
valor_mes = models.DecimalField(
max_digits=6, decimal_places=2, blank=False)
pago = models.CharField(max_length=15, choices=PAGO_CHOICES)
Upvotes: 0
Views: 87
Reputation: 2664
You don't need to store the Person (Pessoa) in the Monthly (Mensalista) model as it is already defined by the vehicle. Having an instance of Mensalista
(let's say m
) you can access the Vehicles's owner simply by doing m.veiculo.proprietario
If, for some reason (clarity, cleanness or whatever) you want to have a proprietario
property on your Mensalista
model you could simply add the following:
@property
def proprietario(self):
return self.veiculo.proprietario
To sum up you could change your Mensalista
model to the following:
class Mensalista(models.Model):
veiculo = models.ForeignKey(Veiculo, on_delete=models.CASCADE, blank=False)
inicio = models.DateField(blank=False)
validade = models.DateField(blank=False)
# The next is not necessary
# proprietario = models.ForeignKey(Pessoa, blank=False, on_delete=models.CASCADE)
valor_mes = models.DecimalField(max_digits=6, decimal_places=2, blank=False)
pago = models.CharField(max_length=15, choices=PAGO_CHOICES)
@property
def proprietario(self):
return self.veiculo.proprietario
To clarify a bit more, the models as you have them are what is called denormalized (you can read more about normalization and denormalization here. Essentially your models are redundant since you have a ForeignKey
to Person
on both Vehicle
and Monthly
but you want that the person in Monthly
is the same as the person in Vehicle
. You can save yourself some trouble by erasing the reference to Person
in your Monthly
model. In this way you don't need to enforce that both reference to Person
coincide as there is only one reference to Person
.
Upvotes: 0
Reputation: 11
I'd suggest you to model this scenario a bit different. As your model Vehicle
is already related to your model Person
, your attribute proprietario in the model Mensalista
is not necessary and this sounds enough to solve your problem.
Notice that once you can get a Person's
attributes due the relationship it has with you model Vehicle
, it doens't make sense (in my humble opinion and inside this context) to explicitly relate a Person
to Mensalita
, if you already have an implictly relatioship between them through your model Vehicle
:
mensalita = Mensalita.objects.get(pk=this_object_id);
veiculo = mensalita.veiculo;
pessoa = veiculo.proprietario; //You've got your Person without problems.
However, in a context where two people share the same vehicle and this car is eventually parked by some of this drivers, this attribute would be helpful but yet not the best solution for your problem.
I hope I understood correctcly your problem. Please let me know if it's everything clear enough for you. I'll be glad to help you out if I missed something.
Upvotes: 1