数据库中的外键

时间:2018-11-28 22:09:08

标签: python sql django

这是一个在巴西使用的数据库,所以语言是葡萄牙语。翻译:

  • 佩索阿=人
  • Veiculo =车辆

我使用该数据库来跟踪具有每月车辆记录的停车场中的车辆。

我的问题是一种排列方式:每个人可能有很多车辆,但是每辆车只属于一个人。

我如何确保在输入时仅以人员(佩索阿)的名义注册车辆,而不是以车辆(Veiculo)的名义注册?

我正在使用Django的SqlLite 3

数据库中的外键

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)

2 个答案:

答案 0 :(得分:1)

我建议您对这种情况进行建模有点不同。由于您的模型Vehicle已与模型Person相关,因此模型Mensalista中的属性属性不是必需的,这听起来足以解决您的问题。
请注意,一旦您获得Person's属性,因为它与您的模型Vehicle有关系,就我而言,在我看来,{{1 }}到Person,如果您已经通过模型Mensalita隐含它们之间的关系:

Vehicle

但是,在两个人共享同一辆车并且此车最终被其中一些驾驶员停放的情况下,此属性将很有帮助,但并不是解决您问题的最佳解决方案。

希望我能正确理解您的问题。请让我知道是否一切都足够清楚。如果我错过了什么,我将很乐意为您提供帮助。

答案 1 :(得分:0)

您不需要将“人员”(Pessoa)存储在“月度(Mensalista)”模型中,因为车辆已经定义了该模型。拥有Mensalista的实例(例如m),您只需执行m.veiculo.proprietario

即可访问车辆的所有者

如果出于某种原因(澄清,整洁或其他原因)想要在proprietario模型上拥有Mensalista属性,则可以简单地添加以下内容:

@property
def proprietario(self):
    return self.veiculo.proprietario

总而言之,您可以将Mensalista模型更改为以下内容:

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

为了更清楚一点,您拥有的模型称为非规范化模型(您可以阅读有关规范化和非规范化here的更多信息。本质上,模型是多余的,因为您有ForeignKey PersonVehicle上的Monthly,但您希望Monthly中的人与Vehicle中的人相同。删除Person模型中对Monthly的引用,这样就无需强制对Person的引用都是一致的,因为对Person的引用只有一个