微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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:

(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:

from django.conf.urls.defaults import *
from mysite.Feeds import LatestEntries,LatestEntriesByCategory

Feeds = {
  'latest': LatestEntries,'categories': LatestEntriesByCategory,}

urlpatterns = patterns('',# ...
  (r'^Feeds/(?P<url>.*)/$',{'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

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>,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:

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:

from django.utils.Feedgenerator import Atom1Feed

class MyFeed(Feed):
  Feed_type = Atom1Feed

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

2015722150842180.jpg (705×179)

闭包

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

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:

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

from django.conf.urls.defaults import *
from myproject.Feeds import RSSLatestEntries,AtomLatestEntries

Feeds = {
  'RSS': RSSLatestEntries,'atom': AtomLatestEntries,# ...
)


版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


我最近重新拾起了计算机视觉,借助Python的opencv还有face_recognition库写了个简单的图像识别demo,额外定制了一些内容,原本想打包成exe然后发给朋友,不过在这当中遇到了许多小问题,都解决了,记录一下踩过的坑。 1、Pyinstaller打包过程当中出现warning,跟d
说到Pooling,相信学习过CNN的朋友们都不会感到陌生。Pooling在中文当中的意思是“池化”,在神经网络当中非常常见,通常用的比较多的一种是Max Pooling,具体操作如下图: 结合图像理解,相信你也会大概明白其中的本意。不过Pooling并不是只可以选取2x2的窗口大小,即便是3x3,
记得大一学Python的时候,有一个题目是判断一个数是否是复数。当时觉得比较复杂不好写,就琢磨了一个偷懒的好办法,用异常处理的手段便可以大大程度帮助你简短代码(偷懒)。以下是判断整数和复数的两段小代码: 相信看到这里,你也有所顿悟,能拓展出更多有意思的方法~
文章目录 3 直方图Histogramplot1. 基本直方图的绘制 Basic histogram2. 数据分布与密度信息显示 Control rug and density on seaborn histogram3. 带箱形图的直方图 Histogram with a boxplot on t
文章目录 5 小提琴图Violinplot1. 基础小提琴图绘制 Basic violinplot2. 小提琴图样式自定义 Custom seaborn violinplot3. 小提琴图颜色自定义 Control color of seaborn violinplot4. 分组小提琴图 Group
文章目录 4 核密度图Densityplot1. 基础核密度图绘制 Basic density plot2. 核密度图的区间控制 Control bandwidth of density plot3. 多个变量的核密度图绘制 Density plot of several variables4. 边
首先 import tensorflow as tf tf.argmax(tenso,n)函数会返回tensor中参数指定的维度中的最大值的索引或者向量。当tensor为矩阵返回向量,tensor为向量返回索引号。其中n表示具体参数的维度。 以实际例子为说明: import tensorflow a
seaborn学习笔记章节 seaborn是一个基于matplotlib的Python数据可视化库。seaborn是matplotlib的高级封装,可以绘制有吸引力且信息丰富的统计图形。相对于matplotlib,seaborn语法更简洁,两者关系类似于numpy和pandas之间的关系,seabo
Python ConfigParser教程显示了如何使用ConfigParser在Python中使用配置文件。 文章目录 1 介绍1.1 Python ConfigParser读取文件1.2 Python ConfigParser中的节1.3 Python ConfigParser从字符串中读取数据
1. 处理Excel 电子表格笔记(第12章)(代码下载) 本文主要介绍openpyxl 的2.5.12版处理excel电子表格,原书是2.1.4 版,OpenPyXL 团队会经常发布新版本。不过不用担心,新版本应该在相当长的时间内向后兼容。如果你有新版本,想看看它提供了什么新功能,可以查看Open