Sophie

Sophie

distrib > Mandriva > current > i586 > media > main-updates > by-pkgid > 57efe471f3561e70a829edf1b0e9f507 > files > 2309

python-django-1.1.4-0.1mdv2010.2.noarch.rpm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <title>The syndication feed framework &mdash; Django v1.1 documentation</title>
    <link rel="stylesheet" href="../../_static/default.css" type="text/css" />
    <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    '../../',
        VERSION:     '1.1',
        COLLAPSE_MODINDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true
      };
    </script>
    <script type="text/javascript" src="../../_static/jquery.js"></script>
    <script type="text/javascript" src="../../_static/doctools.js"></script>
    <link rel="top" title="Django v1.1 documentation" href="../../index.html" />
    <link rel="up" title="contrib packages" href="index.html" />
    <link rel="next" title="django.contrib.webdesign" href="webdesign.html" />
    <link rel="prev" title="The “sites” framework" href="sites.html" />
 
<script type="text/javascript" src="../../templatebuiltins.js"></script>
<script type="text/javascript">
(function($) {
    if (!django_template_builtins) {
       // templatebuiltins.js missing, do nothing.
       return;
    }
    $(document).ready(function() {
        // Hyperlink Django template tags and filters
        var base = "../templates/builtins.html";
        if (base == "#") {
            // Special case for builtins.html itself
            base = "";
        }
        // Tags are keywords, class '.k'
        $("div.highlight\\-html\\+django span.k").each(function(i, elem) {
             var tagname = $(elem).text();
             if ($.inArray(tagname, django_template_builtins.ttags) != -1) {
                 var fragment = tagname.replace(/_/, '-');
                 $(elem).html("<a href='" + base + "#" + fragment + "'>" + tagname + "</a>");
             }
        });
        // Filters are functions, class '.nf'
        $("div.highlight\\-html\\+django span.nf").each(function(i, elem) {
             var filtername = $(elem).text();
             if ($.inArray(filtername, django_template_builtins.tfilters) != -1) {
                 var fragment = filtername.replace(/_/, '-');
                 $(elem).html("<a href='" + base + "#" + fragment + "'>" + filtername + "</a>");
             }
        });
    });
})(jQuery);
</script>

  </head>
  <body>

    <div class="document">
  <div id="custom-doc" class="yui-t6">
    <div id="hd">
      <h1><a href="../../index.html">Django v1.1 documentation</a></h1>
      <div id="global-nav">
        <a title="Home page" href="../../index.html">Home</a>  |
        <a title="Table of contents" href="../../contents.html">Table of contents</a>  |
        <a title="Global index" href="../../genindex.html">Index</a>  |
        <a title="Module index" href="../../modindex.html">Modules</a>
      </div>
      <div class="nav">
    &laquo; <a href="sites.html" title="The &amp;#8220;sites&amp;#8221; framework">previous</a> 
     |
    <a href="../index.html" title="API Reference" accesskey="U">up</a>
   |
    <a href="webdesign.html" title="django.contrib.webdesign">next</a> &raquo;</div>
    </div>
    
    <div id="bd">
      <div id="yui-main">
        <div class="yui-b">
          <div class="yui-g" id="ref-contrib-syndication">
            
  <div class="section" id="s-module-django.contrib.syndication">
