假设,有一个页面有许多与其关联的 block 。每个 block 都需要自定义渲染、保存和数据。
从代码的角度来看,最简单的是为每个模型定义不同的类(因此,模型)。简化如下:
class Page(models.Model):
name = models.CharField(max_length=64)
class Block(models.Model):
page = models.ForeignKey(Page)
class Meta():
abstract = True
class BlockType1(Block):
other_data = models.CharField(max_length=32)
def render(self):
"""Some "stuff" here """
pass
class BlockType2(Block):
other_data2 = models.CharField(max_length=32)
def render(self):
"""Some "other stuff" here """
pass
但是,
- 即使使用此代码,我也无法执行像
page.block_set.all()
这样的查询来获取所有不同的 block ,无论 block 类型如何。 - 造成上述情况的原因是,每个模型定义了不同的表;使用链接模型和通用外键来解决这个问题可以解决问题,但每个页面仍然会留下多个数据库表查询。
建模的正确方法是什么?可以以某种方式使用通用外键(或其他东西),以便最好将数据存储在同一个数据库表中,同时实现继承范例。
更新:
我的观点是,我怎样才能让 OOP 范例发挥作用。对这么多 ifs 使用相同的方法并不是我想要做的。
在我看来,最好的解决方案是创建单独的标准Python类(最好在不同的blocks.py中),它定义一个保存,通过实例化相同的模型来保存数据及其“类型”。然后创建一个模板标签和一个过滤器,根据模型的类型调用渲染、保存和其他方法。
最佳答案
不要在数据库中对页面进行建模。页面是一个演示文稿。
首先——也是最重要的——获取正确的数据。
“每个 block 都需要自定义渲染、保存和数据。”分解一下:你拥有独特的数据。从模型角度忽略“ block ”和“渲染”。只需定义数据,而不考虑表示。
说真的。只需在模型中定义数据,无需考虑呈现或渲染或其他任何内容。建立正确的数据模型。
如果您混淆模型和演示,您将永远无法正常工作。如果您确实让它工作,您将永远无法扩展或重用它。
第二 - 只有在数据模型正确之后 - 您可以转向演示。
您的“ block ”可以简单地使用 HTML 来完成 <div>
标签和样式表。首先尝试一下。
毕竟,该模型有效且非常简单。这只是 HTML 和 CSS,与模型分离。
您的“ block ”可能需要自定义模板标签来创建更复杂的条件 HTML。那就试试吧。
在极端情况下,您的“ block ”可能非常复杂,以至于您必须编写专门的 View 函数来将多个对象转换为 HTML。这是非常非常罕见的。在确定无法使用模板标记执行此操作之前,不应执行此操作。
编辑。
“查询不同的外部数据源”
“具有保存方法的单独简单类(不是模型),可以写入同一个数据库表。”
你拥有三个完全不同、不相关、独立的事物。
模型。持久模型。随着
save()
方法。这些作用非常非常小。 它们有属性和一些方法。没有“查询不同的外部数据源”。没有“在 HTML 中渲染”。外部数据源。这些是获取数据的普通 Python 类。 这些对象 (1) 获取外部数据并 (2) 创建模型对象。没有别的。没有“坚持”。没有“在 HTML 中渲染”。
演示。这些是表示 Model 对象的普通 Django 模板。没有外部查询。没有坚持。
关于database - Django 模型通用建模,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1939750/