<?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>Mad Python &#187; Web Development</title>
	<atom:link href="http://blog.madpython.com/category/tech/web-development/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.madpython.com</link>
	<description>Watch out.. he's angry</description>
	<lastBuildDate>Thu, 04 Nov 2010 14:19:16 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Django Context Processors Best Practice</title>
		<link>http://blog.madpython.com/2010/04/07/django-context-processors-best-practice/</link>
		<comments>http://blog.madpython.com/2010/04/07/django-context-processors-best-practice/#comments</comments>
		<pubDate>Thu, 08 Apr 2010 00:59:39 +0000</pubDate>
		<dc:creator>Xavier</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[tech]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Web Frameworks]]></category>
		<category><![CDATA[convention]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://blog.madpython.com/?p=61</guid>
		<description><![CDATA[In this post, i&#8217;ll show you a simple trick to ensure your Django context-processors don&#8217;t break when Django 1.2 (and possibly future releases as well) is released. If you&#8217;re not familiar with the concept of context-processors, I&#8217;ll also explain what &#8230; <a href="http://blog.madpython.com/2010/04/07/django-context-processors-best-practice/">Continue reading <span class="meta-nav">&#8594;</span></a>
No related posts.]]></description>
			<content:encoded><![CDATA[<p>In this post, i&#8217;ll show you a simple trick to ensure your Django context-processors don&#8217;t break when Django 1.2 (and possibly future releases as well) is released.</p>
<p>If you&#8217;re not familiar with the concept of context-processors, I&#8217;ll also explain what those are and how they work, so don&#8217;t panic. Finally, i&#8217;ll also spend a minute explaining why I consider this to be best-practice.</p>
<h2>What are template context processors?</h2>
<p>Django&#8217;s context processors are a facility that allows you to provide data and callbacks to your templates.</p>
<p>You can do so in one of two ways:</p>
<ol>
<li><strong>On an individual request basis</strong>: by passing a custom <code>Context</code> value to your <code>render_to_response()</code> call</li>
<li><strong>Globally</strong>: by creating a <em>context processor method</em> that accepts a <code>HttpRequest</code> object as input, and returns a payload or callback, <strong>then</strong> registering the context processor in your <code>settings.py</code>, <strong>then</strong> providing your <code>render_to_response()</code> call with the built-in <code>RequestContext</code> attribute instead of your own (you can always extend <code>RequestContext</code> to add more data on an individual request basis of course).</li>
</ol>
<p>If that approach for passing data to templates sounded absurd and obfuscated to you, you&#8217;re not alone. The complexity involved in such a simple operation is unwarranted and counter-productive, but every system has its shortcomings.</p>
<h2>The Issue</h2>
<p>If you follow the <a href="http://docs.djangoproject.com/en/dev/ref/templates/api/#id1" onclick="return TrackClick('http%3A%2F%2Fdocs.djangoproject.com%2Fen%2Fdev%2Fref%2Ftemplates%2Fapi%2F%23id1','Django+documentation')">Django documentation</a> or <a href="http://djangobook.com/en/2.0/" onclick="return TrackClick('http%3A%2F%2Fdjangobook.com%2Fen%2F2.0%2F','The+Django+Book')">The Django Book</a>&#8216;s approach to configuring your own custom context-processors, you&#8217;ll notice that you are encouraged to add to your settings.py a hardcoded list of built-in context processors. If you follow that approach, your context-processors declaration will look like this:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">TEMPLATE_CONTEXT_PROCESSORS = <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;django.contrib.auth.context_processors.auth&quot;</span>,
<span style="color: #483d8b;">&quot;django.core.context_processors.debug&quot;</span>,
<span style="color: #483d8b;">&quot;django.core.context_processors.i18n&quot;</span>,
<span style="color: #483d8b;">&quot;django.core.context_processors.media&quot;</span>,
<span style="color: #483d8b;">&quot;django.contrib.messages.context_processors.messages&quot;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>But if you pay close attention to <a href="http://docs.djangoproject.com/en/dev/ref/settings/#template-context-processors" onclick="return TrackClick('http%3A%2F%2Fdocs.djangoproject.com%2Fen%2Fdev%2Fref%2Fsettings%2F%23template-context-processors','the+development+version%22s+documentation')">the development version&#8217;s documentation</a>, you&#8217;ll notice a couple of interesting notes:</p>
<blockquote><p><strong>Changed in Django Development version: </strong>&#8220;django.contrib.messages.context_processors.messages&#8221; was added to the default. For more information, see the messages documentation.<br />
<strong>Changed in Django Development version</strong>: The auth context processor was moved in this release from its old location django.core.context_processors.auth to django.contrib.auth.context_processors.auth.</p></blockquote>
<p>This is a red flag! The Django dev team would like you to use hardcoded values that reference to classes that will no longer exist once the next version is released, and that omit new processors that you are likely to require.</p>
<h2>The Solution</h2>
<p>Obviously Django has access to its own default settings, so there must be a way to simply <em>extend</em> the defaults instead of overriding them with hardcoded values. You just need to dig around a bit in <a href="http://code.djangoproject.com/browser/django/trunk/django/conf/global_settings.py#L186" onclick="return TrackClick('http%3A%2F%2Fcode.djangoproject.com%2Fbrowser%2Fdjango%2Ftrunk%2Fdjango%2Fconf%2Fglobal_settings.py%23L186','the+Django+source+code')">the Django source code</a> to find exactly how. I&#8217;ll save you some digging:</p>
<p>Add this at the top of your settings.py file:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> django.<span style="color: black;">conf</span>.<span style="color: black;">global_settings</span> <span style="color: #ff7700;font-weight:bold;">as</span> DEFAULT_SETTINGS</pre></div></div>

<p>Then extend the default context processors:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">TEMPLATE_CONTEXT_PROCESSORS = DEFAULT_SETTINGS.<span style="color: black;">TEMPLATE_CONTEXT_PROCESSORS</span> + <span style="color: black;">&#40;</span>
<span style="color: #483d8b;">&quot;myapp.context_processors.example&quot;</span>,
<span style="color: #483d8b;">&quot;myapp.context_processors.other_example&quot;</span>,
<span style="color: #808080; font-style: italic;"># etc...</span>
<span style="color: black;">&#41;</span></pre></div></div>

<h2>Why is this a best-practice approach?</h2>
<p>In software-engineering, you want to ensure maximum (reasonable) future interoperability of all your components, and there is really no component as important as your actual development framework, Django or otherwise.</p>
<p>Using hardcoded values that are already defined somewhere not only breaks <acronym title="Don't Repeat Yourself">DRY</acronym>, but it also introduces possible breakage on framework upgrades. I know you are diligent and always read the release notes before upgrading critical components, and I know you use a staging environment to test those changes, but by actively looking out for this kind of traps, you have just saved yourself some debugging time and some head-scratching.</p>
<p>Happy coding!</p>
<p><a class="a2a_button_reddit" href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fblog.madpython.com%2F2010%2F04%2F07%2Fdjango-context-processors-best-practice%2F&amp;linkname=Django%20Context%20Processors%20Best%20Practice" title="Reddit" rel="nofollow" target="_blank"><img src="http://blog.madpython.com/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a><a class="a2a_button_delicious" href="http://www.addtoany.com/add_to/delicious?linkurl=http%3A%2F%2Fblog.madpython.com%2F2010%2F04%2F07%2Fdjango-context-processors-best-practice%2F&amp;linkname=Django%20Context%20Processors%20Best%20Practice" title="Delicious" rel="nofollow" target="_blank"><img src="http://blog.madpython.com/wp-content/plugins/add-to-any/icons/delicious.png" width="16" height="16" alt="Delicious"/></a><a class="a2a_button_google_bookmarks" href="http://www.addtoany.com/add_to/google_bookmarks?linkurl=http%3A%2F%2Fblog.madpython.com%2F2010%2F04%2F07%2Fdjango-context-processors-best-practice%2F&amp;linkname=Django%20Context%20Processors%20Best%20Practice" title="Google Bookmarks" rel="nofollow" target="_blank"><img src="http://blog.madpython.com/wp-content/plugins/add-to-any/icons/google.png" width="16" height="16" alt="Google Bookmarks"/></a><a class="a2a_button_facebook" href="http://www.addtoany.com/add_to/facebook?linkurl=http%3A%2F%2Fblog.madpython.com%2F2010%2F04%2F07%2Fdjango-context-processors-best-practice%2F&amp;linkname=Django%20Context%20Processors%20Best%20Practice" title="Facebook" rel="nofollow" target="_blank"><img src="http://blog.madpython.com/wp-content/plugins/add-to-any/icons/facebook.png" width="16" height="16" alt="Facebook"/></a><a class="a2a_button_stumbleupon" href="http://www.addtoany.com/add_to/stumbleupon?linkurl=http%3A%2F%2Fblog.madpython.com%2F2010%2F04%2F07%2Fdjango-context-processors-best-practice%2F&amp;linkname=Django%20Context%20Processors%20Best%20Practice" title="StumbleUpon" rel="nofollow" target="_blank"><img src="http://blog.madpython.com/wp-content/plugins/add-to-any/icons/stumbleupon.png" width="16" height="16" alt="StumbleUpon"/></a><a class="a2a_button_linkedin" href="http://www.addtoany.com/add_to/linkedin?linkurl=http%3A%2F%2Fblog.madpython.com%2F2010%2F04%2F07%2Fdjango-context-processors-best-practice%2F&amp;linkname=Django%20Context%20Processors%20Best%20Practice" title="LinkedIn" rel="nofollow" target="_blank"><img src="http://blog.madpython.com/wp-content/plugins/add-to-any/icons/linkedin.png" width="16" height="16" alt="LinkedIn"/></a><a class="a2a_button_twitter" href="http://www.addtoany.com/add_to/twitter?linkurl=http%3A%2F%2Fblog.madpython.com%2F2010%2F04%2F07%2Fdjango-context-processors-best-practice%2F&amp;linkname=Django%20Context%20Processors%20Best%20Practice" title="Twitter" rel="nofollow" target="_blank"><img src="http://blog.madpython.com/wp-content/plugins/add-to-any/icons/twitter.png" width="16" height="16" alt="Twitter"/></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.madpython.com%2F2010%2F04%2F07%2Fdjango-context-processors-best-practice%2F&amp;title=Django%20Context%20Processors%20Best%20Practice" id="wpa2a_2">Share</a></p><p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.madpython.com/2010/04/07/django-context-processors-best-practice/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

