Python基础教程-用Python的Django框架来制作一个RSS阅读器详细介绍

用Python的Django框架来制作一个RSS阅读器是如何来实现的呢?本python基础教程将会通过具体的实例来演示用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:

1
2
3
(r'^feeds/(&#63;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/(&#63;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 里的 , <link> , 和 <description> 标签.</li> <li> 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.</li> </ul> <p>还有一个步骤,在一个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.</p> <p> 如果要指定 <title> 和 <description> ,可以建立一个Django模板(见Chapter 4)名字叫 feeds/latest_title.html 和 feeds/latest_description.html ,后者是URLConf里为对应feed指定的 slug 。注意 .html 后缀是必须的。 Note that the .html extension is required.</p> <p> RSS系统模板渲染每一个条目,需要给传递2个参数给模板上下文变量:</p> <ol> <li> obj : 当前对象 ( 返回到 items() 任意对象之一 )。</li> <li> site : 一个表示当前站点的 django.models.core.sites.Site 对象。 这对于 {{ site.domain }} 或者 {{ site.name }} 很有用。</li> </ol> <p> 如果你在创建模板的时候,没有指明标题或者描述信息,框架会默认使用 “{{ obj }}” ,对象的字符串表示。 (For model objects, this will be the __unicode__() method.</p> <p> 你也可以通过修改 Feed 类中的两个属性 title_template 和 description_template 来改变这两个模板的名字。</p> <p> 你有两种方法来指定 <link> 的内容。 Django 首先执行 items() 中每一项的 get_absolute_url() 方法。 如果该方法不存在,就会尝试执行 Feed 类中的 item_link() 方法,并将自身作为 item 参数传递进去。</p> <p> get_absolute_url() 和 item_link() 都应该以Python字符串形式返回URL。</p> <p> 对于前面提到的 LatestEntries 例子,我们可以实现一个简单的feed模板。 latest_title.html 包括:</p> <p>{{ obj.title }}</p> <p> 并且 latest_description.html 包含:</p> <p>{{ obj.description }}</p> <p> 这真是 太 简单了!</p> <p><strong>一个更复杂的Feed</strong></p> <p>框架通过参数支持更加复杂的feeds。</p> <p>For example, say your blog offers an RSS feed for every distinct tag you’ve used to categorize your entries. 如果为每一个单独的区域建立一个 Feed 类就显得很不明智。</p> <p>取而代之的方法是,使用聚合框架来产生一个通用的源,使其可以根据feeds URL返回相应的信息。</p> <p>Your tag-specific feeds could use URLs like this:</p> <p> http://example.com/feeds/tags/python/ : Returns recent entries tagged with python</p> <p> http://example.com/feeds/tags/cats/ : Returns recent entries tagged with cats</p> <p>固定的那一部分是 “beats” (区域)。</p> <p>举个例子会澄清一切。 下面是每个地区特定的feeds:</p> <div class="codecolorer-container python geshi" style="overflow:auto;white-space:nowrap;width:97%;"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br /></div></td><td><div class="python codecolorer" style="white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">core</span>.<span style="color: #dc143c;">exceptions</span> <span style="color: #ff7700;font-weight:bold;">import</span> ObjectDoesNotExist<br /> <span style="color: #ff7700;font-weight:bold;">from</span> mysite.<span style="color: black;">blog</span>.<span style="color: black;">models</span> <span style="color: #ff7700;font-weight:bold;">import</span> Entry<span style="color: #66cc66;">,</span> Tag<br /> <br /> <span style="color: #ff7700;font-weight:bold;">class</span> TagFeed<span style="color: black;">(</span>Feed<span style="color: black;">)</span>:<br />   <span style="color: #ff7700;font-weight:bold;">def</span> get_object<span style="color: black;">(</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> bits<span style="color: black;">)</span>:<br />     <span style="color: #808080; font-style: italic;"># In case of "/feeds/tags/cats/dogs/mice/", or other such</span><br />     <span style="color: #808080; font-style: italic;"># clutter, check that bits has only one member.</span><br />     <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">(</span>bits<span style="color: black;">)</span> <span style="color: #66cc66;">!=</span> <span style="color: #ff4500;">1</span>:<br />       <span style="color: #ff7700;font-weight:bold;">raise</span> ObjectDoesNotExist<br />     <span style="color: #ff7700;font-weight:bold;">return</span> Tag.<span style="color: black;">objects</span>.<span style="color: black;">get</span><span style="color: black;">(</span>tag<span style="color: #66cc66;">=</span>bits<span style="color: black;">[</span><span style="color: #ff4500;">0</span><span style="color: black;">]</span><span style="color: black;">)</span><br /> <br />   <span style="color: #ff7700;font-weight:bold;">def</span> title<span style="color: black;">(</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> obj<span style="color: black;">)</span>:<br />     <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">"My Blog: Entries tagged with %s"</span> % obj.<span style="color: black;">tag</span><br /> <br />   <span style="color: #ff7700;font-weight:bold;">def</span> link<span style="color: black;">(</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> obj<span style="color: black;">)</span>:<br />     <span style="color: #ff7700;font-weight:bold;">return</span> obj.<span style="color: black;">get_absolute_url</span><span style="color: black;">(</span><span style="color: black;">)</span><br /> <br />   <span style="color: #ff7700;font-weight:bold;">def</span> description<span style="color: black;">(</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> obj<span style="color: black;">)</span>:<br />     <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">"Entries tagged with %s"</span> % obj.<span style="color: black;">tag</span><br /> <br />   <span style="color: #ff7700;font-weight:bold;">def</span> items<span style="color: black;">(</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> obj<span style="color: black;">)</span>:<br />     entries <span style="color: #66cc66;">=</span> Entry.<span style="color: black;">objects</span>.<span style="color: #008000;">filter</span><span style="color: black;">(</span>tags__id__exact<span style="color: #66cc66;">=</span>obj.<span style="color: #008000;">id</span><span style="color: black;">)</span><br />     <span style="color: #ff7700;font-weight:bold;">return</span> entries.<span style="color: black;">order_by</span><span style="color: black;">(</span><span style="color: #483d8b;">'-pub_date'</span><span style="color: black;">)</span><span style="color: black;">[</span>:<span style="color: #ff4500;">30</span><span style="color: black;">]</span></div></td></tr></tbody></table></div> <p>以下是RSS框架的基本算法,我们假设通过URL /rss/beats/0613/ 来访问这个类:</p> <p> 框架获得了URL /rss/beats/0613/ 并且注意到URL中的slug部分后面含有更多的信息。 它将斜杠(“/” )作为分隔符,把剩余的字符串分割开作为参数,调用 Feed 类的 get_object() 方法。</p> <p> 在这个例子中,添加的信息是 [‘0613’] 。对于 /rss/beats/0613/foo/bar/ 的一个URL请求, 这些信息就是 [‘0613’, ‘foo’, ‘bar’] 。</p> <p> get_object() 就根据给定的 bits 值来返回区域信息。</p> <p> 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 代码块。 函数在出错时抛出 Bea</p> <p>对于用Python的Django框架来制作一个RSS阅读器就是这样,欢迎大家参考python基础教程系类的其它介绍。。。。</p> </div> <footer class="entryMeta"> <div class="postinfo post-nav clearfix"><h4 class="clearfix">Other posts</h4><span class="previous-post-link"><a href="http://www.osetc.com/archives/18743.html" rel="prev">Python基础教程-在Django中使用Sitemap的方法讲解详细介绍</a> «</span><span class="next-post-link">» <a href="http://www.osetc.com/archives/18747.html" rel="next">Python基础教程-利用Python的Django框架生成PDF文件的教程详细介绍</a></span></div> </footer> </article> <div class="last-posts-list postinfo clearfix"> </div> </div> <div class="asideMenuButton"> <header class="asideMenuButtonTitle">Sidebar</header> <div class="asideMenuButtonContent"> <hr> <hr> <hr> </div> </div> <aside> <div class="aside-container container-full"> <div class="customSidebar"> <div class="row sidebarContent"> <div class="col-md-12"> </div> </div> </div> <div class="dynamicSidebar"> <div class="row sidebarContent"> <div class="col-md-12"> <div class="widget"><form role="search" method="get" class="search-form" action="http://www.osetc.com/"><label><input type="search" class="search-field" placeholder="搜索" value="" name="s" title="Search" /></label><input type="submit" class="search-submit" value="搜索" /></form></div><div class="widget"> <div class="textwidget"><div align="center"> <script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> <!-- osetc_siderbar_auto1 --> <ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-5710361530012908" data-ad-slot="6553681516" data-ad-format="auto"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> </div></div> </div><div class="widget"> <div class="textwidget"><div align="center"> <script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> <!-- osetc300x600 --> <ins class="adsbygoogle" style="display:inline-block;width:300px;height:600px" data-ad-client="ca-pub-5710361530012908" data-ad-slot="4375985988"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> </div></div> </div><div class="widget"> <div class="textwidget"><div align="center"> <script type="text/javascript"> /*osetc_right_siderbar1 300x250创建于 8/1/2017*/ var cpro_id = "u3049473"; </script> <script type="text/javascript" src="http://cpro.baidustatic.com/cpro/ui/c.js"></script> </div></div> </div> </div> </div> </div> </div> </aside> </div><footer class="container-fluid"><div class="content clearfix"><div class="col-md-12 copyright"><p><strong>©  Copyright  2017 <a href="http://www.osetc.com">OSETC 技术网</a></strong>  All Rights Reserved.  |   <a class="footer-rss-link" href="http://www.osetc.com/feed" title="RSS Feed">RSS</a></p></div></div></footer> <div id="wpfront-scroll-top-container"><img src="http://www.osetc.com/wp-content/plugins/wpfront-scroll-top/images/icons/36.png" alt="" /></div> <script type="text/javascript">function wpfront_scroll_top_init() {if(typeof wpfront_scroll_top == "function" && typeof jQuery !== "undefined") {wpfront_scroll_top({"scroll_offset":100,"button_width":0,"button_height":0,"button_opacity":0.8,"button_fade_duration":200,"scroll_duration":400,"location":1,"marginX":20,"marginY":20,"hide_iframe":false,"auto_hide":false,"auto_hide_after":2});} else {setTimeout(wpfront_scroll_top_init, 100);}}wpfront_scroll_top_init();</script><script type='text/javascript'> /* <![CDATA[ */ var viewsCacheL10n = {"admin_ajax_url":"http:\/\/www.osetc.com\/wp-admin\/admin-ajax.php","post_id":"18746"}; /* ]]> */ </script> <script type='text/javascript' src='http://www.osetc.com/wp-content/plugins/wp-postviews/postviews-cache.js?ver=1.68'></script> <script type='text/javascript' src='http://www.osetc.com/wp-includes/js/comment-reply.min.js?ver=4.7.4'></script> <script type='text/javascript' src='http://www.osetc.com/wp-includes/js/wp-embed.min.js?ver=4.7.4'></script> </body></html>