使用Django,我将如何生成一个汤博乐风格的不同对象的日期排序页面系列



我有一个Django应用程序,里面有不同的类,比如Post、Quote、Image、Link等。就像汤博乐中的项目一样。每个对象都有一个日期时间。

我想显示所有类型的20个最新项目的组合列表。我希望能够翻页浏览旧项目。就像汤博乐的网页一样。

但我想不出如何在许多不同类型的对象之间进行这样的查询。。。我是否必须创建一个单独的类,比如:

class CombinedItem(models.Model):
    date = models.DateTimeField()
    item_type = models.CharField() # eg, 'post', 'quote', 'image', 'link'
    item_id = models.IntegerField()

每当我添加新的Post、Quote、Image等时,都会在其中添加一个新条目。然后,对于我的列表,查询CombinedItem类中的最新条目,然后获取它返回的每个条目的主要详细信息?如果是这样的话,最有效的方法是什么?谢谢

您最好的选择是实际反向工作。每一种都是用户生成的内容,因此它们都应该继承一个共同的基础:

class ContentItem(models.model):
    # common fields here
class Post(ContentItem):
    # post specific fields
....

然后,您可以简单地查询基本模型ContentItem,并获得所有内容的列表。

唯一潜在的问题是结果是ContentItems,而不是Posts、Quotes等。然而,在Django的MTI(多表继承)实现中,子类是父类上的一个属性。因此,"Post"ContentItem将具有.post属性,您可以从该属性访问Post。您可以将其与hasattr结合起来,创建可以在视图中使用的实用程序方法。例如:

class ContentItem(models.Model):
    ...
    def is_post(self):
        return hasattr(self, 'post')

然后,在您的模板中:

{% if content_item.is_post %}
    <!-- do some post-specific rendering here -->
{% endif %}

一个更干净的方法是创建一个名为Item的通用模型(或者CombinedItem,如果你喜欢的话),并从中继承几个模型(Post、Quote、Image等)。Django在设计时考虑到了模型继承,多表继承功能涵盖了你的特定需求。

使用这种技术,数据库将具有不同的Items、Posts、Quotes等表,您可以从中运行单独的查询。

您可以使用GenericForeignKey[1],它将生成与您所描述的几乎相同的结构。

最大的区别是item_type字段实际上是contenttypes表的外键,Django会自动维护该表。

不幸的是,标准的ORMfilter()方法在该字段上不起作用。您必须单独查询模型的日期范围。

或者,您可以将一个通用外键与一个未规范化的上次修改的时间戳字段相结合,每当相关对象发生变化时,您都会更新该字段,然后您可以非常快速地查询该字段,并在需要时为前20名列表提取相关对象。

[1]https://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/#generic-关系

最新更新