Django DB Relations

时间:2017-02-02 16:33:42

标签: mysql django database

我为新手问题道歉,但我的头脑即将爆炸。

我正在努力学习Django,并希望创造一些实用且可以使用的东西。我选择了一个小型库存系统。

我遇到的问题是找出理想数据库设置模型之间关系的最佳方法。

我有以下模型:

  • 折旧政策
  • 制造商
  • 客户/用户
  • 资产类别(服务器,笔记本电脑等)
  • 资产模型(Macbook Pro,Proliant DL380 Gen 9等)
  • 资产状态(已存档,已部署,已丢失等)
  • 资产字段(所有资产都具有通用字段 有,模型(FK),状态(FK),购买日期等。)
  • CPU
  • 服务器
  • 网卡

现在我有Server&网卡继承资产字段。

我的目标是为每种类型的资产设置表,但仍然有一个主表可以通过FK引用每个资产类型的表,这样如果我想显示数据库中的所有资产,我可以只列出一个表格,从相关表格中提取相关信息,而不必查看每个资产的表格。

我想要类似的东西:

资产表:

id(pk),型号(fk),状态(fk),序列号,购买日期,成本,位置,server_id / network_card_id(fk)

服务器表:

id(pk),客户,名称,内存,cpu(fk),ilo_type,ilo_lic

资产模型:

class Asset(models.Model):
    # class Meta:
    #     abstract = True

    assetTag = models.CharField(max_length=50, unique=True)
    model = models.ForeignKey(AssetModel, on_delete=models.SET_NULL, null=True)

    status = models.ForeignKey(AssetStatus, on_delete=models.SET_NULL, null=True)
    serialNumber = models.CharField(max_length=50, unique=True)

    purchaseDate = models.DateTimeField('Date order was placed', blank=True)
    purchaseOrder = models.CharField(max_length=25, blank=True)
    cost = models.DecimalField(default=0, max_digits=8, decimal_places=2, blank=True)

    # location = models.CharField(max_length=25, blank=True, null=True)

    def calculate_current_value(self, purchaseDate, cost):
        purchase_price = float(cost)
        months = self.model.depreciationPolicy.months

        if months > 0:
            days = months * 30
            depreciation_per_day = (float(cost) / days)
            days_owned = timezone.now() - purchaseDate

            value_lost = days_owned.days * depreciation_per_day
            current_asset_value = purchase_price - value_lost
            return round(current_asset_value, 2)

    def __str__(self):
        return self.serialNumber

服务器型号:

class Server(Asset):
    customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, null=True)
    memory = models.IntegerField(default=0)
    cpu = models.ForeignKey(Cpu, on_delete=models.SET_NULL, null=True)

    ILOType = models.CharField(max_length=50, choices=(('Std', 'Standard'), ('Adv', 'Advanced')))
    ILOUsername = models.CharField(max_length=50, null=True, blank=True)
    ILOPassword = models.CharField(max_length=100, null=True, blank=True)
    ILOLicense = models.CharField(max_length=50, null=True, blank=True)

    def __str__(self):
        return self.serialNumber

Network_Card型号:

class Nic(Asset):
    macAddress = models.CharField(max_length=100, unique=True)
    portCount = models.IntegerField(default=0)
    portType = models.CharField(max_length=50, choices=(('Ethernet', 'Ethernet'), ('Fiber', 'Fiber')))

    def __str__(self):
        return self.name

2 个答案:

答案 0 :(得分:0)

我相信我已经解决了这个问题。 解决方案是按如下方式构建它。而不是服务器& Nic类继承了Asset类,我和它们以及Asset类定义了1:1的关系。

asset = models.OneToOneField(Asset, on_delete=models.CASCADE, primary_key=True)

这允许资产表跟踪所有资产,而asset_id(PK)既是服务器&中的foreign_key又是primary_key。 NIC。

答案 1 :(得分:0)

我建议的第一件事就是忘记桌子。您不是在处理Django中的表,而是使用模型,这些模型是表示系统实体的类。模型会在稍后成为表格,但您现在不必关心它们。

其次,仔细模拟你的课程。设计一个代表他们关系的好图表。在您的场景中,一个类将包含对其他类(一个数据透视类)的引用,因此建模。

另外,请花点时间阅读文档。 Django是一个非常整洁和完整的文档。仔细阅读模型和squerysets。您将了解在架构中表示内容所需的一切。

一些提示:

在定义外部字段时,您将有很多选项,包括ForeighKey(),ManyToManyField(),ManyToOneRel()等。阅读每个选项,并选择代表的选项。你的现实最准确。

ManyToMany()有一个有趣的行为,即:如果你没有将表传递给它,它将为你创建一个,作为一个支点。我更喜欢创建我的中间表,因为它更符合Python的Zen。

当您想要返回数据的连贯表示时,您必须使用查询集来强制执行您在模型中建立的关系,这与您使用的方式非常相似关系数据库,可以通过构建查询或设计视图。

这里有一些很好的链接:

此外,我强烈建议您在掌握Django模型的基本概念后立即查看Django Rest Framework。这是链接:http://www.django-rest-framework.org/

当你有更具体的问题时,请回复我。

快乐的编码!