【问题标题】:Django - Can I use an abstract Model in another Model?Django - 我可以在另一个模型中使用抽象模型吗?
【发布时间】:2016-04-12 05:31:42
【问题描述】:

我是 Django 新手(自从我玩数据库以来已经有几年了),并且可能正在围绕一些我不知道该用谷歌搜索什么的简单的东西跳舞。

本质上,我想要一个“事件”表,其中可以包含各种类型的数据。假设一个事件是“警报”,另一个是“消息”。 “警报”类型需要与“消息”不同的字段,因此不将数据存储在一个包含任何事件可能需要的任何类型数据的大表中似乎是有意义的。但是,我希望能够获取给定“event_block”外键的所有事件列表。

我已经阅读了一些关于抽象模型和代理等的信息,但我无法弄清楚一个模型如何引用抽象模型(如果这实际上是要走的路)。

models.py:

class Event(models.Model):
  #id auto-generated primary_key
  event_block = models.ForeignKey(Block, on_delete=models.CASCADE)
  event_data = BaseEvent  # This is wrong, but what is right?

class BaseEvent(Models.model):
  class Meta:
    abstract=True
  ... common event info ...

class AlarmEvent(BaseEvent):
  ... event info for alarms ...

class MessageEvent(BaseEvent):
  ... event info for messages ...

理想情况下,我可以在我的模板中创建一个包含所有可用 event_types 的下拉框,然后单击表单的“提交”按钮以在我的事件模型中创建该事件(及其必要的事件数据字段)和让 Django 处理在数据库表中如何处理的细节。

我错过了什么?

【问题讨论】:

    标签: django


    【解决方案1】:

    首先,这适用于Event 模型

    class Event(models.Model):
      event_block = models.ForeignKey(Block, on_delete=models.CASCADE)
      event_data = models.ForeignKey(BaseEvent)
    

    但是... BaseEventabstract=True 实际不存在,但其子 AlarmEventMessageEvent 存在。所以我不确定你是否可以将BaseEvent 指向ForeignKeyThis post about generic foreign key 可能会有所帮助。

    其次是关于模型的结构。 IMO,没有抽象的母类,事情会变得更简单。带类别字段的模型怎么样?

    CATEGORY = ( ('field1', 'field name 1'), ('field2', 'field name 2'), )
    class Event(models.Model):
      category = models.CharField(max_length=10, choices=CATEGORY)
      # SOME OTHER FIELDS...
    

    默认情况下,您可以通过 django admin 查看模型的形式。

    【讨论】:

    • 感谢您展示 CATEGORY 字段的工作原理 - 这是我还没有遇到过的。但是,这仍然需要我的“事件”类型包含“事件”的所有不同“类别”的所有数据,是吗?
    • SO 上的“通用外键”链接很有帮助——看起来与我的问题类似。似乎这可能是获得我想要的东西的正确解决方案,但我想知道它是否有足够的缺点不值得。刚开始使用 Django 时,在考虑可维护性、速度、内存等方面很难知道“正确”的解决方案是什么。我想知道在某个地方是否有很好的参考?
    【解决方案2】:

    这些单独的表格的原因是什么?你要直接问他们吗?这些事件是否应该共享数据?

    如果这些问题的答案是“我不确定”(或者更好的是“否”),那么您如何(而不是创建单独的表)将所有数据直接保存在 Event 模型上?类似的东西

    class Event(models.Model):
        #id auto-generated primary_key
        event_block = models.ForeignKey(Block, on_delete=models.CASCADE)
        event_data = models.TextField()
    

    并以序列化格式(例如 JSON)将数据保存在 event_data 字段中。或者你可以使用一些插件,例如https://github.com/bradjasper/django-jsonfieldJSONField

    一些常用字段可以分开,例如:

    class Event(models.Model):
        #id auto-generated primary_key
        event_block = models.ForeignKey(Block, on_delete=models.CASCADE)
        event_type = models.CharField(max_length=2)
        event_data = models.TextField()
    

    【讨论】:

    • JSON 想法对于某些类型的数据来说是一个很好的想法 - 但在我的情况下,我需要能够对该数据的一些细节进行查询,所以如果这些是更好的每个单独的字段。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-09
    • 2018-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    相关资源
    最近更新 更多