用Python的Django框架来制作一个RSS阅读器

news2025/7/23 21:05:06

Django带来了一个高级的聚合生成框架,它使得创建RSS和Atom feeds变得非常容易。

什么是RSS? 什么是Atom?

RSS和Atom都是基于XML的格式,你可以用它来提供有关你站点内容的自动更新的feed。 了解更多关于RSS的可以访问 http://www.whatisrss.com/, 更多Atom的信息可以访问 http://www.atomenabled.org/.

想创建一个联合供稿的源(syndication feed),所需要做的只是写一个简短的python类。 你可以创建任意多的源(feed)。

高级feed生成框架是一个默认绑定到/feeds/的视图,Django使用URL的其它部分(在/feeds/之后的任何东西)来决定输出 哪个feed Django uses the remainder of the URL (everything after /feeds/ ) to determine which feed to return.

要创建一个 sitemap,你只需要写一个 Sitemap 类然后配置你的URLconf指向它。
初始化

为了在您的Django站点中激活syndication feeds, 添加如下的 URLconf:

1

2

3

(r'^feeds/(?P<url>.*)/$', 'django.contrib.syndication.views.feed',

  {'feed_dict': feeds}

),

这一行告诉Django使用RSS框架处理所有的以 "feeds/" 开头的URL. ( 你可以修改 "feeds/" 前缀以满足您自己的要求. )

URLConf里有一行参数: {'feed_dict': feeds},这个参数可以把对应URL需要发布的feed内容传递给 syndication framework

特别的,feed_dict应该是一个映射feed的slug(简短URL标签)到它的Feed类的字典 你可以在URL配置本身里定义feed_dict,这里是一个完整的例子 You can define the feed_dict in the URLconf itself. Here's a full example URLconf:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

from django.conf.urls.defaults import *

from mysite.feeds import LatestEntries, LatestEntriesByCategory

feeds = {

  'latest': LatestEntries,

  'categories': LatestEntriesByCategory,

}

urlpatterns = patterns('',

  # ...

  (r'^feeds/(?P<url>.*)/$', 'django.contrib.syndication.views.feed',

    {'feed_dict': feeds}),

  # ...

)

前面的例子注册了两个feed:

  1.     LatestEntries``表示的内容将对应到``feeds/latest/ .
  2.     LatestEntriesByCategory``的内容将对应到 ``feeds/categories/ .

以上的设定完成之后,接下来需要自己定义 Feed 类

一个 Feed 类是一个简单的python类,用来表示一个syndication feed. 一个feed可能是简单的 (例如一个站点新闻feed,或者最基本的,显示一个blog的最新条目),也可能更加复杂(例如一个显示blog某一类别下所有条目的feed。 这里类别 category 是个变量).

Feed类必须继承django.contrib.syndication.feeds.Feed,它们可以在你的代码树的任何位置
一个简单的Feed

1

2

3

4

5

6

7

8

9

10

11

12

This simple example describes a feed of the latest five blog entries for a given blog:

from django.contrib.syndication.feeds import Feed

from mysite.blog.models import Entry

class LatestEntries(Feed):

  title = "My Blog"

  link = "/archive/"

  description = "The latest news about stuff."

  def items(self):

    return Entry.objects.order_by('-pub_date')[:5]

要注意的重要的事情如下所示:

  •     子类 django.contrib.syndication.feeds.Feed .
  •     title , link , 和 description 对应一个标准 RSS 里的 <title> , <link> , 和 <description> 标签.
  •     items() 是一个方法,返回一个用以包含在包含在feed的 <item> 元素里的 list 虽然例子里用Djangos database API返回的 NewsItem 对象, items() 不一定必须返回 model的实例 Although this example returns Entry objects using Django's database API, items() doesn't have to return model instances.

