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

Posted

技术标签:

【中文标题】用于构建“新闻提要”/“状态更新”/“活动流”的 Django 方式【英文标题】:Django-way for building a "News Feed" / "Status update" / "Activity Stream" 【发布时间】:2011-01-08 21:22:06 【问题描述】:

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

用例包括,例如:

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

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

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

    使用模型继承; 使用通用关系。

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

提前致谢,

【问题讨论】:

看看我们是如何在这里做模板的:github.com/GetStream/stream-django#templating 自定义模板标签让它变得非常干净。 【参考方案1】:

我可以从两个方面考虑:

首先,也许您可​​以为您的模型 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')

并且通过signals每次你有一个新的分配或pdf上传或youtube链接时创建一个新的Activity实例,并为每个类创建一个类似render_to_html的方法,这样在你看来,你可以做一个 for over 活动并调用方法 render_to_html

【讨论】:

嗨 diegueus9!感谢您指出提要框架。我已经看到它在文档中链接,但从未检查过。关于 Activity 模型,它似乎确实是最好的方法。 您好 Tiago,很高兴,如果您需要有关 ContentType 框架或信号的更多帮助,请不要怀疑联系 mw。 两个链接都失效了:/【参考方案2】:

Python 实际上是一种用于构建 Activity Streams 和 Newsfeed 的出色语言。 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 框架允许您使用 Redis 或 Cassandra 构建任何类型的新闻源。它是按比例构建的,并使用扇出过程创建单独的新闻源。

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

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

非规范化策略

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

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

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

存储选项

就存储所有这些数据而言,最常见的选项是 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

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

Yahoo Research Paper Twitter 2013 Redis based,带后备 Cassandra at Instagram Etsy feed scaling Facebook history Django project,具有良好的命名约定。 (但仅限数据库) http://activitystrea.ms/specs/atom/1.0/(演员、动词、宾语、目标) Quora post on best practises Quora scaling a social network feed Redis ruby example FriendFeed approach Thoonk setup Twitter's Approach

【讨论】:

【参考方案3】:

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

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

http://ryanberg.net/blog/2008/jun/24/basics-creating-tumblelog-django/ http://ryanberg.net/blog/2008/jul/2/basics-creating-tumblelog-django-part-2/

在那之后,另一篇文章就如何减少 (1 + n) 查询问题提供了建议(这是我最初担心的问题之一,但为了避免问题混乱,我没有提及)。

http://zerokspot.com/weblog/2008/08/13/genericforeignkeys-with-less-queries/

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

http://github.com/philippWassibauer/django-activity-stream

【讨论】:

这是另一个活动流应用程序(链接到上面粘贴的那个)可能更好(据称更简单 + 更多作者,更多活动)github.com/justquick/django-activity-stream【参考方案4】:

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

【讨论】:

嗨,Ignacio,您所说的“自己解决模型”是什么意思?感谢您的回答! 使用各种ContentType方法来获取合适的模型类,而不是直接戳GenericForeignKey字段。 感谢您的澄清,伊格纳西奥!

以上是关于用于构建“新闻提要”/“状态更新”/“活动流”的 Django 方式的主要内容,如果未能解决你的问题,请参考以下文章

UICollectionView 在移动应用上创建新闻提要的代码

实时创建新闻提要

在 modx 中为移动新闻提要创建仅内容页面

使用 Facebook Graph Api 在 iphone 中解析新闻提要响应

RestKit:两个独立的提要,两种不同的对象类型。一个对象管理器?

Facebook API 获取新闻提要