RSS 订阅

2017-06-0915919 阅读24 评论

博客提供 RSS 订阅应该是标配,这样读者就可以通过一些聚合阅读工具订阅你的博客,时时查看是否有文章更新,而不必每次都跳转到博客上来查看。现在我们就来为博客添加 RSS 订阅功能。

RSS 简介

RSS(Really Simple Syndication)是一种描述和同步网站内容的格式,它采用 XML 作为内容传递的格式。简单来说就是网站可以把内容包装成符合 RSS 标准的 XML 格式文档。一旦网站内容符合一个统一的规范,那么人们就可以开发一种读取这种规范化的 XML 文档的工具来聚合各大网站的内容。例如一个读者可能关注了很多的博客网站,如果这些博客网站都支持 RSS 订阅的话,他就只需要一个聚合阅读器订阅这些博客,就可以在聚合器工具里看到全部博客的更新内容,而不必再分别访问各个博客去看有没有内容更新了。更多 RSS 的介绍,可参考 rss (简易信息聚合)

使用 Django Feed 类

根据以上对 RSS 的介绍,我们可以发现关键的地方就是根据网站的内容生成规范化的 XML 文档,幸运的是,Django 已经内置了一些生成这个文档的方法,下面就使用这些方法来创建 RSS 订阅文档。

首先我们在 blog 应用的根目录下(models.py 所在目录)新建一个 feeds.py 文件以存放和 RSS 功能相关的代码。让后在 feeds.py 中写入如下代码:

blog/feeds.py

from django.contrib.syndication.views import Feed

from .models import Post


class AllPostsRssFeed(Feed):
    # 显示在聚合阅读器上的标题
    title = "Django 博客教程演示项目"

    # 通过聚合阅读器跳转到网站的地址
    link = "/"

    # 显示在聚合阅读器上的描述信息
    description = "Django 博客教程演示项目测试文章"

    # 需要显示的内容条目
    def items(self):
        return Post.objects.all()

    # 聚合器中显示的内容条目的标题
    def item_title(self, item):
        return '[%s] %s' % (item.category, item.title)

    # 聚合器中显示的内容条目的描述
    def item_description(self, item):
        return item.body

代码应该不难理解,主要就是指定要生成的 XML 文档内容。各个属性和方法的含义已在代码中注释,你只需把相关的内容替换成符合你博客的描述即可。

添加 URL

接下来就是指定 URL 模式,让人们访问这个 URL 后就可以看到 Feed 生成的内容。通常 RSS 的 URL 配置直接写在项目的 urls.py 文件里,即打开 blogproject/urls.py 文件,添加如下代码:

blogproject/urls.py

from blog.feeds import AllPostsRssFeed

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'', include('blog.urls')),
    url(r'', include('comments.urls')),
    # 记得在顶部引入 AllPostsRssFeed
    url(r'^all/rss/$', AllPostsRssFeed(), name='rss'),
]

修改模板

简单修改一下模板,把 RSS 的 URL 添加到模板中:

<div class="rss">
  <a href="{% url 'rss' %}"><span class="ion-social-rss-outline"></span> RSS 订阅</a>
</div>

运行开发服务器,在侧边栏点击 RSS 订阅的链接,就跳转到 /all/rss/,你会看到这对乱码一样的东西,这就是生成的 RSS 标准文档,当然这个文档不是给你读的,而是给 RSS 聚合阅读器工具读的。

RSS 测试插件

可以在本地测试一下订阅效果,我使用的 Chrome 浏览器,安装了一个 RSS Feed Reader 的应用,如果你也使用的 Chrome 浏览器,可以从应用商店添加它,然后就可以在本地测试订阅效果了。如果是其它浏览器,自行查找相关 RSS 阅读插件即可。我本地测试效果如下:

rss订阅

可以看到订阅成功了,订阅界面显示的信息就是我们在 AllPostsRssFeed 类中指定的相关信息。大功告成,现在任何人都可以订阅我们的博客了!

总结

本章节的代码位于:Step23: rss feed

如果遇到问题,请通过下面的方式寻求帮助。

-- EOF --

24 评论
登录后回复
田田田田
2019-05-06 16:39:58

请问这一条路由url(r'^all/rss/$', AllPostsRssFeed(), name='rss')配置什么?

