18

我想创建一个可重用的 Django 应用程序来处理用户的状态更新。很像 facebook 的“新闻提要”。

用例包括,例如:

  • 教授可以根据特定日期创建作业,每个学生都可以在新闻提要上看到作业已创建,并附有简短说明、到期日期和查看完整说明的链接
  • 他还可以上传他认为对他的学生感兴趣的新 PDF。在新闻提要上,应显示与此相关的信息,例如 pdf 的描述、下载链接和预览链接
  • 可以发布指向 YouTube 视频的链接,并在 News Feed 上显示一个小缩略图,只需单击一下,视频就会使用 javascript 嵌入,用户可以立即观看。

一个问题是如何处理不同类型的更新并为其显示正确的“html 片段”。另一个更重要的是如何设计这种“Django 方式”的模型。

关于前者,我可以想到两种方法:

  1. 使用模型继承;
  2. 使用通用关系。

我在这里发帖之前搜索过,但我没有找到任何东西。我检查了 Pinax,看看他们是否实现了它,但他们没有。所以,我在这里寻找更多关于如何以一种好的和非黑客的方式处理这个问题的建议。

提前致谢,

4

4 回答 4

17

Python 实际上是用于构建 Activity Streams 和 Newsfeeds 的绝佳语言。Tommaso 和我编写了 Stream Framework 包。 https://github.com/tschellenbach/stream-framework 是目前用于构建新闻源的最常用的 Python 解决方案。我们还在https://getstream.io提供托管解决方案。到目前为止,Django 客户端是最容易上手的: https ://github.com/GetStream/stream-django和 python 可以在这里找到 ( https://github.com/getstream/stream-python )

模板部分是这样工作的

{% load stream_django %}

{% for activity in activities %}
    {% render_activity activity %}
{% endfor %}

这将呈现位于 activity/tweet.html 中的模板,并将活动作为上下文。例如

{{ activity.actor.username }} said "{{ activity.object.body }} {{ activity.created_at|timesince }} ago"

完整的文档在这里: https ://github.com/GetStream/stream-django#templating

Stream Framework 允许您使用 Redis 或 Cassandra 构建任何类型的新闻源。它是按比例构建的,并使用扇出过程创建单独的新闻源。

除了 Stream Framework(我显然更喜欢)之外,还有许多其他解决方案。django 包上提供了完整列表: https ://www.djangopackages.com/grids/g/activities/

请注意,对于新闻源,需要牢记一些缩放问题。一般来说,有3种常见的方法:

非规范化策略

大多数 用户都是这样开始的。当您打开提要页面时,您只需查询您关注的所有用户的提要。如果用户提要存储在内存中,这将继续工作相当长的一段时间。最终很难继续使用这种策略,因为您经常需要查询存储用户提要的大多数节点。

推送 推送方法将您的活动写入您的所有关注者供稿。当然,这意味着您浪费了大量资源,但最终结果是每个用户预先计算的提要。这种方法(虽然最初不是很有效)很好地扩展。

组合 一些优化的系统使用这两种方法的组合。另请参阅有关此主题的 Yahoo 论文。

存储选项

在存储所有这些数据方面,最常见的选项是 Redis、Cassandra 和 MongoDB。让我们快速比较一下:

Redis Redis 非常容易设置和维护。但是,它仅将数据存储在内存中。这意味着您必须优化序列化数据的方式,并可能回退到数据库以获取不经常查询的数据。另一个问题是,将机器添加到 Redis 集群并非易事。

MongoDB Mongo DB 主要由一些 ruby​​ 项目使用,它也可用作 e14n 的 pump.io 的后端。我个人从未在生产中运行过它,因此我无法正确评估此选项。然而,有很多博客文章涉及 mongo 的性能、可扩展性和可维护性问题。

Cassandra Fashiolista、Instagram 和 Spotify 都在使用 Cassandra。我们的托管解决方案还使用 Cassandra 作为后端。操作起来极具成本效益,您可以轻松添加更多节点。唯一的问题是很难设置和维护。

文章

另外看看这篇高可扩展性帖子,我们解释了一些涉及的设计决策:http: //highscalability.com/blog/2013/10/28/design-decisions-for-scaling-your-high-traffic-提要.html

要了解有关提要设计的更多信息,我强烈建议阅读我们基于提要的一些文章:

于 2014-10-07T13:37:43.893 回答
9

我可以从两个方面思考:

首先,也许您可​​以为您的模型、和制作提要,并使用库feedparser将其嵌入到您的新闻视图中,这是一种简单的方法,因为您可以在模板中定义每种新活动的代码。AssigmentsPdfFilesYoutube link

我能想到的第二件事是创建一个类Activity

class Activity(models.Model):
    date = models.DateTimeField(auto_now_add = True)
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')

每次你有一个新的分配或 pdf 上传或 youtube 链接时,通过信号render_to_html创建一个新的 Activity 实例,并为每个类创建一个类似的方法,这样在你的视图中,你可以创建一个 for over Activities 并调用方法 render_to_html

于 2010-01-24T22:22:49.183 回答
5

经过更多的谷歌搜索和diegueus9提到的一个有用的关键字(“ Activity ”)以及我以前没有想到的,我能够找到更多相关的材料。

ContentType首先,两篇关于如何使用 django 使用框架构建 tumbleblog 的博文:

在那之后,另一篇文章给出了如何减少 (1 + n) 查询问题的建议(这是我最初关心的问题之一,但我没有提到以避免混淆问题)。

最后是一个可重用的 Django 应用程序,它具有我需要的一些功能,可用于进一步参考:

于 2010-01-25T00:14:28.097 回答
3

通用关系将是这里的方法。只需确保自己解析模型,而不是加入更新表。

于 2010-01-24T21:19:09.317 回答