<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Reliably Broken &#187; urlpatterns</title>
	<atom:link href="http://reliablybroken.com/b/tag/urlpatterns/feed/" rel="self" type="application/rss+xml" />
	<link>http://reliablybroken.com/b</link>
	<description>It&#039;s a blog: let&#039;s do funch!</description>
	<lastBuildDate>Sat, 04 Sep 2010 21:22:45 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>reverse() chicken and egg problem</title>
		<link>http://reliablybroken.com/b/2009/03/reverse-chicken-and-egg-problem/</link>
		<comments>http://reliablybroken.com/b/2009/03/reverse-chicken-and-egg-problem/#comments</comments>
		<pubDate>Mon, 30 Mar 2009 14:34:07 +0000</pubDate>
		<dc:creator>david</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[urlpatterns]]></category>

		<guid isPermaLink="false">http://reliablybroken.com/b/?p=111</guid>
		<description><![CDATA[I wound up in a chicken and egg situation today using Django&#8217;s syndication
framework and the reverse helper. The problem was
that immediately after starting the development server, Django would throw a
NoReverseMatch exception on the first client visit, followed by AttributeError
on all subsequent visits.

It all started so innocently&#8230; I had wanted a set of urls for my [...]]]></description>
			<content:encoded><![CDATA[<p>I wound up in a chicken and egg situation today using <a href="http://docs.djangoproject.com/en/dev/ref/contrib/syndication/">Django&#8217;s syndication
framework</a> and the <a href="http://docs.djangoproject.com/en/dev/topics/http/urls/#reverse"><code>reverse</code></a> helper. The problem was
that immediately after starting the development server, Django would throw a
<code>NoReverseMatch</code> exception on the first client visit, followed by <code>AttributeError</code>
on all subsequent visits.</p>

<p>It all started so innocently&#8230; I had wanted a set of urls for my application
like this:</p>

<ul>
<li><a href="">http://example.com/a/</a>         # List view of arrivals</li>
<li><a href="">http://example.com/d/</a>         # List view of departures</li>
<li><a href="">http://example.com/a/feed/</a>    # Syndication feed for arrivals</li>
<li><a href="">http://example.com/d/feed/</a>    # Syndication feed for departures</li>
</ul>

<p>So I put the following in the application&#8217;s <code>urls.py</code>:</p>

<pre><code># myapp/urls.py
from django.conf.urls.defaults import *
from views import arrivals_list, departures_list
from feeds import LatestArrivals, LatestDepartures


feed_dict = {'a': LatestArrivals, 'd': LatestDepartures}


urlpatterns = patterns('',
    (r'^a/$', arrivals_list, {}, 'arrivals'),
    (r'^d/$', departures_list, {}, 'departures'),
    (r'^(?P&lt;url&gt;[ad])/feed/$', 'django.contrib.syndication.views.feed', {'feed_dict':feed_dict}),
)
</code></pre>

<p>That covers my URL wishes, and because I have named the URL patterns I
can use that name in templates with the <a href="http://docs.djangoproject.com/en/dev/ref/templates/builtins/#url"><code>{% url %} template tag</code></a>
and in Python code using the <code>reverse</code> helper.</p>

<p>So naturally the feed classes in <code>feeds.py</code> look like this:</p>

<pre><code># myapp/feeds.py
from django.contrib.syndication.feeds import Feed
from django.core.urlresolvers import reverse
from django.utils.feedgenerator import Atom1Feed
from models import Tx


class LatestArrivals(Feed):
    """Produces an Atom feed of recent arrival tickets."""
    feed_type = Atom1Feed
    title = 'Arrivals'
    link = reverse('arrivals')
    subtitle = 'Most recent arrivals'

    def items(self):
        return Tx.objects.arrivals()[:10]


class LatestDepartures(Feed):
    """Produces an Atom feed of recent departure tickets."""
    feed_type = Atom1Feed
    title = 'Departures'
    link = reverse('departures')
    subtitle = 'Most recent departures'

    def items(self):
        return Tx.objects.departures()[:10]
</code></pre>

<p>Note I used <code>reverse</code> on the link attribute of each class so that I can
define the URL in one place, the <code>urls.py</code> module, and a change there will
be reflected in the feed&#8217;s link too.</p>

<p>But this doesn&#8217;t work! When Django imports my <code>urls.py</code> module, it imports
<code>LatestDepartures</code> and <code>LatestArrivals</code>, and they in turn use <code>reverse</code> to
find the named URL patterns &#8211; except those names aren&#8217;t defined until after
<code>urlpatterns</code> has been defined in <code>urls.py</code> <em>so Django throws an exception
and never imports my <code>urls.py</code> module</em>.</p>

<p>You could work around this either by defining your syndication feeds in an
entirely different <code>urls.py</code> module. But you can also split up <code>urlpatterns</code>
within the same module and import the feed classes after their named URL
patterns have been defined.</p>

<p>Here&#8217;s the working <code>urls.py</code> module:</p>

<pre><code>from django.conf.urls.defaults import *
from views import arrivals_list, departures_list


urlpatterns = patterns('',
    (r'^a/$', arrivals_list, {}, 'arrivals'),
    (r'^d/$', departures_list, {}, 'departures'),
)


from feeds import LatestArrivals, LatestDepartures
feed_dict = {'a': LatestArrivals, 'd': LatestDepartures}


urlpatterns += patterns('',
    (r'^(?P&lt;url&gt;[ad])/feed/$', 'django.contrib.syndication.views.feed', {'feed_dict':feed_dict}),
)
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://reliablybroken.com/b/2009/03/reverse-chicken-and-egg-problem/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