还有一个步骤,在一个RSS feed里,每个(item)有一个(title),(link)和(description),我们需要告诉框架 把数据放到这些元素中 In an RSS feed, each <item> has a <title> , <link> , and <description> . We need to tell the framework what data to put into those elements.

    如果要指定 <title> 和 <description> ,可以建立一个Django模板(见Chapter 4)名字叫 feeds/latest_title.html 和 feeds/latest_description.html ,后者是URLConf里为对应feed指定的 slug 。注意 .html 后缀是必须的。 Note that the .html extension is required.

    RSS系统模板渲染每一个条目,需要给传递2个参数给模板上下文变量:

  1.         obj : 当前对象 ( 返回到 items() 任意对象之一 )。
  2.         site : 一个表示当前站点的 django.models.core.sites.Site 对象。 这对于 {{ site.domain }} 或者 {{ site.name }} 很有用。

    如果你在创建模板的时候,没有指明标题或者描述信息,框架会默认使用 "{{ obj }}" ,对象的字符串表示。 (For model objects, this will be the __unicode__() method.

    你也可以通过修改 Feed 类中的两个属性 title_template 和 description_template 来改变这两个模板的名字。

    你有两种方法来指定 <link> 的内容。 Django 首先执行 items() 中每一项的 get_absolute_url() 方法。 如果该方法不存在,就会尝试执行 Feed 类中的 item_link() 方法,并将自身作为 item 参数传递进去。

    get_absolute_url() 和 item_link() 都应该以Python字符串形式返回URL。

    对于前面提到的 LatestEntries 例子,我们可以实现一个简单的feed模板。 latest_title.html 包括:

{{ obj.title }}

    并且 latest_description.html 包含:

{{ obj.description }}

    这真是 太 简单了!

一个更复杂的Feed

框架通过参数支持更加复杂的feeds。

For example, say your blog offers an RSS feed for every distinct tag you've used to categorize your entries. 如果为每一个单独的区域建立一个 Feed 类就显得很不明智。

取而代之的方法是,使用聚合框架来产生一个通用的源,使其可以根据feeds URL返回相应的信息。

Your tag-specific feeds could use URLs like this:

    http://example.com/feeds/tags/python/ : Returns recent entries tagged with python

    http://example.com/feeds/tags/cats/ : Returns recent entries tagged with cats

固定的那一部分是 "beats" (区域)。

举个例子会澄清一切。 下面是每个地区特定的feeds:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

from django.core.exceptions import ObjectDoesNotExist

from mysite.blog.models import Entry, Tag

class TagFeed(Feed):

  def get_object(self, bits):

    # In case of "/feeds/tags/cats/dogs/mice/", or other such

    # clutter, check that bits has only one member.

    if len(bits) != 1:

      raise ObjectDoesNotExist

    return Tag.objects.get(tag=bits[0])

  def title(self, obj):

    return "My Blog: Entries tagged with %s" % obj.tag

  def link(self, obj):

    return obj.get_absolute_url()

  def description(self, obj):

    return "Entries tagged with %s" % obj.tag

  def items(self, obj):

    entries = Entry.objects.filter(tags__id__exact=obj.id)

    return entries.order_by('-pub_date')[:30]

以下是RSS框架的基本算法,我们假设通过URL /rss/beats/0613/ 来访问这个类:

    框架获得了URL /rss/beats/0613/ 并且注意到URL中的slug部分后面含有更多的信息。 它将斜杠("/" )作为分隔符,把剩余的字符串分割开作为参数,调用 Feed 类的 get_object() 方法。

    在这个例子中,添加的信息是 ['0613'] 。对于 /rss/beats/0613/foo/bar/ 的一个URL请求, 这些信息就是 ['0613', 'foo', 'bar'] 。

    get_object() 就根据给定的 bits 值来返回区域信息。

    In this case, it uses the Django database API to retrieve the Tag . Note that get_object() should raise django.core.exceptions.ObjectDoesNotExist if given invalid parameters. 在 Beat.objects.get() 调用中也没有出现 try /except 代码块。 函数在出错时抛出 Beat.DoesNotExist 异常,而 Beat.DoesNotExist 是 ObjectDoesNotExist 异常的一个子类型。

    为产生 <title> , <link> , 和 <description> 的feeds, Django使用 title() , link() , 和 description() 方法。 在上面的例子中,它们都是简单的字符串类型的类属性,而这个例子表明,它们既可以是字符串, 也可以是 方法。 对于每一个 title , link 和 description 的组合,Django使用以下的算法:

        试图调用一个函数,并且以 get_object() 返回的对象作为参数传递给 obj 参数。

        如果没有成功,则不带参数调用一个方法。

        还不成功,则使用类属性。

    最后,值得注意的是,这个例子中的 items() 使用 obj 参数。 对于 items 的算法就如同上面第一步所描述的那样,首先尝试 items(obj) , 然后是 items() ,最后是 items 类属性(必须是一个列表)。

Feed 类所有方法和属性的完整文档,请参考官方的Django文档 (http://www.djangoproject.com/documentation/0.96/syndication_feeds/) 。
指定Feed的类型

默认情况下, 聚合框架生成RSS 2.0. 要改变这样的情况, 在 Feed 类中添加一个 feed_type 属性. To change that, add a feed_type attribute to your Feed class:

1

2

3

4

from django.utils.feedgenerator import Atom1Feed

class MyFeed(Feed):

  feed_type = Atom1Feed

注意你把 feed_type 赋值成一个类对象,而不是类实例。 目前合法的Feed类型如表所示。

闭包

为了指定闭包(例如,与feed项比方说MP3 feeds相关联的媒体资源信息),使用 item_enclosure_url , item_enclosure_length , 以及 item_enclosure_mime_type ,比如

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

from myproject.models import Song

class MyFeedWithEnclosures(Feed):

  title = "Example feed with enclosures"

  link = "/feeds/example-with-enclosures/"

  def items(self):

    return Song.objects.all()[:30]

  def item_enclosure_url(self, item):

    return item.song_url

  def item_enclosure_length(self, item):

    return item.song_length

  item_enclosure_mime_type = "audio/mpeg"

当然,你首先要创建一个包含有 song_url 和 song_length (比如按照字节计算的长度)域的 Song 对象。
语言

聚合框架自动创建的Feed包含适当的 <language> 标签(RSS 2.0) 或 xml:lang 属性(Atom). 他直接来自于您的 LANGUAGE_CODE 设置. This comes directly from your LANGUAGE_CODE setting.
URLs

link 方法/属性可以以绝对URL的形式(例如, "/blog/" )或者指定协议和域名的URL的形式返回(例如 "http://www.example.com/blog/" )。如果 link 没有返回域名,聚合框架会根据 SITE_ID 设置,自动的插入当前站点的域信息。 (See Chapter 16 for more on SITE_ID and the sites framework.)

Atom feeds需要 <link rel="self"> 指明feeds现在的位置。 The syndication framework populates this automatically.
同时发布Atom and RSS

一些开发人员想 同时 支持Atom和RSS。 这在Django中很容易实现: 只需创建一个你的 feed 类的子类,然后修改 feed_type ,并且更新URLconf内容。 下面是一个完整的例子: Here's a full example:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

from django.contrib.syndication.feeds import Feed

from django.utils.feedgenerator import Atom1Feed

from mysite.blog.models import Entry

class RssLatestEntries(Feed):

  title = "My Blog"

  link = "/archive/"

  description = "The latest news about stuff."

  def items(self):

    return Entry.objects.order_by('-pub_date')[:5]

class AtomLatestEntries(RssLatestEntries):

  feed_type = Atom1Feed

这是与之相对应那个的URLconf:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

from django.conf.urls.defaults import *

from myproject.feeds import RssLatestEntries, AtomLatestEntries

feeds = {

  'rss': RssLatestEntries,

  'atom': AtomLatestEntries,

}

urlpatterns = patterns('',

  # ...

  (r'^feeds/(?P<url>.*)/$', 'django.contrib.syndication.views.feed',

    {'feed_dict': feeds}),

  # ...

)

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/16879.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[附源码]SSM计算机毕业设计足球队管理系统JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

[附源码]java毕业设计企业记账系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

QT 发布文章遇到问题解决方案

提供了两种可以发布 Qt 程序的方案&#xff0c;建议使用第二种直接生成对应的文件&#xff0c;直接打包就可以 1. 手动复制需要的文件到运行目录下 我们写完 QT 程序当然是要发布或者发给其他需要用到的人&#xff0c;由于找不到Qt6Core.dll,无法继续执行代码,打开 realease …

Python基础语法

一、字面量&#xff1a;在代码中&#xff0c;被写下来的固定的值 二、注释 /增加代码的可读性 单行注释 #空格注释文字内容 &#xff08;加空格只是规范&#xff09;#右边 多行注释 一对三个双引号 """注释内容""" 三、变量 -->程序运行时…

Linux基础内容(12)—— 程序地址空间

目录 1.误区和它的由来 2.虚拟地址的证明 3.虚拟地址的实现 1.虚拟空间的解释 2.操作系统管理和规划虚拟空间 3.虚拟地址与物理地址的联系 4.多进程的虚拟地址解释 5.磁盘中可执行文件的地址 6.进程地址空间出现的原因 接上面内容 Linux基础内容&#xff08;11&#…

在排序数组中查找元素的第一个和最后一个位置 - 力扣中等

在排序数组中查找元素的第一个和最后一个位置 题目链接 给你一个按照非递减顺序排列的整数数组 nums&#xff0c;和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。 如果数组中不存在目标值 target&#xff0c;返回 [-1, -1]。 你必须设计并实现时间…

2022 年 10 月 NFT 报告

Sept. 13, 2022, Daniel Data Source: October 2022 NFT Report (ENG) 10 月对于区块链来说是一个相对沉闷的月份&#xff0c;没有巨大的市场波动、项目启动或融资轮次。 由于宏观环境依然严峻&#xff0c;NFT 市场自夏末以来继续停滞不前。 从上个月的报告开始&#xff0c;F…

精准配置无线接入点发射功率

目录 1、为什么需要调节无线接入点的发射功率 2、无线接入点发送功率配置原则 2.1 802.11管理帧发射功率对接入行为影响 2.2 802.11数据帧发射功率对接入质量的影响 2.3 802.11管理帧、数据帧发射功率协调原则 1、数据帧发射功率务必大于等于管理帧发射功率 2、高频射频…

DOX-Poloxamer/DBCO-PEG-DOX 阿霉素修饰泊洛沙姆/二苯基环辛-聚乙二醇-阿霉素的探究

小编这里分享了DOX-Poloxamer/DBCO-PEG-DOX 阿霉素修饰泊洛沙姆/二苯基环辛-聚乙二醇-阿霉素的探究&#xff0c;和小编一起来看&#xff01; DBCO&#xff08;二苯并环辛炔&#xff09;是一种环炔烃&#xff0c;可以通过在水溶液中通过应变促进的1,3-偶极环加成反应与叠氮化物反…

【毕业设计】机器视觉答题卡识别系统 - python 深度学习

文章目录1 简介2 什么是机器视觉3 实现步骤4 最后1 简介 &#x1f525; Hi&#xff0c;大家好&#xff0c;这里是丹成学长的毕设系列文章&#xff01; &#x1f525; 对毕设有任何疑问都可以问学长哦! 这两年开始&#xff0c;各个学校对毕设的要求越来越高&#xff0c;难度也…

Cy7-NH2/amine氨基修饰荧光染料

伯胺基(primary amine)是生物标记反应中常用的基团。蛋白表面赖氨酸侧链(residue)官能团就是伯氨基,伯胺基可以和NHS活化酯(N-羟基琥珀酰亚胺酯,N-hydroxysuccinimide ester,succinimidyl ester),异氰酸酯(-NCS,isothiocyanate)或其它活化基团反应生成稳定链接,从而把Cy7分子连…

标志寄存器

标志寄存器 文章目录标志寄存器1.标志寄存器概念1.1 零标志位(ZF)1.2 奇偶标志位(PF)1.3 符号标志符(SF)1.4 进位标志符(CF)1.5溢出标志符(OF)2.adc指令和sbb指令3.cmp指令4.检测比较结果的条件转移指令5.DF标志和串传送指令6.pushf和popf1.标志寄存器概念 CPU内部的寄存器中&a…

UG NX 12装配——组件位置:装配约束

利用装配约束在装配中定位组件。 选择【装配】【组件】【装配约束】命令&#xff0c;或单击【装配】工具条上的【装配约束】按钮出现【装配约束】对话框。 &#xff08;1&#xff09;接触对齐 接触对齐约束可约束两个组件&#xff0c;使其彼此接触或对齐。这是最常用的约束。…

m无线通信信道matlab仿真,包括自由空间损耗模型,Okumura-Hata模型,COST231 Hata模型,SUI信道模型

目录 1.算法概述 2.仿真效果预览 3.MATLAB部分代码预览 4.完整MATLAB程序 1.算法概述 无线信道是移动通信的传输媒体&#xff0c;所有的信息都在这个信道中传输。信道性能的好坏直接决定着人们通信的质量&#xff0c;因此要想在有限的频谱资源上尽可能地高质量、大容量传输…

2022关键之年,国产奶粉「争霸之秋」

奶粉又到关键年。 在中国奶粉的发展历程中&#xff0c;有两个关键性的时间节点&#xff1a;2008年&#xff0c;三鹿事件打乱了国产奶粉的发展节奏&#xff0c;洋奶粉开始大行其道&#xff1b;2016年&#xff0c;婴配粉注册制实行&#xff0c;打着“更适合中国宝宝体质”旗号的…

数据库系统工程师难考吗?

数据库系统工程师属于软考中级科目&#xff0c;只要你多看书多做练习&#xff0c;熟悉考试题型&#xff0c;用对学习方法&#xff0c;并不难考的。但是你专业不对口&#xff0c;应该在备考上多下功夫&#xff0c;建议把考试大纲里的内容复习一遍&#xff0c;掌握好考纲里的知识…

使用android 提取小米手机日志

如何使用android sdk获取小米日志 下载android sdk 登录网址https://www.androiddevtools.cn/ 往下滑找到SDK tools,下载zip包并解压到电脑随便一个位置 解压缩位置打开SDK Manager.exe&#xff0c;安装相关工具&#xff08;具体可以网络搜索&#xff09; 打开电脑cmd 使用a…

世界杯听腾格尔《遥远的地方》,可以多帮助你爱的球队多进几个球

世界杯又到来啦&#xff0c;球迷朋友笑哈哈&#xff0c;听着音乐看球赛&#xff0c;球迷朋友乐开怀。——世界杯&#xff0c;中国球迷欢迎你&#xff01;随着2022年11月20号的临近&#xff0c;卡特尔世界杯即将打响&#xff0c;每一位中国球迷都为之热血沸腾。 虽然说中国的足球…

ly-tab插件动态更改高度进行多端适配

在开发移动端用ly-tab时遇到的一个小问题&#xff0c;众所周知当我们使用rem配合flexible.js时元素的高度会根据不同的设配进行自动适配&#xff0c;但是ly-tab插件的高度默认使用px为单位&#xff0c;就会导致在不同的设备中出现我们不可控的因素 比如当我们想将其定位到顶部…

[附源码]java毕业设计农产品溯源管理

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…