<span id="s-ref-contrib-syndication"></span><span id="module-django.contrib.syndication"></span><span id="ref-contrib-syndication"></span><h1>The syndication feed framework<a class="headerlink" href="#module-django.contrib.syndication" title="Permalink to this headline">¶</a></h1>
<p>Django comes with a high-level syndication-feed-generating framework that makes
creating <a class="reference external" href="http://www.whatisrss.com/">RSS</a> and <a class="reference external" href="http://www.atomenabled.org/">Atom</a> feeds easy.</p>
<p>To create any syndication feed, all you have to do is write a short Python
class. You can create as many feeds as you want.</p>
<p>Django also comes with a lower-level feed-generating API. Use this if you want
to generate feeds outside of a Web context, or in some other lower-level way.</p>
<div class="section" id="s-the-high-level-framework">
<span id="the-high-level-framework"></span><h2>The high-level framework<a class="headerlink" href="#the-high-level-framework" title="Permalink to this headline">¶</a></h2>
<div class="section" id="s-overview">
<span id="overview"></span><h3>Overview<a class="headerlink" href="#overview" title="Permalink to this headline">¶</a></h3>
<p>The high-level feed-generating framework is a view that&#8217;s hooked to <tt class="docutils literal"><span class="pre">/feeds/</span></tt>
by default. Django uses the remainder of the URL (everything after <tt class="docutils literal"><span class="pre">/feeds/</span></tt>)
to determine which feed to output.</p>
<p>To create a feed, just write a <a title="django.contrib.syndication.django.contrib.syndication.feeds.Feed" class="reference internal" href="#django.contrib.syndication.django.contrib.syndication.feeds.Feed"><tt class="xref docutils literal"><span class="pre">Feed</span></tt></a>
class and point to it in your <a class="reference external" href="../../topics/http/urls.html#topics-http-urls"><em>URLconf</em></a>.</p>
</div>
<div class="section" id="s-initialization">
<span id="initialization"></span><h3>Initialization<a class="headerlink" href="#initialization" title="Permalink to this headline">¶</a></h3>
<p>To activate syndication feeds on your Django site, add this line to your
<a class="reference external" href="../../topics/http/urls.html#topics-http-urls"><em>URLconf</em></a>:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="p">(</span><span class="s">r&#39;^feeds/(?P&lt;url&gt;.*)/$&#39;</span><span class="p">,</span> <span class="s">&#39;django.contrib.syndication.views.feed&#39;</span><span class="p">,</span> <span class="p">{</span><span class="s">&#39;feed_dict&#39;</span><span class="p">:</span> <span class="n">feeds</span><span class="p">}),</span>
</pre></div>
</div>
<p>This tells Django to use the RSS framework to handle all URLs starting with
<tt class="docutils literal"><span class="pre">&quot;feeds/&quot;</span></tt>. (You can change that <tt class="docutils literal"><span class="pre">&quot;feeds/&quot;</span></tt> prefix to fit your own
needs.)</p>
<p>This URLconf line has an extra argument: <tt class="docutils literal"><span class="pre">{'feed_dict':</span> <span class="pre">feeds}</span></tt>. Use this
extra argument to pass the syndication framework the feeds that should be
published under that URL.</p>
<p>Specifically, <tt class="xref docutils literal"><span class="pre">feed_dict</span></tt> should be a dictionary that maps a feed's slug
(short URL label) to its <a title="django.contrib.syndication.django.contrib.syndication.feeds.Feed" class="reference internal" href="#django.contrib.syndication.django.contrib.syndication.feeds.Feed"><tt class="xref docutils literal"><span class="pre">Feed</span></tt></a> class.</p>
<p>You can define the <tt class="docutils literal"><span class="pre">feed_dict</span></tt> in the URLconf itself. Here's a full example
URLconf:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">django.conf.urls.defaults</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">from</span> <span class="nn">myproject.feeds</span> <span class="kn">import</span> <span class="n">LatestEntries</span><span class="p">,</span> <span class="n">LatestEntriesByCategory</span>

<span class="n">feeds</span> <span class="o">=</span> <span class="p">{</span>
    <span class="s">&#39;latest&#39;</span><span class="p">:</span> <span class="n">LatestEntries</span><span class="p">,</span>
    <span class="s">&#39;categories&#39;</span><span class="p">:</span> <span class="n">LatestEntriesByCategory</span><span class="p">,</span>
<span class="p">}</span>

<span class="n">urlpatterns</span> <span class="o">=</span> <span class="n">patterns</span><span class="p">(</span><span class="s">&#39;&#39;</span><span class="p">,</span>
    <span class="c"># ...</span>
    <span class="p">(</span><span class="s">r&#39;^feeds/(?P&lt;url&gt;.*)/$&#39;</span><span class="p">,</span> <span class="s">&#39;django.contrib.syndication.views.feed&#39;</span><span class="p">,</span>
        <span class="p">{</span><span class="s">&#39;feed_dict&#39;</span><span class="p">:</span> <span class="n">feeds</span><span class="p">}),</span>
    <span class="c"># ...</span>
<span class="p">)</span>
</pre></div>
</div>
<p>The above example registers two feeds:</p>
<ul class="simple">
<li>The feed represented by <tt class="docutils literal"><span class="pre">LatestEntries</span></tt> will live at <tt class="docutils literal"><span class="pre">feeds/latest/</span></tt>.</li>
<li>The feed represented by <tt class="docutils literal"><span class="pre">LatestEntriesByCategory</span></tt> will live at
<tt class="docutils literal"><span class="pre">feeds/categories/</span></tt>.</li>
</ul>
<p>Once that's set up, you just need to define the
<a title="django.contrib.syndication.django.contrib.syndication.feeds.Feed" class="reference internal" href="#django.contrib.syndication.django.contrib.syndication.feeds.Feed"><tt class="xref docutils literal"><span class="pre">Feed</span></tt></a> classes themselves.</p>
</div>
<div class="section" id="s-feed-classes">
<span id="feed-classes"></span><h3>Feed classes<a class="headerlink" href="#feed-classes" title="Permalink to this headline">¶</a></h3>
<p>A <a title="django.contrib.syndication.django.contrib.syndication.feeds.Feed" class="reference internal" href="#django.contrib.syndication.django.contrib.syndication.feeds.Feed"><tt class="xref docutils literal"><span class="pre">Feed</span></tt></a> class is a simple Python class
that represents a syndication feed. A feed can be simple (e.g., a &quot;site news&quot;
feed, or a basic feed displaying the latest entries of a blog) or more complex
(e.g., a feed displaying all the blog entries in a particular category, where
the category is variable).</p>
<p><a title="django.contrib.syndication.django.contrib.syndication.feeds.Feed" class="reference internal" href="#django.contrib.syndication.django.contrib.syndication.feeds.Feed"><tt class="xref docutils literal"><span class="pre">Feed</span></tt></a> classes must subclass
<tt class="docutils literal"><span class="pre">django.contrib.syndication.feeds.Feed</span></tt>. They can live anywhere in your
codebase.</p>
</div>
<div class="section" id="s-a-simple-example">
<span id="a-simple-example"></span><h3>A simple example<a class="headerlink" href="#a-simple-example" title="Permalink to this headline">¶</a></h3>
<p>This simple example, taken from <a class="reference external" href="http://www.chicagocrime.org/">chicagocrime.org</a>, describes a feed of the
latest five news items:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">django.contrib.syndication.feeds</span> <span class="kn">import</span> <span class="n">Feed</span>
<span class="kn">from</span> <span class="nn">chicagocrime.models</span> <span class="kn">import</span> <span class="n">NewsItem</span>

<span class="k">class</span> <span class="nc">LatestEntries</span><span class="p">(</span><span class="n">Feed</span><span class="p">):</span>
    <span class="n">title</span> <span class="o">=</span> <span class="s">&quot;Chicagocrime.org site news&quot;</span>
    <span class="n">link</span> <span class="o">=</span> <span class="s">&quot;/sitenews/&quot;</span>
    <span class="n">description</span> <span class="o">=</span> <span class="s">&quot;Updates on changes and additions to chicagocrime.org.&quot;</span>

    <span class="k">def</span> <span class="nf">items</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">NewsItem</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s">&#39;-pub_date&#39;</span><span class="p">)[:</span><span class="mi">5</span><span class="p">]</span>
</pre></div>
</div>
<p>Note:</p>
<ul class="simple">
<li>The class subclasses <tt class="docutils literal"><span class="pre">django.contrib.syndication.feeds.Feed</span></tt>.</li>
<li><tt class="xref docutils literal"><span class="pre">title</span></tt>, <tt class="xref docutils literal"><span class="pre">link</span></tt> and <tt class="xref docutils literal"><span class="pre">description</span></tt> correspond to the
standard RSS <tt class="docutils literal"><span class="pre">&lt;title&gt;</span></tt>, <tt class="docutils literal"><span class="pre">&lt;link&gt;</span></tt> and <tt class="docutils literal"><span class="pre">&lt;description&gt;</span></tt> elements,
respectively.</li>
<li><tt class="xref docutils literal"><span class="pre">items()</span></tt> is, simply, a method that returns a list of objects that
should be included in the feed as <tt class="docutils literal"><span class="pre">&lt;item&gt;</span></tt> elements. Although this
example returns <tt class="docutils literal"><span class="pre">NewsItem</span></tt> objects using Django's
<a class="reference external" href="../models/querysets.html#ref-models-querysets"><em>object-relational mapper</em></a>, <tt class="xref docutils literal"><span class="pre">items()</span></tt>
doesn't have to return model instances. Although you get a few bits of
functionality &quot;for free&quot; by using Django models, <tt class="xref docutils literal"><span class="pre">items()</span></tt> can
return any type of object you want.</li>
<li>If you're creating an Atom feed, rather than an RSS feed, set the
<tt class="xref docutils literal"><span class="pre">subtitle</span></tt> attribute instead of the <tt class="xref docutils literal"><span class="pre">description</span></tt> attribute.
See <a class="reference internal" href="#publishing-atom-and-rss-feeds-in-tandem">Publishing Atom and RSS feeds in tandem</a>, later, for an example.</li>
</ul>
<p>One thing's left to do. In an RSS feed, each <tt class="docutils literal"><span class="pre">&lt;item&gt;</span></tt> has a <tt class="docutils literal"><span class="pre">&lt;title&gt;</span></tt>,
<tt class="docutils literal"><span class="pre">&lt;link&gt;</span></tt> and <tt class="docutils literal"><span class="pre">&lt;description&gt;</span></tt>. We need to tell the framework what data to put
into those elements.</p>
<ul>
<li><p class="first">To specify the contents of <tt class="docutils literal"><span class="pre">&lt;title&gt;</span></tt> and <tt class="docutils literal"><span class="pre">&lt;description&gt;</span></tt>, create
<a class="reference external" href="../../topics/templates.html#topics-templates"><em>Django templates</em></a> called
<tt class="docutils literal"><span class="pre">feeds/latest_title.html</span></tt> and
<tt class="docutils literal"><span class="pre">feeds/latest_description.html</span></tt>, where <tt class="xref docutils literal"><span class="pre">latest</span></tt> is the
<tt class="xref docutils literal"><span class="pre">slug</span></tt> specified in the URLconf for the given feed. Note the
<tt class="docutils literal"><span class="pre">.html</span></tt> extension is required. The RSS system renders that template for
each item, passing it two template context variables:</p>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">{{</span> <span class="pre">obj</span> <span class="pre">}}</span></tt> -- The current object (one of whichever objects you
returned in <tt class="xref docutils literal"><span class="pre">items()</span></tt>).</li>
<li><tt class="docutils literal"><span class="pre">{{</span> <span class="pre">site</span> <span class="pre">}}</span></tt> -- A <tt class="xref docutils literal"><span class="pre">django.contrib.sites.models.Site</span></tt> object
representing the current site. This is useful for <tt class="docutils literal"><span class="pre">{{</span> <span class="pre">site.domain</span>
<span class="pre">}}</span></tt> or <tt class="docutils literal"><span class="pre">{{</span> <span class="pre">site.name</span> <span class="pre">}}</span></tt>. If you do <em>not</em> have the Django sites
framework installed, this will be set to a
<tt class="xref docutils literal"><span class="pre">django.contrib.sites.models.RequestSite</span></tt> object. See the
<a class="reference external" href="sites.html#id1"><em>RequestSite section of the sites framework documentation</em></a> for more.</li>
</ul>
<p>If you don't create a template for either the title or description, the
framework will use the template <tt class="docutils literal"><span class="pre">&quot;{{</span> <span class="pre">obj</span> <span class="pre">}}&quot;</span></tt> by default -- that is, the
normal string representation of the object. You can also change the names
of these two templates by specifying <tt class="docutils literal"><span class="pre">title_template</span></tt> and
<tt class="docutils literal"><span class="pre">description_template</span></tt> as attributes of your
<a title="django.contrib.syndication.django.contrib.syndication.feeds.Feed" class="reference internal" href="#django.contrib.syndication.django.contrib.syndication.feeds.Feed"><tt class="xref docutils literal"><span class="pre">Feed</span></tt></a> class.</p>
</li>
<li><p class="first">To specify the contents of <tt class="docutils literal"><span class="pre">&lt;link&gt;</span></tt>, you have two options. For each item
in <tt class="xref docutils literal"><span class="pre">items()</span></tt>, Django first tries calling a method
<tt class="xref docutils literal"><span class="pre">item_link()</span></tt> in the <a title="django.contrib.syndication.django.contrib.syndication.feeds.Feed" class="reference internal" href="#django.contrib.syndication.django.contrib.syndication.feeds.Feed"><tt class="xref docutils literal"><span class="pre">Feed</span></tt></a>
class, passing it a single parameter, <tt class="xref docutils literal"><span class="pre">item</span></tt>, which is the object
itself. If that method doesn't exist, Django tries executing a
<tt class="docutils literal"><span class="pre">get_absolute_url()</span></tt> method on that object. . Both
<tt class="docutils literal"><span class="pre">get_absolute_url()</span></tt> and <tt class="xref docutils literal"><span class="pre">item_link()</span></tt> should return the item's
URL as a normal Python string. As with <tt class="docutils literal"><span class="pre">get_absolute_url()</span></tt>, the result
of <tt class="xref docutils literal"><span class="pre">item_link()</span></tt> will be included directly in the URL, so you are
responsible for doing all necessary URL quoting and conversion to ASCII
inside the method itself.</p>
</li>
<li><p class="first">For the LatestEntries example above, we could have very simple feed
templates:</p>
<ul>
<li><p class="first">latest_title.html:</p>
<div class="highlight-html+django"><div class="highlight"><pre><span class="cp">{{</span> <span class="nv">obj.title</span> <span class="cp">}}</span>
</pre></div>
</div>
</li>
<li><p class="first">latest_description.html:</p>
<div class="highlight-html+django"><div class="highlight"><pre><span class="cp">{{</span> <span class="nv">obj.description</span> <span class="cp">}}</span>
</pre></div>
</div>
</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="s-a-complex-example">
<span id="a-complex-example"></span><h3>A complex example<a class="headerlink" href="#a-complex-example" title="Permalink to this headline">¶</a></h3>
<p>The framework also supports more complex feeds, via parameters.</p>
<p>For example, <a class="reference external" href="http://www.chicagocrime.org/">chicagocrime.org</a> offers an RSS feed of recent crimes for every
police beat in Chicago. It'd be silly to create a separate
<a title="django.contrib.syndication.django.contrib.syndication.feeds.Feed" class="reference internal" href="#django.contrib.syndication.django.contrib.syndication.feeds.Feed"><tt class="xref docutils literal"><span class="pre">Feed</span></tt></a> class for each police beat; that
would violate the <a class="reference external" href="../../misc/design-philosophies.html#dry"><em>DRY principle</em></a> and would couple data to
programming logic. Instead, the syndication framework lets you make generic
feeds that output items based on information in the feed's URL.</p>
<p>On chicagocrime.org, the police-beat feeds are accessible via URLs like this:</p>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">/rss/beats/0613/</span></tt> -- Returns recent crimes for beat 0613.</li>
<li><tt class="docutils literal"><span class="pre">/rss/beats/1424/</span></tt> -- Returns recent crimes for beat 1424.</li>
</ul>
<p>The slug here is <tt class="docutils literal"><span class="pre">&quot;beats&quot;</span></tt>. The syndication framework sees the extra URL bits
after the slug -- <tt class="docutils literal"><span class="pre">0613</span></tt> and <tt class="docutils literal"><span class="pre">1424</span></tt> -- and gives you a hook to tell it what
those URL bits mean, and how they should influence which items get published in
the feed.</p>
<p>An example makes this clear. Here's the code for these beat-specific feeds:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">django.contrib.syndication.feeds</span> <span class="kn">import</span> <span class="n">FeedDoesNotExist</span>
<span class="kn">from</span> <span class="nn">django.core.exceptions</span> <span class="kn">import</span> <span class="n">ObjectDoesNotExist</span>

<span class="k">class</span> <span class="nc">BeatFeed</span><span class="p">(</span><span class="n">Feed</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">get_object</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bits</span><span class="p">):</span>
        <span class="c"># In case of &quot;/rss/beats/0613/foo/bar/baz/&quot;, or other such clutter,</span>
        <span class="c"># check that bits has only one member.</span>
        <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">bits</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">1</span><span class="p">:</span>
            <span class="k">raise</span> <span class="n">ObjectDoesNotExist</span>
        <span class="k">return</span> <span class="n">Beat</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">beat__exact</span><span class="o">=</span><span class="n">bits</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>

    <span class="k">def</span> <span class="nf">title</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
        <span class="k">return</span> <span class="s">&quot;Chicagocrime.org: Crimes for beat </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">obj</span><span class="o">.</span><span class="n">beat</span>

    <span class="k">def</span> <span class="nf">link</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="n">obj</span><span class="p">:</span>
            <span class="k">raise</span> <span class="n">FeedDoesNotExist</span>
        <span class="k">return</span> <span class="n">obj</span><span class="o">.</span><span class="n">get_absolute_url</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">description</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
        <span class="k">return</span> <span class="s">&quot;Crimes recently reported in police beat </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">obj</span><span class="o">.</span><span class="n">beat</span>

    <span class="k">def</span> <span class="nf">items</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
       <span class="k">return</span> <span class="n">Crime</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">beat__id__exact</span><span class="o">=</span><span class="n">obj</span><span class="o">.</span><span class="n">id</span><span class="p">)</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s">&#39;-crime_date&#39;</span><span class="p">)[:</span><span class="mi">30</span><span class="p">]</span>
</pre></div>
</div>
<p>Here's the basic algorithm the RSS framework follows, given this class and a
request to the URL <tt class="docutils literal"><span class="pre">/rss/beats/0613/</span></tt>:</p>
<ul>
<li><p class="first">The framework gets the URL <tt class="docutils literal"><span class="pre">/rss/beats/0613/</span></tt> and notices there's an
extra bit of URL after the slug. It splits that remaining string by the
slash character (<tt class="docutils literal"><span class="pre">&quot;/&quot;</span></tt>) and calls the
<a title="django.contrib.syndication.django.contrib.syndication.feeds.Feed" class="reference internal" href="#django.contrib.syndication.django.contrib.syndication.feeds.Feed"><tt class="xref docutils literal"><span class="pre">Feed</span></tt></a> class'
<tt class="xref docutils literal"><span class="pre">get_object()</span></tt> method, passing it the bits. In this case, bits is
<tt class="docutils literal"><span class="pre">['0613']</span></tt>. For a request to <tt class="docutils literal"><span class="pre">/rss/beats/0613/foo/bar/</span></tt>, bits
would be <tt class="docutils literal"><span class="pre">['0613',</span> <span class="pre">'foo',</span> <span class="pre">'bar']</span></tt>.</p>
</li>
<li><p class="first"><tt class="xref docutils literal"><span class="pre">get_object()</span></tt> is responsible for retrieving the given beat, from
the given <tt class="docutils literal"><span class="pre">bits</span></tt>. In this case, it uses the Django database API to
retrieve the beat. Note that <tt class="xref docutils literal"><span class="pre">get_object()</span></tt> should raise
<tt class="xref docutils literal"><span class="pre">django.core.exceptions.ObjectDoesNotExist</span></tt> if given invalid
parameters. There's no <tt class="docutils literal"><span class="pre">try</span></tt>/<tt class="docutils literal"><span class="pre">except</span></tt> around the
<tt class="docutils literal"><span class="pre">Beat.objects.get()</span></tt> call, because it's not necessary; that function
raises <tt class="xref docutils literal"><span class="pre">Beat.DoesNotExist</span></tt> on failure, and <tt class="xref docutils literal"><span class="pre">Beat.DoesNotExist</span></tt>
is a subclass of <tt class="xref docutils literal"><span class="pre">ObjectDoesNotExist</span></tt>. Raising
<tt class="xref docutils literal"><span class="pre">ObjectDoesNotExist</span></tt> in <tt class="xref docutils literal"><span class="pre">get_object()</span></tt> tells Django to produce
a 404 error for that request.</p>
<div class="versionadded">
<span class="title">New in Django 1.0:</span> <tt class="xref docutils literal"><span class="pre">get_object()</span></tt> can handle the <tt class="docutils literal"><span class="pre">/rss/beats/</span></tt> url.</div>
<p>The <tt class="xref docutils literal"><span class="pre">get_object()</span></tt> method also has a chance to handle the
<tt class="docutils literal"><span class="pre">/rss/beats/</span></tt> url. In this case, <tt class="xref docutils literal"><span class="pre">bits</span></tt> will be an
empty list. In our example, <tt class="docutils literal"><span class="pre">len(bits)</span> <span class="pre">!=</span> <span class="pre">1</span></tt> and an
<tt class="xref docutils literal"><span class="pre">ObjectDoesNotExist</span></tt> exception will be raised, so
<tt class="docutils literal"><span class="pre">/rss/beats/</span></tt> will generate a 404 page. But you can handle this case
however you like. For example, you could generate a combined feed for all
beats.</p>
</li>
<li><p class="first">To generate the feed's <tt class="docutils literal"><span class="pre">&lt;title&gt;</span></tt>, <tt class="docutils literal"><span class="pre">&lt;link&gt;</span></tt> and <tt class="docutils literal"><span class="pre">&lt;description&gt;</span></tt>,
Django uses the <tt class="xref docutils literal"><span class="pre">title()</span></tt>, <tt class="xref docutils literal"><span class="pre">link()</span></tt> and <tt class="xref docutils literal"><span class="pre">description()</span></tt>
methods. In the previous example, they were simple string class
attributes, but this example illustrates that they can be either strings
<em>or</em> methods. For each of <tt class="xref docutils literal"><span class="pre">title</span></tt>, <tt class="xref docutils literal"><span class="pre">link</span></tt> and
<tt class="xref docutils literal"><span class="pre">description</span></tt>, Django follows this algorithm:</p>
<ul class="simple">
<li>First, it tries to call a method, passing the <tt class="docutils literal"><span class="pre">obj</span></tt> argument, where
<tt class="docutils literal"><span class="pre">obj</span></tt> is the object returned by <tt class="xref docutils literal"><span class="pre">get_object()</span></tt>.</li>
<li>Failing that, it tries to call a method with no arguments.</li>
<li>Failing that, it uses the class attribute.</li>
</ul>
<p>Inside the <tt class="xref docutils literal"><span class="pre">link()</span></tt> method, we handle the possibility that <tt class="docutils literal"><span class="pre">obj</span></tt>
might be <tt class="xref docutils literal"><span class="pre">None</span></tt>, which can occur when the URL isn't fully specified. In
some cases, you might want to do something else in this case, which would
mean you'd need to check for <tt class="docutils literal"><span class="pre">obj</span></tt> existing in other methods as well.
(The <tt class="xref docutils literal"><span class="pre">link()</span></tt> method is called very early in the feed generation
process, so it's a good place to bail out early.)</p>
</li>
<li><p class="first">Finally, note that <tt class="xref docutils literal"><span class="pre">items()</span></tt> in this example also takes the <tt class="docutils literal"><span class="pre">obj</span></tt>
argument. The algorithm for <tt class="xref docutils literal"><span class="pre">items</span></tt> is the same as described in the
previous step -- first, it tries <tt class="xref docutils literal"><span class="pre">items(obj)()</span></tt>, then <tt class="xref docutils literal"><span class="pre">items()</span></tt>,
then finally an <tt class="xref docutils literal"><span class="pre">items</span></tt> class attribute (which should be a list).</p>
</li>
</ul>
<p>The <tt class="docutils literal"><span class="pre">ExampleFeed</span></tt> class below gives full documentation on methods and
attributes of <a title="django.contrib.syndication.django.contrib.syndication.feeds.Feed" class="reference internal" href="#django.contrib.syndication.django.contrib.syndication.feeds.Feed"><tt class="xref docutils literal"><span class="pre">Feed</span></tt></a> classes.</p>
</div>
<div class="section" id="s-specifying-the-type-of-feed">
<span id="specifying-the-type-of-feed"></span><h3>Specifying the type of feed<a class="headerlink" href="#specifying-the-type-of-feed" title="Permalink to this headline">¶</a></h3>
<p>By default, feeds produced in this framework use RSS 2.0.</p>
<p>To change that, add a <tt class="docutils literal"><span class="pre">feed_type</span></tt> attribute to your
<a title="django.contrib.syndication.django.contrib.syndication.feeds.Feed" class="reference internal" href="#django.contrib.syndication.django.contrib.syndication.feeds.Feed"><tt class="xref docutils literal"><span class="pre">Feed</span></tt></a> class, like so:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">django.utils.feedgenerator</span> <span class="kn">import</span> <span class="n">Atom1Feed</span>

<span class="k">class</span> <span class="nc">MyFeed</span><span class="p">(</span><span class="n">Feed</span><span class="p">):</span>
    <span class="n">feed_type</span> <span class="o">=</span> <span class="n">Atom1Feed</span>
</pre></div>
</div>
<p>Note that you set <tt class="docutils literal"><span class="pre">feed_type</span></tt> to a class object, not an instance.</p>
<p>Currently available feed types are:</p>
<ul class="simple">
<li><a title="django.contrib.syndication.django.utils.feedgenerator.Rss201rev2Feed" class="reference internal" href="#django.contrib.syndication.django.utils.feedgenerator.Rss201rev2Feed"><tt class="xref docutils literal"><span class="pre">django.utils.feedgenerator.Rss201rev2Feed</span></tt></a> (RSS 2.01. Default.)</li>
<li><a title="django.contrib.syndication.django.utils.feedgenerator.RssUserland091Feed" class="reference internal" href="#django.contrib.syndication.django.utils.feedgenerator.RssUserland091Feed"><tt class="xref docutils literal"><span class="pre">django.utils.feedgenerator.RssUserland091Feed</span></tt></a> (RSS 0.91.)</li>
<li><a title="django.contrib.syndication.django.utils.feedgenerator.Atom1Feed" class="reference internal" href="#django.contrib.syndication.django.utils.feedgenerator.Atom1Feed"><tt class="xref docutils literal"><span class="pre">django.utils.feedgenerator.Atom1Feed</span></tt></a> (Atom 1.0.)</li>
</ul>
</div>
<div class="section" id="s-enclosures">
<span id="enclosures"></span><h3>Enclosures<a class="headerlink" href="#enclosures" title="Permalink to this headline">¶</a></h3>
<p>To specify enclosures, such as those used in creating podcast feeds, use the
<tt class="xref docutils literal"><span class="pre">item_enclosure_url</span></tt>, <tt class="xref docutils literal"><span class="pre">item_enclosure_length</span></tt> and
<tt class="xref docutils literal"><span class="pre">item_enclosure_mime_type</span></tt> hooks. See the <tt class="docutils literal"><span class="pre">ExampleFeed</span></tt> class below for
usage examples.</p>
</div>
<div class="section" id="s-language">
<span id="language"></span><h3>Language<a class="headerlink" href="#language" title="Permalink to this headline">¶</a></h3>
<p>Feeds created by the syndication framework automatically include the
appropriate <tt class="docutils literal"><span class="pre">&lt;language&gt;</span></tt> tag (RSS 2.0) or <tt class="docutils literal"><span class="pre">xml:lang</span></tt> attribute (Atom). This
comes directly from your <a class="reference external" href="../settings.html#setting-LANGUAGE_CODE"><tt class="xref docutils literal"><span class="pre">LANGUAGE_CODE</span></tt></a> setting.</p>
</div>
<div class="section" id="s-urls">
<span id="urls"></span><h3>URLs<a class="headerlink" href="#urls" title="Permalink to this headline">¶</a></h3>
<p>The <tt class="xref docutils literal"><span class="pre">link</span></tt> method/attribute can return either an absolute URL (e.g.
<tt class="docutils literal"><span class="pre">&quot;/blog/&quot;</span></tt>) or a URL with the fully-qualified domain and protocol (e.g.
<tt class="docutils literal"><span class="pre">&quot;http://www.example.com/blog/&quot;</span></tt>). If <tt class="xref docutils literal"><span class="pre">link</span></tt> doesn't return the domain,
the syndication framework will insert the domain of the current site, according
to your <a class="reference external" href="../settings.html#setting-SITE_ID"><tt class="xref docutils literal"><span class="pre">SITE_ID</span> <span class="pre">setting</span></tt></a>.</p>
<p>Atom feeds require a <tt class="docutils literal"><span class="pre">&lt;link</span> <span class="pre">rel=&quot;self&quot;&gt;</span></tt> that defines the feed's current
location. The syndication framework populates this automatically, using the
domain of the current site according to the <a class="reference external" href="../settings.html#setting-SITE_ID"><tt class="xref docutils literal"><span class="pre">SITE_ID</span></tt></a> setting.</p>
</div>
<div class="section" id="s-publishing-atom-and-rss-feeds-in-tandem">
<span id="publishing-atom-and-rss-feeds-in-tandem"></span><h3>Publishing Atom and RSS feeds in tandem<a class="headerlink" href="#publishing-atom-and-rss-feeds-in-tandem" title="Permalink to this headline">¶</a></h3>
<p>Some developers like to make available both Atom <em>and</em> RSS versions of their
feeds. That's easy to do with Django: Just create a subclass of your
<a title="django.contrib.syndication.django.contrib.syndication.feeds.Feed" class="reference internal" href="#django.contrib.syndication.django.contrib.syndication.feeds.Feed"><tt class="xref docutils literal"><span class="pre">Feed</span></tt></a>
class and set the <tt class="xref docutils literal"><span class="pre">feed_type</span></tt> to something different. Then update your
URLconf to add the extra versions.</p>
<p>Here's a full example:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">django.contrib.syndication.feeds</span> <span class="kn">import</span> <span class="n">Feed</span>
<span class="kn">from</span> <span class="nn">chicagocrime.models</span> <span class="kn">import</span> <span class="n">NewsItem</span>
<span class="kn">from</span> <span class="nn">django.utils.feedgenerator</span> <span class="kn">import</span> <span class="n">Atom1Feed</span>

<span class="k">class</span> <span class="nc">RssSiteNewsFeed</span><span class="p">(</span><span class="n">Feed</span><span class="p">):</span>
    <span class="n">title</span> <span class="o">=</span> <span class="s">&quot;Chicagocrime.org site news&quot;</span>
    <span class="n">link</span> <span class="o">=</span> <span class="s">&quot;/sitenews/&quot;</span>
    <span class="n">description</span> <span class="o">=</span> <span class="s">&quot;Updates on changes and additions to chicagocrime.org.&quot;</span>

    <span class="k">def</span> <span class="nf">items</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">NewsItem</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="s">&#39;-pub_date&#39;</span><span class="p">)[:</span><span class="mi">5</span><span class="p">]</span>

<span class="k">class</span> <span class="nc">AtomSiteNewsFeed</span><span class="p">(</span><span class="n">RssSiteNewsFeed</span><span class="p">):</span>
    <span class="n">feed_type</span> <span class="o">=</span> <span class="n">Atom1Feed</span>
    <span class="n">subtitle</span> <span class="o">=</span> <span class="n">RssSiteNewsFeed</span><span class="o">.</span><span class="n">description</span>
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p>In this example, the RSS feed uses a <tt class="xref docutils literal"><span class="pre">description</span></tt> while the Atom
feed uses a <tt class="xref docutils literal"><span class="pre">subtitle</span></tt>. That's because Atom feeds don't provide for
a feed-level &quot;description,&quot; but they <em>do</em> provide for a &quot;subtitle.&quot;</p>
<p>If you provide a <tt class="xref docutils literal"><span class="pre">description</span></tt> in your
<a title="django.contrib.syndication.django.contrib.syndication.feeds.Feed" class="reference internal" href="#django.contrib.syndication.django.contrib.syndication.feeds.Feed"><tt class="xref docutils literal"><span class="pre">Feed</span></tt></a> class, Django will <em>not</em>
automatically put that into the <tt class="xref docutils literal"><span class="pre">subtitle</span></tt> element, because a
subtitle and description are not necessarily the same thing. Instead, you
should define a <tt class="xref docutils literal"><span class="pre">subtitle</span></tt> attribute.</p>
<p class="last">In the above example, we simply set the Atom feed's <tt class="xref docutils literal"><span class="pre">subtitle</span></tt> to the
RSS feed's <tt class="xref docutils literal"><span class="pre">description</span></tt>, because it's quite short already.</p>
</div>
<p>And the accompanying URLconf:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">django.conf.urls.defaults</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">from</span> <span class="nn">myproject.feeds</span> <span class="kn">import</span> <span class="n">RssSiteNewsFeed</span><span class="p">,</span> <span class="n">AtomSiteNewsFeed</span>

<span class="n">feeds</span> <span class="o">=</span> <span class="p">{</span>
    <span class="s">&#39;rss&#39;</span><span class="p">:</span> <span class="n">RssSiteNewsFeed</span><span class="p">,</span>
    <span class="s">&#39;atom&#39;</span><span class="p">:</span> <span class="n">AtomSiteNewsFeed</span><span class="p">,</span>
<span class="p">}</span>

<span class="n">urlpatterns</span> <span class="o">=</span> <span class="n">patterns</span><span class="p">(</span><span class="s">&#39;&#39;</span><span class="p">,</span>
    <span class="c"># ...</span>
    <span class="p">(</span><span class="s">r&#39;^feeds/(?P&lt;url&gt;.*)/$&#39;</span><span class="p">,</span> <span class="s">&#39;django.contrib.syndication.views.feed&#39;</span><span class="p">,</span>
        <span class="p">{</span><span class="s">&#39;feed_dict&#39;</span><span class="p">:</span> <span class="n">feeds</span><span class="p">}),</span>
    <span class="c"># ...</span>
<span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="s-feed-class-reference">
<span id="feed-class-reference"></span><h3>Feed class reference<a class="headerlink" href="#feed-class-reference" title="Permalink to this headline">¶</a></h3>
<dl class="class">
<dt id="django.contrib.syndication.django.contrib.syndication.feeds.Feed">
<em class="property">class </em><tt class="descclassname">django.contrib.syndication.feeds.</tt><tt class="descname">Feed</tt><a class="headerlink" href="#django.contrib.syndication.django.contrib.syndication.feeds.Feed" title="Permalink to this definition">¶</a></dt>
<dd></dd></dl>

<p>This example illustrates all possible attributes and methods for a
<a title="django.contrib.syndication.django.contrib.syndication.feeds.Feed" class="reference internal" href="#django.contrib.syndication.django.contrib.syndication.feeds.Feed"><tt class="xref docutils literal"><span class="pre">Feed</span></tt></a> class:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">django.contrib.syndication.feeds</span> <span class="kn">import</span> <span class="n">Feed</span>
<span class="kn">from</span> <span class="nn">django.utils</span> <span class="kn">import</span> <span class="n">feedgenerator</span>

<span class="k">class</span> <span class="nc">ExampleFeed</span><span class="p">(</span><span class="n">Feed</span><span class="p">):</span>

    <span class="c"># FEED TYPE -- Optional. This should be a class that subclasses</span>
    <span class="c"># django.utils.feedgenerator.SyndicationFeed. This designates which</span>
    <span class="c"># type of feed this should be: RSS 2.0, Atom 1.0, etc.</span>
    <span class="c"># If you don&#39;t specify feed_type, your feed will be RSS 2.0.</span>
    <span class="c"># This should be a class, not an instance of the class.</span>

    <span class="n">feed_type</span> <span class="o">=</span> <span class="n">feedgenerator</span><span class="o">.</span><span class="n">Rss201rev2Feed</span>

    <span class="c"># TEMPLATE NAMES -- Optional. These should be strings representing</span>
    <span class="c"># names of Django templates that the system should use in rendering the</span>
    <span class="c"># title and description of your feed items. Both are optional.</span>
    <span class="c"># If you don&#39;t specify one, or either, Django will use the template</span>
    <span class="c"># &#39;feeds/SLUG_title.html&#39; and &#39;feeds/SLUG_description.html&#39;, where SLUG</span>
    <span class="c"># is the slug you specify in the URL.</span>

    <span class="n">title_template</span> <span class="o">=</span> <span class="bp">None</span>
    <span class="n">description_template</span> <span class="o">=</span> <span class="bp">None</span>

    <span class="c"># TITLE -- One of the following three is required. The framework looks</span>
    <span class="c"># for them in this order.</span>

    <span class="k">def</span> <span class="nf">title</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Takes the object returned by get_object() and returns the feed&#39;s</span>
<span class="sd">        title as a normal Python string.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="nf">title</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Returns the feed&#39;s title as a normal Python string.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="n">title</span> <span class="o">=</span> <span class="s">&#39;foo&#39;</span> <span class="c"># Hard-coded title.</span>

    <span class="c"># LINK -- One of the following three is required. The framework looks</span>
    <span class="c"># for them in this order.</span>

    <span class="k">def</span> <span class="nf">link</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Takes the object returned by get_object() and returns the feed&#39;s</span>
<span class="sd">        link as a normal Python string.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="nf">link</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Returns the feed&#39;s link as a normal Python string.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="n">link</span> <span class="o">=</span> <span class="s">&#39;/foo/bar/&#39;</span> <span class="c"># Hard-coded link.</span>

    <span class="c"># GUID -- One of the following three is optional. The framework looks</span>
    <span class="c"># for them in this order. This property is only used for Atom feeds</span>
    <span class="c"># (where it is the feed-level ID element). If not provided, the feed</span>
    <span class="c"># link is used as the ID.</span>

    <span class="k">def</span> <span class="nf">feed_guid</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Takes the object returned by get_object() and returns the globally</span>
<span class="sd">        unique ID for the feed as a normal Python string.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="nf">feed_guid</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Returns the feed&#39;s globally unique ID as a normal Python string.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="n">feed_guid</span> <span class="o">=</span> <span class="s">&#39;/foo/bar/1234&#39;</span> <span class="c"># Hard-coded guid.</span>

    <span class="c"># DESCRIPTION -- One of the following three is required. The framework</span>
    <span class="c"># looks for them in this order.</span>

    <span class="k">def</span> <span class="nf">description</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Takes the object returned by get_object() and returns the feed&#39;s</span>
<span class="sd">        description as a normal Python string.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="nf">description</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Returns the feed&#39;s description as a normal Python string.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="n">description</span> <span class="o">=</span> <span class="s">&#39;Foo bar baz.&#39;</span> <span class="c"># Hard-coded description.</span>

    <span class="c"># AUTHOR NAME --One of the following three is optional. The framework</span>
    <span class="c"># looks for them in this order.</span>

    <span class="k">def</span> <span class="nf">author_name</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Takes the object returned by get_object() and returns the feed&#39;s</span>
<span class="sd">        author&#39;s name as a normal Python string.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="nf">author_name</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Returns the feed&#39;s author&#39;s name as a normal Python string.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="n">author_name</span> <span class="o">=</span> <span class="s">&#39;Sally Smith&#39;</span> <span class="c"># Hard-coded author name.</span>

    <span class="c"># AUTHOR E-MAIL --One of the following three is optional. The framework</span>
    <span class="c"># looks for them in this order.</span>

    <span class="k">def</span> <span class="nf">author_email</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Takes the object returned by get_object() and returns the feed&#39;s</span>
<span class="sd">        author&#39;s e-mail as a normal Python string.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="nf">author_email</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Returns the feed&#39;s author&#39;s e-mail as a normal Python string.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="n">author_email</span> <span class="o">=</span> <span class="s">&#39;test@example.com&#39;</span> <span class="c"># Hard-coded author e-mail.</span>

    <span class="c"># AUTHOR LINK --One of the following three is optional. The framework</span>
    <span class="c"># looks for them in this order. In each case, the URL should include</span>
    <span class="c"># the &quot;http://&quot; and domain name.</span>

    <span class="k">def</span> <span class="nf">author_link</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Takes the object returned by get_object() and returns the feed&#39;s</span>
<span class="sd">        author&#39;s URL as a normal Python string.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="nf">author_link</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Returns the feed&#39;s author&#39;s URL as a normal Python string.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="n">author_link</span> <span class="o">=</span> <span class="s">&#39;http://www.example.com/&#39;</span> <span class="c"># Hard-coded author URL.</span>

    <span class="c"># CATEGORIES -- One of the following three is optional. The framework</span>
    <span class="c"># looks for them in this order. In each case, the method/attribute</span>
    <span class="c"># should return an iterable object that returns strings.</span>

    <span class="k">def</span> <span class="nf">categories</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Takes the object returned by get_object() and returns the feed&#39;s</span>
<span class="sd">        categories as iterable over strings.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="nf">categories</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Returns the feed&#39;s categories as iterable over strings.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="n">categories</span> <span class="o">=</span> <span class="p">(</span><span class="s">&quot;python&quot;</span><span class="p">,</span> <span class="s">&quot;django&quot;</span><span class="p">)</span> <span class="c"># Hard-coded list of categories.</span>

    <span class="c"># COPYRIGHT NOTICE -- One of the following three is optional. The</span>
    <span class="c"># framework looks for them in this order.</span>

    <span class="k">def</span> <span class="nf">feed_copyright</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Takes the object returned by get_object() and returns the feed&#39;s</span>
<span class="sd">        copyright notice as a normal Python string.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="nf">feed_copyright</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Returns the feed&#39;s copyright notice as a normal Python string.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="n">feed_copyright</span> <span class="o">=</span> <span class="s">&#39;Copyright (c) 2007, Sally Smith&#39;</span> <span class="c"># Hard-coded copyright notice.</span>

    <span class="c"># TTL -- One of the following three is optional. The framework looks</span>
    <span class="c"># for them in this order. Ignored for Atom feeds.</span>

    <span class="k">def</span> <span class="nf">ttl</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Takes the object returned by get_object() and returns the feed&#39;s</span>
<span class="sd">        TTL (Time To Live) as a normal Python string.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="nf">ttl</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Returns the feed&#39;s TTL as a normal Python string.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="n">ttl</span> <span class="o">=</span> <span class="mi">600</span> <span class="c"># Hard-coded Time To Live.</span>

    <span class="c"># ITEMS -- One of the following three is required. The framework looks</span>
    <span class="c"># for them in this order.</span>

    <span class="k">def</span> <span class="nf">items</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Takes the object returned by get_object() and returns a list of</span>
<span class="sd">        items to publish in this feed.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="nf">items</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Returns a list of items to publish in this feed.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="n">items</span> <span class="o">=</span> <span class="p">(</span><span class="s">&#39;Item 1&#39;</span><span class="p">,</span> <span class="s">&#39;Item 2&#39;</span><span class="p">)</span> <span class="c"># Hard-coded items.</span>

    <span class="c"># GET_OBJECT -- This is required for feeds that publish different data</span>
    <span class="c"># for different URL parameters. (See &quot;A complex example&quot; above.)</span>

    <span class="k">def</span> <span class="nf">get_object</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bits</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Takes a list of strings gleaned from the URL and returns an object</span>
<span class="sd">        represented by this feed. Raises</span>
<span class="sd">        django.core.exceptions.ObjectDoesNotExist on error.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="c"># ITEM LINK -- One of these three is required. The framework looks for</span>
    <span class="c"># them in this order.</span>

    <span class="c"># First, the framework tries the two methods below, in</span>
    <span class="c"># order. Failing that, it falls back to the get_absolute_url()</span>
    <span class="c"># method on each item returned by items().</span>

    <span class="k">def</span> <span class="nf">item_link</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">item</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Takes an item, as returned by items(), and returns the item&#39;s URL.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="nf">item_link</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Returns the URL for every item in the feed.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="c"># ITEM_GUID -- The following method is optional. If not provided, the</span>
    <span class="c"># item&#39;s link is used by default.</span>

    <span class="k">def</span> <span class="nf">item_guid</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Takes an item, as return by items(), and returns the item&#39;s ID.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="c"># ITEM AUTHOR NAME -- One of the following three is optional. The</span>
    <span class="c"># framework looks for them in this order.</span>

    <span class="k">def</span> <span class="nf">item_author_name</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">item</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Takes an item, as returned by items(), and returns the item&#39;s</span>
<span class="sd">        author&#39;s name as a normal Python string.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="nf">item_author_name</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Returns the author name for every item in the feed.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="n">item_author_name</span> <span class="o">=</span> <span class="s">&#39;Sally Smith&#39;</span> <span class="c"># Hard-coded author name.</span>

    <span class="c"># ITEM AUTHOR E-MAIL --One of the following three is optional. The</span>
    <span class="c"># framework looks for them in this order.</span>
    <span class="c">#</span>
    <span class="c"># If you specify this, you must specify item_author_name.</span>

    <span class="k">def</span> <span class="nf">item_author_email</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Takes an item, as returned by items(), and returns the item&#39;s</span>
<span class="sd">        author&#39;s e-mail as a normal Python string.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="nf">item_author_email</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Returns the author e-mail for every item in the feed.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="n">item_author_email</span> <span class="o">=</span> <span class="s">&#39;test@example.com&#39;</span> <span class="c"># Hard-coded author e-mail.</span>

    <span class="c"># ITEM AUTHOR LINK --One of the following three is optional. The</span>
    <span class="c"># framework looks for them in this order. In each case, the URL should</span>
    <span class="c"># include the &quot;http://&quot; and domain name.</span>
    <span class="c">#</span>
    <span class="c"># If you specify this, you must specify item_author_name.</span>

    <span class="k">def</span> <span class="nf">item_author_link</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Takes an item, as returned by items(), and returns the item&#39;s</span>
<span class="sd">        author&#39;s URL as a normal Python string.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="nf">item_author_link</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Returns the author URL for every item in the feed.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="n">item_author_link</span> <span class="o">=</span> <span class="s">&#39;http://www.example.com/&#39;</span> <span class="c"># Hard-coded author URL.</span>

    <span class="c"># ITEM ENCLOSURE URL -- One of these three is required if you&#39;re</span>
    <span class="c"># publishing enclosures. The framework looks for them in this order.</span>

    <span class="k">def</span> <span class="nf">item_enclosure_url</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">item</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Takes an item, as returned by items(), and returns the item&#39;s</span>
<span class="sd">        enclosure URL.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="nf">item_enclosure_url</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Returns the enclosure URL for every item in the feed.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="n">item_enclosure_url</span> <span class="o">=</span> <span class="s">&quot;/foo/bar.mp3&quot;</span> <span class="c"># Hard-coded enclosure link.</span>

    <span class="c"># ITEM ENCLOSURE LENGTH -- One of these three is required if you&#39;re</span>
    <span class="c"># publishing enclosures. The framework looks for them in this order.</span>
    <span class="c"># In each case, the returned value should be either an integer, or a</span>
    <span class="c"># string representation of the integer, in bytes.</span>

    <span class="k">def</span> <span class="nf">item_enclosure_length</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">item</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Takes an item, as returned by items(), and returns the item&#39;s</span>
<span class="sd">        enclosure length.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="nf">item_enclosure_length</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Returns the enclosure length for every item in the feed.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="n">item_enclosure_length</span> <span class="o">=</span> <span class="mi">32000</span> <span class="c"># Hard-coded enclosure length.</span>

    <span class="c"># ITEM ENCLOSURE MIME TYPE -- One of these three is required if you&#39;re</span>
    <span class="c"># publishing enclosures. The framework looks for them in this order.</span>

    <span class="k">def</span> <span class="nf">item_enclosure_mime_type</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">item</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Takes an item, as returned by items(), and returns the item&#39;s</span>
<span class="sd">        enclosure MIME type.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="nf">item_enclosure_mime_type</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Returns the enclosure MIME type for every item in the feed.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="n">item_enclosure_mime_type</span> <span class="o">=</span> <span class="s">&quot;audio/mpeg&quot;</span> <span class="c"># Hard-coded enclosure MIME type.</span>

    <span class="c"># ITEM PUBDATE -- It&#39;s optional to use one of these three. This is a</span>
    <span class="c"># hook that specifies how to get the pubdate for a given item.</span>
    <span class="c"># In each case, the method/attribute should return a Python</span>
    <span class="c"># datetime.datetime object.</span>

    <span class="k">def</span> <span class="nf">item_pubdate</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">item</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Takes an item, as returned by items(), and returns the item&#39;s</span>
<span class="sd">        pubdate.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="nf">item_pubdate</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Returns the pubdate for every item in the feed.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="n">item_pubdate</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="p">(</span><span class="mi">2005</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span> <span class="c"># Hard-coded pubdate.</span>

    <span class="c"># ITEM CATEGORIES -- It&#39;s optional to use one of these three. This is</span>
    <span class="c"># a hook that specifies how to get the list of categories for a given</span>
    <span class="c"># item. In each case, the method/attribute should return an iterable</span>
    <span class="c"># object that returns strings.</span>

    <span class="k">def</span> <span class="nf">item_categories</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">item</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Takes an item, as returned by items(), and returns the item&#39;s</span>
<span class="sd">        categories.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="nf">item_categories</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Returns the categories for every item in the feed.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="n">item_categories</span> <span class="o">=</span> <span class="p">(</span><span class="s">&quot;python&quot;</span><span class="p">,</span> <span class="s">&quot;django&quot;</span><span class="p">)</span> <span class="c"># Hard-coded categories.</span>

    <span class="c"># ITEM COPYRIGHT NOTICE (only applicable to Atom feeds) -- One of the</span>
    <span class="c"># following three is optional. The framework looks for them in this</span>
    <span class="c"># order.</span>

    <span class="k">def</span> <span class="nf">item_copyright</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Takes an item, as returned by items(), and returns the item&#39;s</span>
<span class="sd">        copyright notice as a normal Python string.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="nf">item_copyright</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Returns the copyright notice for every item in the feed.</span>
<span class="sd">        &quot;&quot;&quot;</span>

    <span class="n">item_copyright</span> <span class="o">=</span> <span class="s">&#39;Copyright (c) 2007, Sally Smith&#39;</span> <span class="c"># Hard-coded copyright notice.</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="s-the-low-level-framework">
<span id="the-low-level-framework"></span><h2>The low-level framework<a class="headerlink" href="#the-low-level-framework" title="Permalink to this headline">¶</a></h2>
<p>Behind the scenes, the high-level RSS framework uses a lower-level framework
for generating feeds' XML. This framework lives in a single module:
<a class="reference external" href="http://code.djangoproject.com/browser/django/trunk/django/utils/feedgenerator.py">django/utils/feedgenerator.py</a>.</p>
<p>You use this framework on your own, for lower-level feed generation. You can
also create custom feed generator subclasses for use with the <tt class="docutils literal"><span class="pre">feed_type</span></tt>
<tt class="docutils literal"><span class="pre">Feed</span></tt> option.</p>
<div class="section" id="s-syndicationfeed-classes">
<span id="syndicationfeed-classes"></span><h3><tt class="docutils literal"><span class="pre">SyndicationFeed</span></tt> classes<a class="headerlink" href="#syndicationfeed-classes" title="Permalink to this headline">¶</a></h3>
<p>The <tt class="xref docutils literal"><span class="pre">feedgenerator</span></tt> module contains a base class:</p>
<dl class="class">
<dt id="django.contrib.syndication.django.utils.feedgenerator.SyndicationFeed">
<em class="property">class </em><tt class="descclassname">django.utils.feedgenerator.</tt><tt class="descname">SyndicationFeed</tt><a class="headerlink" href="#django.contrib.syndication.django.utils.feedgenerator.SyndicationFeed" title="Permalink to this definition">¶</a></dt>
<dd></dd></dl>

<p>and several subclasses:</p>
<dl class="class">
<dt id="django.contrib.syndication.django.utils.feedgenerator.RssUserland091Feed">
<em class="property">class </em><tt class="descclassname">django.utils.feedgenerator.</tt><tt class="descname">RssUserland091Feed</tt><a class="headerlink" href="#django.contrib.syndication.django.utils.feedgenerator.RssUserland091Feed" title="Permalink to this definition">¶</a></dt>
<dd></dd></dl>

<dl class="class">
<dt id="django.contrib.syndication.django.utils.feedgenerator.Rss201rev2Feed">
<em class="property">class </em><tt class="descclassname">django.utils.feedgenerator.</tt><tt class="descname">Rss201rev2Feed</tt><a class="headerlink" href="#django.contrib.syndication.django.utils.feedgenerator.Rss201rev2Feed" title="Permalink to this definition">¶</a></dt>
<dd></dd></dl>

<dl class="class">
<dt id="django.contrib.syndication.django.utils.feedgenerator.Atom1Feed">
<em class="property">class </em><tt class="descclassname">django.utils.feedgenerator.</tt><tt class="descname">Atom1Feed</tt><a class="headerlink" href="#django.contrib.syndication.django.utils.feedgenerator.Atom1Feed" title="Permalink to this definition">¶</a></dt>
<dd></dd></dl>

<p>Each of these three classes knows how to render a certain type of feed as XML.
They share this interface:</p>
<dl class="method">
<dt id="django.contrib.syndication.SyndicationFeed.__init__">
<tt class="descclassname">SyndicationFeed.</tt><tt class="descname">__init__</tt>(<em>**kwargs</em>)<a class="headerlink" href="#django.contrib.syndication.SyndicationFeed.__init__" title="Permalink to this definition">¶</a></dt>
<dd><p>Initialize the feed with the given dictionary of metadata, which applies to
the entire feed. Required keyword arguments are:</p>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">title</span></tt></li>
<li><tt class="docutils literal"><span class="pre">link</span></tt></li>
<li><tt class="docutils literal"><span class="pre">description</span></tt></li>
</ul>
<p>There's also a bunch of other optional keywords:</p>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">language</span></tt></li>
<li><tt class="docutils literal"><span class="pre">author_email</span></tt></li>
<li><tt class="docutils literal"><span class="pre">author_name</span></tt></li>
<li><tt class="docutils literal"><span class="pre">author_link</span></tt></li>
<li><tt class="docutils literal"><span class="pre">subtitle</span></tt></li>
<li><tt class="docutils literal"><span class="pre">categories</span></tt></li>
<li><tt class="docutils literal"><span class="pre">feed_url</span></tt></li>
<li><tt class="docutils literal"><span class="pre">feed_copyright</span></tt></li>
<li><tt class="docutils literal"><span class="pre">feed_guid</span></tt></li>
<li><tt class="docutils literal"><span class="pre">ttl</span></tt></li>
</ul>
<p>Any extra keyword arguments you pass to <tt class="docutils literal"><span class="pre">__init__</span></tt> will be stored in
<tt class="docutils literal"><span class="pre">self.feed</span></tt> for use with <a class="reference internal" href="#custom-feed-generators">custom feed generators</a>.</p>
<p>All parameters should be Unicode objects, except <tt class="docutils literal"><span class="pre">categories</span></tt>, which
should be a sequence of Unicode objects.</p>
</dd></dl>

<dl class="method">
<dt id="django.contrib.syndication.SyndicationFeed.add_item">
<tt class="descclassname">SyndicationFeed.</tt><tt class="descname">add_item</tt>(<em>**kwargs</em>)<a class="headerlink" href="#django.contrib.syndication.SyndicationFeed.add_item" title="Permalink to this definition">¶</a></dt>
<dd><p>Add an item to the feed with the given parameters.</p>
<p>Required keyword arguments are:</p>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">title</span></tt></li>
<li><tt class="docutils literal"><span class="pre">link</span></tt></li>
<li><tt class="docutils literal"><span class="pre">description</span></tt></li>
</ul>
<p>Optional keyword arguments are:</p>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">author_email</span></tt></li>
<li><tt class="docutils literal"><span class="pre">author_name</span></tt></li>
<li><tt class="docutils literal"><span class="pre">author_link</span></tt></li>
<li><tt class="docutils literal"><span class="pre">pubdate</span></tt></li>
<li><tt class="docutils literal"><span class="pre">comments</span></tt></li>
<li><tt class="docutils literal"><span class="pre">unique_id</span></tt></li>
<li><tt class="docutils literal"><span class="pre">enclosure</span></tt></li>
<li><tt class="docutils literal"><span class="pre">categories</span></tt></li>
<li><tt class="docutils literal"><span class="pre">item_copyright</span></tt></li>
<li><tt class="docutils literal"><span class="pre">ttl</span></tt></li>
</ul>
<p>Extra keyword arguments will be stored for <a class="reference internal" href="#custom-feed-generators">custom feed generators</a>.</p>
<p>All parameters, if given, should be Unicode objects, except:</p>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">pubdate</span></tt> should be a <a class="reference external" href="http://docs.python.org/library/datetime.html#datetime-objects">Python datetime object</a>.</li>
<li><tt class="docutils literal"><span class="pre">enclosure</span></tt> should be an instance of <tt class="docutils literal"><span class="pre">feedgenerator.Enclosure</span></tt>.</li>
<li><tt class="docutils literal"><span class="pre">categories</span></tt> should be a sequence of Unicode objects.</li>
</ul>
</dd></dl>

<dl class="method">
<dt id="django.contrib.syndication.SyndicationFeed.write">
<tt class="descclassname">SyndicationFeed.</tt><tt class="descname">write</tt>(<em>outfile</em>, <em>encoding</em>)<a class="headerlink" href="#django.contrib.syndication.SyndicationFeed.write" title="Permalink to this definition">¶</a></dt>
<dd>Outputs the feed in the given encoding to outfile, which is a file-like object.</dd></dl>

<dl class="method">
<dt id="django.contrib.syndication.SyndicationFeed.writeString">
<tt class="descclassname">SyndicationFeed.</tt><tt class="descname">writeString</tt>(<em>encoding</em>)<a class="headerlink" href="#django.contrib.syndication.SyndicationFeed.writeString" title="Permalink to this definition">¶</a></dt>
<dd>Returns the feed as a string in the given encoding.</dd></dl>

<p>For example, to create an Atom 1.0 feed and print it to standard output:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">django.utils</span> <span class="kn">import</span> <span class="n">feedgenerator</span>
<span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">datetime</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">f</span> <span class="o">=</span> <span class="n">feedgenerator</span><span class="o">.</span><span class="n">Atom1Feed</span><span class="p">(</span>
<span class="gp">... </span>    <span class="n">title</span><span class="o">=</span><span class="s">u&quot;My Weblog&quot;</span><span class="p">,</span>
<span class="gp">... </span>    <span class="n">link</span><span class="o">=</span><span class="s">u&quot;http://www.example.com/&quot;</span><span class="p">,</span>
<span class="gp">... </span>    <span class="n">description</span><span class="o">=</span><span class="s">u&quot;In which I write about what I ate today.&quot;</span><span class="p">,</span>
<span class="gp">... </span>    <span class="n">language</span><span class="o">=</span><span class="s">u&quot;en&quot;</span><span class="p">,</span>
<span class="gp">... </span>    <span class="n">author_name</span><span class="o">=</span><span class="s">u&quot;Myself&quot;</span><span class="p">,</span>
<span class="gp">... </span>    <span class="n">feed_url</span><span class="o">=</span><span class="s">u&quot;http://example.com/atom.xml&quot;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">f</span><span class="o">.</span><span class="n">add_item</span><span class="p">(</span><span class="n">title</span><span class="o">=</span><span class="s">u&quot;Hot dog today&quot;</span><span class="p">,</span>
<span class="gp">... </span>    <span class="n">link</span><span class="o">=</span><span class="s">u&quot;http://www.example.com/entries/1/&quot;</span><span class="p">,</span>
<span class="gp">... </span>    <span class="n">pubdate</span><span class="o">=</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">(),</span>
<span class="gp">... </span>    <span class="n">description</span><span class="o">=</span><span class="s">u&quot;&lt;p&gt;Today I had a Vienna Beef hot dog. It was pink, plump and perfect.&lt;/p&gt;&quot;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">print</span> <span class="n">f</span><span class="o">.</span><span class="n">writeString</span><span class="p">(</span><span class="s">&#39;UTF-8&#39;</span><span class="p">)</span>
<span class="go">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</span>
<span class="go">&lt;feed xmlns=&quot;http://www.w3.org/2005/Atom&quot; xml:lang=&quot;en&quot;&gt;</span>
<span class="gp">...</span>
<span class="go">&lt;/feed&gt;</span>
</pre></div>
</div>
</div>
<div class="section" id="s-custom-feed-generators">
<span id="custom-feed-generators"></span><h3>Custom feed generators<a class="headerlink" href="#custom-feed-generators" title="Permalink to this headline">¶</a></h3>
<p>If you need to produce a custom feed format, you've got a couple of options.</p>
<p>If the feed format is totally custom, you'll want to subclass
<tt class="docutils literal"><span class="pre">SyndicationFeed</span></tt> and completely replace the <tt class="docutils literal"><span class="pre">write()</span></tt> and
<tt class="docutils literal"><span class="pre">writeString()</span></tt> methods.</p>
<p>However, if the feed format is a spin-off of RSS or Atom (i.e. <a class="reference external" href="http://georss.org/">GeoRSS</a>, Apple's
<a class="reference external" href="http://www.apple.com/itunes/podcasts/specs.html">iTunes podcast format</a>, etc.), you've got a better choice. These types of
feeds typically add extra elements and/or attributes to the underlying format,
and there are a set of methods that <tt class="docutils literal"><span class="pre">SyndicationFeed</span></tt> calls to get these extra
attributes. Thus, you can subclass the appropriate feed generator class
(<tt class="docutils literal"><span class="pre">Atom1Feed</span></tt> or <tt class="docutils literal"><span class="pre">Rss201rev2Feed</span></tt>) and extend these callbacks. They are:</p>
<dl class="docutils">
<dt><tt class="docutils literal"><span class="pre">SyndicationFeed.root_attributes(self,</span> <span class="pre">)</span></tt></dt>
<dd>Return a <tt class="docutils literal"><span class="pre">dict</span></tt> of attributes to add to the root feed element
(<tt class="docutils literal"><span class="pre">feed</span></tt>/<tt class="docutils literal"><span class="pre">channel</span></tt>).</dd>
<dt><tt class="docutils literal"><span class="pre">SyndicationFeed.add_root_elements(self,</span> <span class="pre">handler)</span></tt></dt>
<dd>Callback to add elements inside the root feed element
(<tt class="docutils literal"><span class="pre">feed</span></tt>/<tt class="docutils literal"><span class="pre">channel</span></tt>). <tt class="docutils literal"><span class="pre">handler</span></tt> is an <a class="reference external" href="http://docs.python.org/dev/library/xml.sax.utils.html#xml.sax.saxutils.XMLGenerator">XMLGenerator</a> from Python's
built-in SAX library; you'll call methods on it to add to the XML
document in process.</dd>
<dt><tt class="docutils literal"><span class="pre">SyndicationFeed.item_attributes(self,</span> <span class="pre">item)</span></tt></dt>
<dd>Return a <tt class="docutils literal"><span class="pre">dict</span></tt> of attributes to add to each item (<tt class="docutils literal"><span class="pre">item</span></tt>/<tt class="docutils literal"><span class="pre">entry</span></tt>)
element. The argument, <tt class="docutils literal"><span class="pre">item</span></tt>, is a dictionary of all the data passed to
<tt class="docutils literal"><span class="pre">SyndicationFeed.add_item()</span></tt>.</dd>
<dt><tt class="docutils literal"><span class="pre">SyndicationFeed.add_item_elements(self,</span> <span class="pre">handler,</span> <span class="pre">item)</span></tt></dt>
<dd>Callback to add elements to each item (<tt class="docutils literal"><span class="pre">item</span></tt>/<tt class="docutils literal"><span class="pre">entry</span></tt>) element.
<tt class="docutils literal"><span class="pre">handler</span></tt> and <tt class="docutils literal"><span class="pre">item</span></tt> are as above.</dd>
</dl>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last">If you override any of these methods, be sure to call the superclass methods
since they add the required elements for each feed format.</p>
</div>
<p>For example, you might start implementing an iTunes RSS feed generator like so:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">iTunesFeed</span><span class="p">(</span><span class="n">Rss201rev2Feed</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">root_attributes</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">attrs</span> <span class="o">=</span> <span class="nb">super</span><span class="p">(</span><span class="n">iTunesFeed</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">root_attributes</span><span class="p">()</span>
        <span class="n">attrs</span><span class="p">[</span><span class="s">&#39;xmlns:itunes&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s">&#39;http://www.itunes.com/dtds/podcast-1.0.dtd&#39;</span>
        <span class="k">return</span> <span class="n">attrs</span>

    <span class="k">def</span> <span class="nf">add_root_elements</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">handler</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">iTunesFeed</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">add_root_elements</span><span class="p">(</span><span class="n">handler</span><span class="p">)</span>
        <span class="n">handler</span><span class="o">.</span><span class="n">addQuickElement</span><span class="p">(</span><span class="s">&#39;itunes:explicit&#39;</span><span class="p">,</span> <span class="s">&#39;clean&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>Obviously there's a lot more work to be done for a complete custom feed class,
but the above example should demonstrate the basic idea.</p>
</div>
</div>
</div>


          </div>         
        </div>
      </div>
      
        
          <div class="yui-b" id="sidebar">
            
      <div class="sphinxsidebar">
        <div class="sphinxsidebarwrapper">
            <h3><a href="../../contents.html">Table Of Contents</a></h3>
            <ul>
<li><a class="reference external" href="#">The syndication feed framework</a><ul>
<li><a class="reference external" href="#the-high-level-framework">The high-level framework</a><ul>
<li><a class="reference external" href="#overview">Overview</a></li>
<li><a class="reference external" href="#initialization">Initialization</a></li>
<li><a class="reference external" href="#feed-classes">Feed classes</a></li>
<li><a class="reference external" href="#a-simple-example">A simple example</a></li>
<li><a class="reference external" href="#a-complex-example">A complex example</a></li>
<li><a class="reference external" href="#specifying-the-type-of-feed">Specifying the type of feed</a></li>
<li><a class="reference external" href="#enclosures">Enclosures</a></li>
<li><a class="reference external" href="#language">Language</a></li>
<li><a class="reference external" href="#urls">URLs</a></li>
<li><a class="reference external" href="#publishing-atom-and-rss-feeds-in-tandem">Publishing Atom and RSS feeds in tandem</a></li>
<li><a class="reference external" href="#feed-class-reference">Feed class reference</a></li>
</ul>
</li>
<li><a class="reference external" href="#the-low-level-framework">The low-level framework</a><ul>
<li><a class="reference external" href="#syndicationfeed-classes"><tt class="docutils literal"><span class="pre">SyndicationFeed</span></tt> classes</a></li>
<li><a class="reference external" href="#custom-feed-generators">Custom feed generators</a></li>
</ul>
</li>
</ul>
</li>
</ul>

  <h3>Browse</h3>
  <ul>
    
      <li>Prev: <a href="sites.html">The &#8220;sites&#8221; framework</a></li>
    
    
      <li>Next: <a href="webdesign.html">django.contrib.webdesign</a></li>
    
  </ul>
  <h3>You are here:</h3>
  <ul>
      <li>
        <a href="../../index.html">Django v1.1 documentation</a>
        
          <ul><li><a href="../index.html">API Reference</a>
        
          <ul><li><a href="index.html"><tt class="docutils literal docutils literal docutils literal docutils literal docutils literal docutils literal docutils literal docutils literal docutils literal docutils literal docutils literal docutils literal docutils literal docutils literal docutils literal docutils literal docutils literal docutils literal docutils literal docutils literal docutils literal docutils literal docutils literal docutils literal docutils literal docutils literal docutils literal docutils literal"><span class="pre">contrib</span></tt> packages</a>
        
        <ul><li>The syndication feed framework</li></ul>
        </li></ul></li></ul>
      </li>
  </ul>  

            <h3>This Page</h3>
            <ul class="this-page-menu">
              <li><a href="../../_sources/ref/contrib/syndication.txt"
                     rel="nofollow">Show Source</a></li>
            </ul>
          <div id="searchbox" style="display: none">
            <h3>Quick search</h3>
              <form class="search" action="../../search.html" method="get">
                <input type="text" name="q" size="18" />
                <input type="submit" value="Go" />
                <input type="hidden" name="check_keywords" value="yes" />
                <input type="hidden" name="area" value="default" />
              </form>
              <p class="searchtip" style="font-size: 90%">
              Enter search terms or a module, class or function name.
              </p>
          </div>
          <script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
              <h3>Last update:</h3>
              <p class="topless">Feb 18, 2011</p>
          </div> 
        
      
    </div>
    
    <div id="ft">
      <div class="nav">
    &laquo; <a href="sites.html" title="The &amp;#8220;sites&amp;#8221; framework">previous</a> 
     |
    <a href="../index.html" title="API Reference" accesskey="U">up</a>
   |
    <a href="webdesign.html" title="django.contrib.webdesign">next</a> &raquo;</div>
    </div>
  </div>

      <div class="clearer"></div>
    </div>
  </body>
</html>