用于构建“新闻源”/“状态更新”/“活动流”的Django方式

时间:2010-01-24 21:16:53

标签: django django-models status news-feed activity-streams

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

用例包括,例如:

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

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

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

  1. 使用模型继承;
  2. 使用通用关系。
  3. 我在张贴之前搜索过,但我没有找到任何东西。我检查了Pinax,看看他们是否实施了它,但他们没有。所以,我在这里寻找更多关于如何以一种漂亮和非黑客的方式处理这个问题的建议。

    提前致谢,

4 个答案:

答案 0 :(得分:15)

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/

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

非规范化策略

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

<强>推 推送方法将您的活动写入您的所有关注者Feed。当然,这意味着您浪费了大量资源,但最终结果是每个用户预先计算的Feed。这种方法(尽管最初效率不高)可以很好地扩展。

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

存储选项

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

<强> Redis的 Redis非常易于设置和维护。但它只将数据存储在内存中。这意味着您必须优化序列化数据的方式,并且可能回退到数据库以查找频率较低的数据。另一个问题是,将计算机添加到Redis群集并非易事。

<强> MongoDB的 Mongo DB主要用于一些ruby项目,它也可以作为e14n的pump.io的后端。我个人从未在生产中使用它,因此我无法正确评估此选项。然而,有许多博客文章涉及mongo的性能,可伸缩性和可维护性问题。

<强>卡桑德拉 Fashiolista,Instagram和Spotify都在使用Cassandra。我们的托管解决方案也使用Cassandra作为后端。它的运行成本非常高,您可以轻松添加更多节点。唯一的问题是难以设置和维护。

<强>文章

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

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

答案 1 :(得分:7)

我可以用两种方式思考:

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

我能想到的第二件事就是上课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链接时,通过signals制作一个新的Activity实例,并为每个类制作一个类似render_to_html的方法,以这种方式在您的查看,你可以为活动做一个并调用方法render_to_html

答案 2 :(得分:5)

经过更多谷歌搜索和一个有用的关键词(“活动”) diegueus9 提到并且我之前没有想过,我能够找到更多相关材料。

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

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

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

答案 3 :(得分:3)

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