回复
suyufeilong
2018-06-14 14:37:27

[python] markdown测试# 一级标题 ## 二级标题 ### 三级标题 - 列表项1 - 列表项2 - 列表项3 > 这是一段引用 ```python @requires_authorization def somefunc(param1='', param2=0): '''A docstring''' if param1 > param2: # interesting print 'Greater' return (param2 - param1 + 1) or None class SomeClass: pass >>> message = '''interpreter ... prompt''' ```


在聚合阅读器看到的是这种格式的内容,怎么搞

回复
suyufeilong suyufeilong
2018-06-14 14:39:11

[python] markdown测试  是标题,后面的是内容,把markdown语法格式也显示出来了

回复
rookie250
2017-11-26 06:20:27

在开发环境可以,但是生产环境点击后还是在详情页,检查后浏览器h5元素后发现{% url 'rss' %} 被渲染成为空串,不知道什么原因。请教楼主

回复
追梦人物 rookie250
2017-11-27 12:23:15

能否提供相关的线索,仅有一个异常难以分析。

回复
rookie250
2017-11-26 06:20:07

在开发环境可以,但是生产环境点击后还是在详情页,检查后浏览器h5元素后发现{% url 'rss' %} 被渲染成k空,不知道什么原因。请教楼主

回复
iosyaowei
2017-09-28 23:48:17

'QuerySet' object has no attribute 'content_type'  我使用的时候python2.7 这是编码的问题吗 怎么解决呢

回复
iosyaowei iosyaowei
2017-09-29 00:34:14

找到原因了,自己写错了

回复
linuxying
2017-09-16 21:00:44

<div class="rss">

     <a href="{% url 'rss' %}"><span class="ion-social-rss-outline"></span> RSS 订阅</a>

</div>

博主你好,这个位置是不是要改为{% url 'blog:rss' %},我按照你这样写总是提示这个位置报错,未找到rss,但是改成加上blog的这个就可以了。

回复
Stallionshell linuxying
2017-11-22 13:45:58

如果你添加的rss是在blog应用下需要如此,但是博主的教程是直接在blogproject下添加的

回复
陌上花开迟迟
2017-07-02 17:52:59

请问一下feeds模块加载不成功是怎么回事?

回复
追梦人物 陌上花开迟迟
2017-07-03 12:08:43

错误信息?

回复
陌上花开迟迟 追梦人物
2017-07-03 13:52:13

找不到blog.feeds文件,我不实验这个功能,感觉这个功能对我来说用处不大。

回复
追梦人物 陌上花开迟迟
2017-07-03 16:43:22

嗯,那可以不用做的。

回复
李伟
2017-06-16 11:30:57

博主看了文章后,有个疑问:在urlconf配置时直接写的AllPostsRssFeed()类名(),而这个AllPostsRssFeed类定义在blog/feeds.py模块中,访问时系统就直接能找到这个类了么?urlConf配置时是在顶层urlConf配置的,也没指定是在blog应用中啊?求解?如果别的应用中也有同名的类AllPostsRssFeed,那么会不会冲突?

回复
追梦人物 李伟
2017-06-16 11:38:21

我从 from blog.feeds import AllPostsRssFeed 导入的。

回复
李伟 追梦人物
2017-06-16 13:27:54

不好意思,没看到。

回复
JustBreaking
2017-06-14 21:49:07

返回的title中有中文就报错了。请问博主是怎么解决的呀

回复
JustBreaking JustBreaking
2017-06-14 22:18:50

解决啦已经

回复
hldgaoshuo JustBreaking
2017-07-27 23:00:12

请问是怎么解决的呀?

回复
追梦人物 hldgaoshuo
2017-08-04 20:35:10

py2?查一查 py2 处理中文编码的解决方案吧。

回复
toSummerDawn
2017-06-09 16:06:30

    # 聚合器中显示的内容条目的描述
def item_description(self, item):
return item.body

是否可以截取一段body内容作为描述会更好。

回复
追梦人物 toSummerDawn
2017-06-09 16:14:58

各个聚合器应该会自动截取的,返回整个正文内容应该没有什么影响。而且聚合器应该是使用 item_description 的内容作为正文内容。

回复
toSummerDawn
2017-06-09 15:58:57

低调的为人民服务,是我们的榜样!

回复