这篇文章将为大家详细讲解有关使用Django怎么实现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 = "HelloDjango-blog-tutorial" # 通过聚合阅读器跳转到网站的地址 link = "/" # 显示在聚合阅读器上的描述信息 description = "HelloDjango-blog-tutorial 全部文章" # 需要显示的内容条目 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_html
代码应该不难理解,主要就是指定要生成的 XML 文档内容。各个属性和方法的含义已在代码中注释,你只需把相关的内容替换成符合你博客的描述即可。
需要注意一点的是这个方法:
# 聚合器中显示的内容条目的描述 def item_description(self, item): return item.body_html
item 是文章 (Post 模型的实例),聚合内容的描述我们返回了 body_html 属性的值。模型中原本使用 body 属性存储博客文章的内容,但是这些内容是以 Markdown 格式的,并非所有的聚合内容阅读器都支持 Markdown 格式的解析,因此我们返回的是已经解析后的 HTML 格式内容。
但 Post 模型原来并没有 body_html 这个属性的,那它是哪里来的呢?
回顾一下 PostDetailView 这个视图,我们在获取博客文章 post 的详细内容的视图中,使用 markdown 这个 Python 库在解析 post.body 这个属性的值。这个解析的过程其实在很多地方都可能用到,不应该写死在 PostDetailView 这个视图里,所以我们先将 PostDetailView 视图的 get_object 方法解析 Markdown 内容的过程封装为一个函数,暂且将其放在 blog/models.py 中。
blog/models.py
def generate_rich_content(value): md = markdown.Markdown( extensions=[ "markdown.extensions.extra", "markdown.extensions.codehilite", # 记得在顶部引入 TocExtension 和 slugify TocExtension(slugify=slugify), ] ) content = md.convert(value) m = re.search(r'<div class="toc">\s*<ul>(.*)</ul>\s*</div>', md.toc, re.S) toc = m.group(1) if m is not None else "" return {"content": content, "toc": toc}
解析过程和原来一样,只是将解析得到的 HTML 内容(content)和目录(toc)放在一个字典里返回。
然后,我们来给 Post 模型定义几个属性,以便方便地获取解析后的内容和目录:
blog/models.py
from django.utils.functional import cached_property class Post(models.Model): # 省略其它代码 @property def toc(self): return self.rich_content.get("toc", "") @property def body_html(self): return self.rich_content.get("content", "") @cached_property def rich_content(self): return generate_rich_content(self.body)
首先看到 rich_content 这个方法,它返回的是 generate_rich_content 函数调用后的结果,即将 body 属性的值经 Markdown 解析后的内容。但要注意的是我们使用了 django 提供的 cached_property 装饰器,这个装饰器和 Python 内置的 property 装饰器功能一样,可以将方法转为属性,这样就能够以属性访问的方式获取方法返回的值,不过 cached_property 进一步提供缓存功能,它将被装饰方法调用返回的值缓存起来,下次访问时将直接读取缓存内容,而不需重复执行方法获取返回结果。例如对博客文章内容的 Markdown 解析是比较耗时的,而解析的结果可能被多次访问,因此将其缓存起来能起到优化作用。
为了更方便地获取文章的 HTML 格式的内容和目录,我们进一步将 generate_rich_content 返回的值放到 toc 和 body_html 两个属性中,这里两个属性都从 rich_content 中取值,cached_property 的作用就发挥出来了。
添加 URL
接下来就是指定 URL 模式,让人们访问这个 URL 后就可以看到 Feed 生成的内容。通常 RSS 的 URL 配置直接写在项目的 urls.py 文件里,即打开 blogproject/urls.py 文件,添加如下代码:
blogproject/urls.py
from blog.feeds import AllPostsRssFeed urlpatterns = [ path('admin/', admin.site.urls), path('', include('blog.urls')), path('', include('comments.urls')), # 记得在顶部引入 AllPostsRssFeed path('all/rss/', AllPostsRssFeed(), name='rss'), ]
修改模板
简单修改一下 templates/base.html 模板,把 RSS 的 URL 添加到模板中:
<div class="rss"> <a href="{% url 'rss' %}" rel="external nofollow" ><span class="ion-social-rss-outline"></span> RSS 订阅</a> </div>
此外,由于将 Markdown 解析的内容放在了 body_html 属性,将之前博客文章详情模板里获取文章内容的代码也做相应调整:
templates/blog/detail.html
<div class="entry-content clearfix"> {{ post.body_html|safe }} </div>
关于使用Django怎么实现RSS功能就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。