<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Code Spatter</title>
	
	<link>http://codespatter.com</link>
	<description />
	<lastBuildDate>Fri, 10 Jul 2009 16:35:54 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/CodeSpatter" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
		<title>Python Projects in Users’ Home Directories with wsgi</title>
		<link>http://feedproxy.google.com/~r/CodeSpatter/~3/eZ9a0rCJ4Ow/</link>
		<comments>http://codespatter.com/2009/07/08/python-projects-in-users-home-directories-with-wsgi/#comments</comments>
		<pubDate>Wed, 08 Jul 2009 14:27:12 +0000</pubDate>
		<dc:creator>Greg Allard</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Server Administration]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[wsgi]]></category>

		<guid isPermaLink="false">http://codespatter.com/?p=484</guid>
		<description><![CDATA[Letting users put static files and php files in a public_html folder in their home directory has been a common convention for some time. I created a way for users to have a public_python folder that will allow for python projects.
In the apache configuration files I created some regular expression patterns that will look for [...]


Related posts:<ol><li><a href='http://codespatter.com/2009/04/10/how-to-add-locations-to-python-path-for-reusable-django-apps/' rel='bookmark' title='Permanent Link: How to Add Locations to Python Path for Reusable Django Apps'>How to Add Locations to Python Path for Reusable Django Apps</a> <small>In my 
pre</small></li><li><a href='http://codespatter.com/2008/10/15/setting-up-apache2-mod_python-mysql-and-django-on-debian-lenny-or-ubuntu-hardy-heron/' rel='bookmark' title='Permanent Link: Setting up Apache2, mod_python, MySQL, and Django on Debian Lenny or Ubuntu Hardy Heron'>Setting up Apache2, mod_python, MySQL, and Django on Debian Lenny or Ubuntu Hardy Heron</a> <small>Both Debia</small></li><li><a href='http://codespatter.com/2009/04/01/getting-basecamp-api-working-with-python/' rel='bookmark' title='Permanent Link: Getting Basecamp API Working with Python'>Getting Basecamp API Working with Python</a> <small>I found 
o</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>Letting users put static files and php files in a public_html folder in their home directory has been a common convention for some time. I created a way for users to have a public_python folder that will allow for python projects.</p>
<p>In the apache configuration files I created some regular expression patterns that will look for a wsgi file based on the url requested. To serve this url: <strong>http://domain/~user/p/myproject</strong>, the server will look for this wsgi file: <strong>/home/user/public_python/myproject/deploy/myproject.wsgi</strong></p>
<p>It is set up to run wsgi in daemon mode so that each user can touch their own wsgi file to restart their project instead of needing to reload the apache config and inconvenience everyone.</p>
<p>This is the code I added to the apache configuration (in a virtual host, other configs might be different):</p>

<div class="wp_syntax"><div class="code"><pre class="apache"><span style="color: #00007f;">RewriteEngine</span> <span style="color: #0000ff;">On</span>
<span style="color: #00007f;">RewriteCond</span> %<span style="color: #66cc66;">&#123;</span>REQUEST_URI<span style="color: #66cc66;">&#125;</span> ^/~<span style="color: #66cc66;">&#40;</span>\w+<span style="color: #66cc66;">&#41;</span>/p/<span style="color: #66cc66;">&#40;</span>\w+<span style="color: #66cc66;">&#41;</span>/<span style="color: #66cc66;">&#40;</span>.*<span style="color: #66cc66;">&#41;</span>
<span style="color: #00007f;">RewriteRule</span> . - <span style="color: #66cc66;">&#91;</span>E=python_project_name:%<span style="color: #ff0000;">2</span><span style="color: #66cc66;">&#93;</span>
&nbsp;
WSGIScriptAliasMatch ^/~<span style="color: #66cc66;">&#40;</span>\w+<span style="color: #66cc66;">&#41;</span>/p/<span style="color: #66cc66;">&#40;</span>\w+<span style="color: #66cc66;">&#41;</span>  /home/$<span style="color: #ff0000;">1</span>/public_python/$<span style="color: #ff0000;">2</span>/deploy/$<span style="color: #ff0000;">2</span>.wsgi
WSGIDaemonProcess wsgi_processes.%<span style="color: #66cc66;">&#123;</span>ENV:python_project_name<span style="color: #66cc66;">&#125;</span>
processes=<span style="color: #ff0000;">2</span> threads=<span style="color: #ff0000;">15</span>
WSGIProcessGroup wsgi_processes.%<span style="color: #66cc66;">&#123;</span>ENV:python_project_name<span style="color: #66cc66;">&#125;</span>
&nbsp;
<span style="color: #00007f;">AliasMatch</span> ^/~<span style="color: #66cc66;">&#40;</span>\w+<span style="color: #66cc66;">&#41;</span>/p/<span style="color: #66cc66;">&#40;</span>\w+<span style="color: #66cc66;">&#41;</span>/<span style="color: #00007f;">files</span><span style="color: #66cc66;">&#40;</span>.*<span style="color: #66cc66;">&#41;</span> /home/$<span style="color: #ff0000;">1</span>/public_python/$<span style="color: #ff0000;">2</span>/<span style="color: #00007f;">files</span>$<span style="color: #ff0000;">3</span>
&lt;LocationMatch ^/~<span style="color: #66cc66;">&#40;</span>\w+<span style="color: #66cc66;">&#41;</span>/p/<span style="color: #66cc66;">&#40;</span>\w+<span style="color: #66cc66;">&#41;</span>/<span style="color: #00007f;">files</span><span style="color: #66cc66;">&#40;</span>.*<span style="color: #66cc66;">&#41;</span>&gt;
       <span style="color: #00007f;">SetHandler</span> <span style="color: #0000ff;">none</span>
&lt;/LocationMatch&gt;
&nbsp;
<span style="color: #00007f;">AliasMatch</span> ^/~<span style="color: #66cc66;">&#40;</span>\w+<span style="color: #66cc66;">&#41;</span>/p/<span style="color: #66cc66;">&#40;</span>\w+<span style="color: #66cc66;">&#41;</span>/media<span style="color: #66cc66;">&#40;</span>.*<span style="color: #66cc66;">&#41;</span> /home/$<span style="color: #ff0000;">1</span>/public_python/$<span style="color: #ff0000;">2</span>/media$<span style="color: #ff0000;">3</span>
&lt;LocationMatch ^/~<span style="color: #66cc66;">&#40;</span>\w+<span style="color: #66cc66;">&#41;</span>/p/<span style="color: #66cc66;">&#40;</span>\w+<span style="color: #66cc66;">&#41;</span>/media<span style="color: #66cc66;">&#40;</span>.*<span style="color: #66cc66;">&#41;</span>&gt;
       <span style="color: #00007f;">SetHandler</span> <span style="color: #0000ff;">none</span>
&lt;/LocationMatch&gt;</pre></div></div>

<p>This will also serve two directories statically for images, css, and javascript. For one of them, I always make a symbolic link to the django admin media and tell my settings file to use that.</p>

<div class="wp_syntax"><div class="code"><pre class="bash"><span style="color: #c20cb9; font-weight: bold;">ln</span> -s <span style="color: #000000; font-weight: bold;">/</span>path<span style="color: #000000; font-weight: bold;">/</span>to<span style="color: #000000; font-weight: bold;">/</span>django<span style="color: #000000; font-weight: bold;">/</span>contrib<span style="color: #000000; font-weight: bold;">/</span>admin<span style="color: #000000; font-weight: bold;">/</span>media media</pre></div></div>

<h3>To use this for a django project</h3>
<p>This is a sample wsgi file to use for a django project. Username and project_name will need to be replaced. I&#8217;m also adding an apps folder to the path following 
<a  href="http://codespatter.com/2009/01/15/how-to-write-reusable-apps-for-pinax-and-django/">the style I mention in my reusable apps post</a>.</p>

<div class="wp_syntax"><div class="code"><pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
&nbsp;
<span style="color: #dc143c;">sys</span>.<span style="color: black;">path</span> = <span style="color: black;">&#91;</span><span style="color: #483d8b;">'/home/username/public_python/'</span>, <span style="color: #483d8b;">'/home/username/public_python/project_name/apps'</span><span style="color: black;">&#93;</span> + <span style="color: #dc143c;">sys</span>.<span style="color: black;">path</span>
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">core</span>.<span style="color: black;">handlers</span>.<span style="color: black;">wsgi</span> <span style="color: #ff7700;font-weight:bold;">import</span> WSGIHandler
&nbsp;
<span style="color: #dc143c;">os</span>.<span style="color: black;">environ</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'DJANGO_SETTINGS_MODULE'</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">'project_name.settings'</span>
application = WSGIHandler<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>I&#8217;ve been using this for a couple weeks and it&#8217;s working great for me. If you use it, I&#8217;d like to know how it works out for you. Let me know in the comments.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fcodespatter.com%2F2009%2F07%2F08%2Fpython-projects-in-users-home-directories-with-wsgi%2F';
  addthis_title  = 'Python+Projects+in+Users%26%238217%3B+Home+Directories+with+wsgi';
  addthis_pub    = 'gallard';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>


<p>Related posts:</p><ol><li><a href='http://codespatter.com/2009/04/10/how-to-add-locations-to-python-path-for-reusable-django-apps/' rel='bookmark' title='Permanent Link: How to Add Locations to Python Path for Reusable Django Apps'>How to Add Locations to Python Path for Reusable Django Apps</a> <small>In my 
pre</small></li><li><a href='http://codespatter.com/2008/10/15/setting-up-apache2-mod_python-mysql-and-django-on-debian-lenny-or-ubuntu-hardy-heron/' rel='bookmark' title='Permanent Link: Setting up Apache2, mod_python, MySQL, and Django on Debian Lenny or Ubuntu Hardy Heron'>Setting up Apache2, mod_python, MySQL, and Django on Debian Lenny or Ubuntu Hardy Heron</a> <small>Both Debia</small></li><li><a href='http://codespatter.com/2009/04/01/getting-basecamp-api-working-with-python/' rel='bookmark' title='Permanent Link: Getting Basecamp API Working with Python'>Getting Basecamp API Working with Python</a> <small>I found 
o</small></li></ol><img src="http://feeds.feedburner.com/~r/CodeSpatter/~4/eZ9a0rCJ4Ow" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://codespatter.com/2009/07/08/python-projects-in-users-home-directories-with-wsgi/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://codespatter.com/2009/07/08/python-projects-in-users-home-directories-with-wsgi/</feedburner:origLink></item>
		<item>
		<title>A Django Model Manager for Soft Deleting Records and How to Customize the Django Admin</title>
		<link>http://feedproxy.google.com/~r/CodeSpatter/~3/Lk6HVaUDrRs/</link>
		<comments>http://codespatter.com/2009/07/01/django-model-manager-soft-delete-how-to-customize-admin/#comments</comments>
		<pubDate>Wed, 01 Jul 2009 14:37:45 +0000</pubDate>
		<dc:creator>Greg Allard</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://codespatter.com/?p=467</guid>
		<description><![CDATA[Sometimes it&#8217;s good to hide things instead of deleting them. Users may accidentally delete something and this way there will be an extra backup. The way I&#8217;ve been doing this is I set a flag in the database, deleted = 1. I wrote this code to automatically hide records from django if they are flagged.

Django [...]


Related posts:<ol><li><a href='http://codespatter.com/2009/01/22/how-to-write-django-template-tags/' rel='bookmark' title='Permanent Link: How to Write Django Template Tags'>How to Write Django Template Tags</a> <small>Template t</small></li><li><a href='http://codespatter.com/2009/01/15/how-to-write-reusable-apps-for-pinax-and-django/' rel='bookmark' title='Permanent Link: How to Write Reusable Apps for Pinax and Django'>How to Write Reusable Apps for Pinax and Django</a> <small>
Pinax is </small></li><li><a href='http://codespatter.com/2009/01/05/django-settings-site-domain-examplecom/' rel='bookmark' title='Permanent Link: Django Settings Site Domain example.com'>Django Settings Site Domain example.com</a> <small>It took me</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>Sometimes it&#8217;s good to hide things instead of deleting them. Users may accidentally delete something and this way there will be an extra backup. The way I&#8217;ve been doing this is I set a flag in the database, <strong>deleted = 1</strong>. I wrote this code to automatically hide records from django if they are flagged.</p>
<p>
<a  href="http://docs.djangoproject.com/en/1.0/topics/db/managers/" onclick="javascript:pageTracker._trackPageview('/external/docs.djangoproject.com/en/1.0/topics/db/managers/');" >Django allows developers to create model managers</a> that can change how the models work. The code below was written to return only the undeleted records by default. I added two new methods in case I need to get some of the deleted records.</p>

<div class="wp_syntax"><div class="code"><pre class="python"><span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">db</span> <span style="color: #ff7700;font-weight:bold;">import</span> models
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> SoftDeleteManager<span style="color: black;">&#40;</span>models.<span style="color: black;">Manager</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">''</span><span style="color: #483d8b;">' Use this manager to get objects that have a deleted field '</span><span style="color: #483d8b;">''</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> get_query_set<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">super</span><span style="color: black;">&#40;</span>SoftDeleteManager, <span style="color: #008000;">self</span><span style="color: black;">&#41;</span>.<span style="color: black;">get_query_set</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: #008000;">filter</span><span style="color: black;">&#40;</span>deleted=<span style="color: #008000;">False</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> all_with_deleted<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">super</span><span style="color: black;">&#40;</span>SoftDeleteManager, <span style="color: #008000;">self</span><span style="color: black;">&#41;</span>.<span style="color: black;">get_query_set</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> deleted_set<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">super</span><span style="color: black;">&#40;</span>SoftDeleteManager, <span style="color: #008000;">self</span><span style="color: black;">&#41;</span>.<span style="color: black;">get_query_set</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: #008000;">filter</span><span style="color: black;">&#40;</span>deleted=<span style="color: #008000;">True</span><span style="color: black;">&#41;</span></pre></div></div>

<p>This is usable by many models by adding this line to the model (it needs a deleted field) <strong>objects = SoftDeleteManager()</strong></p>
<p>This will hide deleted records from django completely, even the django admin and even if you specify the id directly. The only way to find it is through the database itself or an app like phpMyAdmin. This might be good for some cases, but I went a step further to make it possible to undelete things in the django admin.</p>
<p>
<a  href="http://docs.djangoproject.com/en/1.0/ref/contrib/admin/" onclick="javascript:pageTracker._trackPageview('/external/docs.djangoproject.com/en/1.0/ref/contrib/admin/');" >Django has a lot of customization options for the admin interface</a> (
<a  href="http://www.ibm.com/developerworks/opensource/library/os-django-admin/" onclick="javascript:pageTracker._trackPageview('/external/www.ibm.com/developerworks/opensource/library/os-django-admin/');" >this article has some more info on customizing the django admin</a>). I wanted the queryset to be different in the admin, so I created a ModelAdmin to customize what is displayed. First I set it up to show a few more columns than just __unicode__ on the list of items and added a filter to help easily separate the deleted from the active.</p>

<div class="wp_syntax"><div class="code"><pre class="python"><span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">contrib</span> <span style="color: #ff7700;font-weight:bold;">import</span> admin
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> SoftDeleteAdmin<span style="color: black;">&#40;</span>admin.<span style="color: black;">ModelAdmin</span><span style="color: black;">&#41;</span>:
    list_display = <span style="color: black;">&#40;</span><span style="color: #483d8b;">'id'</span>, <span style="color: #483d8b;">'__unicode__'</span>, <span style="color: #483d8b;">'deleted'</span>,<span style="color: black;">&#41;</span>
    list_filter = <span style="color: black;">&#40;</span><span style="color: #483d8b;">'deleted'</span>,<span style="color: black;">&#41;</span>
<span style="color: #808080; font-style: italic;"># this requires __unicode__ to be defined in your model</span></pre></div></div>

<p>This can also be used by many models by adding this at the bottom of the models.py file:</p>

<div class="wp_syntax"><div class="code"><pre class="python"><span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">contrib</span> <span style="color: #ff7700;font-weight:bold;">import</span> admin
<span style="color: #ff7700;font-weight:bold;">from</span> wherever <span style="color: #ff7700;font-weight:bold;">import</span> SoftDeleteAdmin
admin.<span style="color: #dc143c;">site</span>.<span style="color: black;">register</span><span style="color: black;">&#40;</span>MyModel, SoftDeleteAdmin<span style="color: black;">&#41;</span></pre></div></div>

<p>The next thing to do was override the queryset method in the default ModelAdmin. I copied the code from the django source and changed it from using get_query_set to make it use <strong>all_with_deleted()</strong> which was a method added to the ModelManager. The following code was <strong>added to SoftDeleteAdmin</strong>.</p>

<div class="wp_syntax"><div class="code"><pre class="python">    <span style="color: #ff7700;font-weight:bold;">def</span> queryset<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, request<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot; Returns a QuerySet of all model instances that can be edited by the
        admin site. This is used by changelist_view. &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        <span style="color: #808080; font-style: italic;"># Default: qs = self.model._default_manager.get_query_set()</span>
        qs = <span style="color: #008000;">self</span>.<span style="color: black;">model</span>._default_manager.<span style="color: black;">all_with_deleted</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #808080; font-style: italic;"># TODO: this should be handled by some parameter to the ChangeList.</span>
        ordering = <span style="color: #008000;">self</span>.<span style="color: black;">ordering</span> <span style="color: #ff7700;font-weight:bold;">or</span> <span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># otherwise we might try to *None, which is bad ;)</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> ordering:
            qs = qs.<span style="color: black;">order_by</span><span style="color: black;">&#40;</span><span style="color: #66cc66;">*</span>ordering<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> qs</pre></div></div>

<p>The list of objects in the admin will start to look like this.</p>
<div id="attachment_474" class="wp-caption aligncenter" style="width: 458px"><img src="http://codespatter.com/wp-content/uploads/2009/07/admin-deleted.gif" alt="A screenshot of the django admin interface" title="admin-deleted" width="448" height="237" class="size-full wp-image-474" /><p class="wp-caption-text">A screenshot of the django admin interface</p></div>
<p>They are showing up there now, but won&#8217;t be editable yet because django is using get_query_set to find them. There are two methods I <strong>added to SoftDeleteManager</strong> so that django can find the deleted records.</p>

<div class="wp_syntax"><div class="code"><pre class="python">    <span style="color: #ff7700;font-weight:bold;">def</span> get<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #66cc66;">*</span>args, <span style="color: #66cc66;">**</span>kwargs<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">''</span><span style="color: #483d8b;">' if a specific record was requested, return it even if it'</span>s deleted <span style="color: #483d8b;">''</span><span style="color: #483d8b;">'
        return self.all_with_deleted().get(*args, **kwargs)
&nbsp;
    def filter(self, *args, **kwargs):
        '</span><span style="color: #483d8b;">''</span> <span style="color: #ff7700;font-weight:bold;">if</span> pk was specified as a kwarg, <span style="color: #ff7700;font-weight:bold;">return</span> even <span style="color: #ff7700;font-weight:bold;">if</span> it<span style="color: #483d8b;">'s deleted '</span><span style="color: #483d8b;">''</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #483d8b;">'pk'</span> <span style="color: #ff7700;font-weight:bold;">in</span> kwargs:
            <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">all_with_deleted</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: #008000;">filter</span><span style="color: black;">&#40;</span><span style="color: #66cc66;">*</span>args, <span style="color: #66cc66;">**</span>kwargs<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">get_query_set</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: #008000;">filter</span><span style="color: black;">&#40;</span><span style="color: #66cc66;">*</span>args, <span style="color: #66cc66;">**</span>kwargs<span style="color: black;">&#41;</span></pre></div></div>

<p>With those updated methods, django will be able to find records if the primary key is specified, not only in the admin section, but everywhere in the project. Lists of objects will only return deleted records in the admin section still.</p>
<p>This code can be applied to a bunch of models and easily allow soft deletes of records to prevent loss of accidentally deleted objects.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fcodespatter.com%2F2009%2F07%2F01%2Fdjango-model-manager-soft-delete-how-to-customize-admin%2F';
  addthis_title  = 'A+Django+Model+Manager+for+Soft+Deleting+Records+and+How+to+Customize+the+Django+Admin';
  addthis_pub    = 'gallard';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>


<p>Related posts:</p><ol><li><a href='http://codespatter.com/2009/01/22/how-to-write-django-template-tags/' rel='bookmark' title='Permanent Link: How to Write Django Template Tags'>How to Write Django Template Tags</a> <small>Template t</small></li><li><a href='http://codespatter.com/2009/01/15/how-to-write-reusable-apps-for-pinax-and-django/' rel='bookmark' title='Permanent Link: How to Write Reusable Apps for Pinax and Django'>How to Write Reusable Apps for Pinax and Django</a> <small>
Pinax is </small></li><li><a href='http://codespatter.com/2009/01/05/django-settings-site-domain-examplecom/' rel='bookmark' title='Permanent Link: Django Settings Site Domain example.com'>Django Settings Site Domain example.com</a> <small>It took me</small></li></ol><img src="http://feeds.feedburner.com/~r/CodeSpatter/~4/Lk6HVaUDrRs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://codespatter.com/2009/07/01/django-model-manager-soft-delete-how-to-customize-admin/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://codespatter.com/2009/07/01/django-model-manager-soft-delete-how-to-customize-admin/</feedburner:origLink></item>
		<item>
		<title>Django Single Sign On or a Solution to Multi-domain Cookies</title>
		<link>http://feedproxy.google.com/~r/CodeSpatter/~3/8RFWvGYn2ck/</link>
		<comments>http://codespatter.com/2009/06/18/django-single-sign-on-or-a-solution-to-multi-domain-cookies/#comments</comments>
		<pubDate>Thu, 18 Jun 2009 19:48:52 +0000</pubDate>
		<dc:creator>Greg Allard</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Authorization]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[SSO]]></category>

		<guid isPermaLink="false">http://codespatter.com/?p=435</guid>
		<description><![CDATA[I&#8217;ve been working on a project for a while and it has recently started to expand to an additional domain name. The domains will be using the same user base and I want to make it simple for users to be logged in at both applications. With a little research I dug up a few [...]


Related posts:<ol><li><a href='http://codespatter.com/2009/01/05/django-settings-site-domain-examplecom/' rel='bookmark' title='Permanent Link: Django Settings Site Domain example.com'>Django Settings Site Domain example.com</a> <small>It took me</small></li><li><a href='http://codespatter.com/2007/08/10/openid-enabled/' rel='bookmark' title='Permanent Link: OpenID Enabled'>OpenID Enabled</a> <small>If you hav</small></li><li><a href='http://codespatter.com/2009/07/08/python-projects-in-users-home-directories-with-wsgi/' rel='bookmark' title='Permanent Link: Python Projects in Users&#8217; Home Directories with wsgi'>Python Projects in Users&#8217; Home Directories with wsgi</a> <small>Letting us</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been working on a project for a while and it has recently started to expand to an additional domain name. The domains will be using the same user base and I want to make it simple for users to be logged in at both applications. With a little research I dug up a few options I could go with. There is a redirect option, a javascript option, or a single sign on option.</p>
<p>With the redirect option I could redirect users to the main domain, check for cookies, and redirect them back so that they could get new cookies for the additional domain. The downside to this method is it will increase traffic for every pageload from a new visitor even if they will never need to log in. And since the sites this was for will have pages being viewed many more times than there will be logged in users, it wasn&#8217;t worth all of the extra traffic. It might be possible to minimize this traffic by only redirecting on login pages, but if the login form is at the top of all pages then it doesn&#8217;t help much.</p>
<p>Facebook uses a javascript method on all of the sites where you see facebook connect so you can use your facebook credentials to comment on blogs and other things. This method may be fine for their case, but again it will cause the extra traffic since the javascript is still connecting to the main server to get cookie info. I also don&#8217;t want to rely on javascript for my sessions.</p>
<p>I wanted a solution where it would only keep users logged in when they needed to be kept logged in. One way of knowing if they need to be kept logged in is: they are on one domain and click a link to go over to the other domain. Using a single-sign-on link to the other domain, the user would stay logged in at the new domain. The only use case that this doesn&#8217;t account for is someone is logged in at one domain and then types the other domain into the address bar. However that is a minimal case and I think the sso link will be the best way to keep users logged in most of the time and keep the overhead down.</p>
<p>I plan on open sourcing the django sso code so that other people can use it in their projects. It will allow a django site to accept single sign on requests and it will also help to create single sign on links to other sites. Both ends of the process don&#8217;t need to be a django site since it should work with other applications that use this type of process to authenticate users.</p>
<p>I&#8217;ll write a post on here about how to use the code once I get it set up at google code so if you are interested in that, you should probably 
<a  href="http://codespatter.com/feed/">subscribe to the rss</a> so you don&#8217;t miss it.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fcodespatter.com%2F2009%2F06%2F18%2Fdjango-single-sign-on-or-a-solution-to-multi-domain-cookies%2F';
  addthis_title  = 'Django+Single+Sign+On+or+a+Solution+to+Multi-domain+Cookies';
  addthis_pub    = 'gallard';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>


<p>Related posts:</p><ol><li><a href='http://codespatter.com/2009/01/05/django-settings-site-domain-examplecom/' rel='bookmark' title='Permanent Link: Django Settings Site Domain example.com'>Django Settings Site Domain example.com</a> <small>It took me</small></li><li><a href='http://codespatter.com/2007/08/10/openid-enabled/' rel='bookmark' title='Permanent Link: OpenID Enabled'>OpenID Enabled</a> <small>If you hav</small></li><li><a href='http://codespatter.com/2009/07/08/python-projects-in-users-home-directories-with-wsgi/' rel='bookmark' title='Permanent Link: Python Projects in Users&#8217; Home Directories with wsgi'>Python Projects in Users&#8217; Home Directories with wsgi</a> <small>Letting us</small></li></ol><img src="http://feeds.feedburner.com/~r/CodeSpatter/~4/8RFWvGYn2ck" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://codespatter.com/2009/06/18/django-single-sign-on-or-a-solution-to-multi-domain-cookies/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://codespatter.com/2009/06/18/django-single-sign-on-or-a-solution-to-multi-domain-cookies/</feedburner:origLink></item>
		<item>
		<title>How to Speed up Your Django Sites with NginX, Memcached, and django-compress</title>
		<link>http://feedproxy.google.com/~r/CodeSpatter/~3/-GLBHBvluY8/</link>
		<comments>http://codespatter.com/2009/04/23/how-to-speed-up-your-django-sites/#comments</comments>
		<pubDate>Thu, 23 Apr 2009 14:22:30 +0000</pubDate>
		<dc:creator>Greg Allard</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Server Administration]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://codespatter.com/?p=389</guid>
		<description><![CDATA[A lot of these steps will speed up any kind of application, not just django projects, but there are a few django specific things. Everything has been tested on 
IvyLees which is running in a Debian/Ubuntu environment.
These three simple steps will speed up your server and allow it to handle more traffic.


Reducing the Number of [...]


Related posts:<ol><li><a href='http://codespatter.com/2008/09/22/static-files-in-django-on-production-and-development/' rel='bookmark' title='Permanent Link: Static Files in Django on Production and Development'>Static Files in Django on Production and Development</a> <small>Update 200</small></li><li><a href='http://codespatter.com/2009/07/08/python-projects-in-users-home-directories-with-wsgi/' rel='bookmark' title='Permanent Link: Python Projects in Users&#8217; Home Directories with wsgi'>Python Projects in Users&#8217; Home Directories with wsgi</a> <small>Letting us</small></li><li><a href='http://codespatter.com/2008/10/15/setting-up-apache2-mod_python-mysql-and-django-on-debian-lenny-or-ubuntu-hardy-heron/' rel='bookmark' title='Permanent Link: Setting up Apache2, mod_python, MySQL, and Django on Debian Lenny or Ubuntu Hardy Heron'>Setting up Apache2, mod_python, MySQL, and Django on Debian Lenny or Ubuntu Hardy Heron</a> <small>Both Debia</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>A lot of these steps will speed up any kind of application, not just django projects, but there are a few django specific things. Everything has been tested on 
<a  href="http://ivylees.com" onclick="javascript:pageTracker._trackPageview('/external/ivylees.com');" >IvyLees</a> which is running in a Debian/Ubuntu environment.</p>
<p>These three simple steps will speed up your server and allow it to handle more traffic.</p>
<ul>
<li>
<a  href="#http-requests">Reducing the Number of HTTP Requests</a></li>
<li>
<a  href="#memcached">Caching</a></li>
<li>
<a  href="#nginx">Using a lightweight front end server</a></li>
</ul>
<h3 id="http-requests">Reducing the Number of HTTP Requests</h3>
<p>Yahoo has developed a 
<a  href="http://www.mozilla.com/firefox/" onclick="javascript:pageTracker._trackPageview('/external/www.mozilla.com/firefox/');" >firefox</a> extension called 
<a  href="http://developer.yahoo.com/yslow/" onclick="javascript:pageTracker._trackPageview('/external/developer.yahoo.com/yslow/');" >YSlow</a>. It analyzes all of the traffic from a website and gives a score on a few categories where improvements can be made.</p>
<p>It recommends reducing all of your css files into one file and all of your js files into one file or as few as possible. There is a pluggable, open source django application available to help with that task. After setting up 
<a  href="http://code.google.com/p/django-compress/" onclick="javascript:pageTracker._trackPageview('/external/code.google.com/p/django-compress/');" >django-compress</a>, a website will have css and js files that are minified (excess white space and characters are removed to reduce file size). The application will also give the files version numbers so that they can be cached by the web browser and won&#8217;t need to be downloaded again until a change is made and a new version of the file is created. 
<a  href="#far_future_expires">How to setup the server to set a far future expiration is shown below in the lightweight server section</a>.</p>
<h3 id="memcached">Setting up Memcached</h3>
<p>Django makes it really simple to set up caching backends and memcached is easy to install.</p>

<div class="wp_syntax"><div class="code"><pre>sudo aptitude install memcached, python-setuptools</pre></div></div>

<p>We will need setuptools so that we can do the following command.</p>

<div class="wp_syntax"><div class="code"><pre>sudo easy_install python-memcached</pre></div></div>

<p>Once that is done you can start the memcached server by doing the following:</p>

<div class="wp_syntax"><div class="code"><pre>sudo memcached -d -u www-data -p 11211 -m 64</pre></div></div>

<p>-d will start it in daemon mode, -u is the user for it to run as, -p is the port, and -m is the maximum number of megabytes of memory to use.</p>
<p>Now open up the settings.py file for your project and add the following line:</p>

<div class="wp_syntax"><div class="code"><pre class="python">CACHE_BACKEND = <span style="color: #483d8b;">'memcached://127.0.0.1:11211/'</span></pre></div></div>

<p>Find the MIDDLEWARE_CLASSES section and add this to the beginning of the list:</p>

<div class="wp_syntax"><div class="code"><pre class="python">    <span style="color: #483d8b;">'django.middleware.cache.UpdateCacheMiddleware'</span>,</pre></div></div>

<p>and this to the end of the list:</p>

<div class="wp_syntax"><div class="code"><pre class="python">    <span style="color: #483d8b;">'django.middleware.cache.FetchFromCacheMiddleware'</span>,</pre></div></div>

<p>For more about caching with django see the 
<a  href="http://docs.djangoproject.com/en/dev/topics/cache/" onclick="javascript:pageTracker._trackPageview('/external/docs.djangoproject.com/en/dev/topics/cache/');" >django docs on caching</a>. You can reload the server now to try it out.</p>

<div class="wp_syntax"><div class="code"><pre>sudo /etc/init.d/apache2 reload</pre></div></div>

<p>To make sure that memcached is set up correctly you can telnet into it and get some statistics.</p>

<div class="wp_syntax"><div class="code"><pre>telnet localhost 11211</pre></div></div>

<p>Once you are in type <strong>stats</strong> and it will show some information (press ctrl ] and then ctrl d to exit). If there are too many zeroes, it either isn&#8217;t working or you haven&#8217;t visited your site since the caching was set up. See 
<a  href="http://www.danga.com/memcached/" onclick="javascript:pageTracker._trackPageview('/external/www.danga.com/memcached/');" >the memcached site</a> for more information.</p>
<h3 id="nginx">Don&#8217;t Use Apache for Static Files</h3>
<p>Apache has some overhead involved that makes it good for serving php, python, or ruby applications, but you do not need that for static files like your images, style sheets, and javascript. There are a few options for lightweight servers that you can put in front of apache to handle the static files. 
<a  href="http://www.lighttpd.net/" onclick="javascript:pageTracker._trackPageview('/external/www.lighttpd.net/');" >Lighttpd (lighty)</a> and 
<a  href="http://nginx.net/" onclick="javascript:pageTracker._trackPageview('/external/nginx.net/');" >nginx (engine x)</a> are two good options. Adding this layer in front of your application will act as an application firewall so there is a security bonus to the speed bonus. </p>
<p>There is this guide to 
<a  href="http://www.ventanazul.com/webzine/tutorials/django-deployment-guide-ubuntu" onclick="javascript:pageTracker._trackPageview('/external/www.ventanazul.com/webzine/tutorials/django-deployment-guide-ubuntu');" >install a django setup with nginx and apache from scratch</a>. If you followed 
<a  href="http://codespatter.com/2008/10/15/setting-up-apache2-mod_python-mysql-and-django-on-debian-lenny-or-ubuntu-hardy-heron/">my guide to set up your server</a> or already have apache set up for your application, then there are a few steps to get nginx handling your static files.</p>

<div class="wp_syntax"><div class="code"><pre>sudo aptitude install nginx</pre></div></div>

<p>Edit the config file for your site (sudo nano /etc/apache2/sites-available/default) and change the port from 80 to 8080 and change the ip address (might be *) to 127.0.0.1. The lines will look like the following</p>

<div class="wp_syntax"><div class="code"><pre>NameVirtualHost 127.0.0.1:8080
&lt;VirtualHost 127.0.0.1:8080&gt;</pre></div></div>

<p>Also edit the ports.conf file (sudo nano /etc/apache2/ports.conf) so that it will listen on 8080.</p>

<div class="wp_syntax"><div class="code"><pre>Listen 8080</pre></div></div>

<p>Don&#8217;t restart the server yet, you want to configure nginx first. Edit the default nginx config file (sudo nano /etc/nginx/sites-available/default) and find where it says</p>

<div class="wp_syntax"><div class="code"><pre>        location / {
               root   /var/www/nginx-default;
               index  index.html index.htm;
        }</pre></div></div>

<p>and replace it with</p>

<div class="wp_syntax"><div class="code"><pre>location / {
    proxy_pass http://192.168.0.180:8080;
    proxy_redirect off;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    client_max_body_size 10m;
    client_body_buffer_size 128k;
    proxy_connect_timeout 90;
    proxy_send_timeout 90;
    proxy_read_timeout 90;
    proxy_buffer_size 4k;
    proxy_buffers 4 32k;
    proxy_busy_buffers_size 64k;
    proxy_temp_file_write_size 64k; 
}
location /files/ {
    root /var/www/myproject/;
    expires max;
}</pre></div></div>

<p>/files/ is where I&#8217;ve stored all of my static files and /var/www/myproject/ is where my project lives and it contains the files directory. </p>
<p id="far_future_expires"><strong>Set static files to expire far in the future</strong></p>
<p>expires max; will tell your users&#8217; browsers to cache the files from that directory for a long time. Only use that if you are use those files won&#8217;t change. You can use expires 24h; if you aren&#8217;t sure.</p>
<p id="far_future_expires"><strong>Configure gzip</strong></p>
<p>Edit the nginx configuration to use gzip on all of your static files (sudo nano /etc/nginx/nginx.conf). Where it says gzip on; make sure it looks like the following:</p>

<div class="wp_syntax"><div class="code"><pre>    gzip  on;
    gzip_comp_level 2;
    gzip_proxied any;
    gzip_types      text/plain text/html text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;</pre></div></div>

<p>The servers should be ready to be restarted.</p>

<div class="wp_syntax"><div class="code"><pre>sudo /etc/init.d/apache2 reload
sudo /etc/init.d/nginx reload</pre></div></div>

<p>If you are having any problems I suggest reading through 
<a  href="http://www.ventanazul.com/webzine/tutorials/django-deployment-guide-ubuntu" onclick="javascript:pageTracker._trackPageview('/external/www.ventanazul.com/webzine/tutorials/django-deployment-guide-ubuntu');" >this guide</a> and seeing if you have something set up differently.</p>
<h3>Speedy Django Sites</h3>
<p>Those three steps should speed up your server and allow for more simultaneous visitors. There is a lot more that can be done, but getting these three easy things out of the way first is a good start.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fcodespatter.com%2F2009%2F04%2F23%2Fhow-to-speed-up-your-django-sites%2F';
  addthis_title  = 'How+to+Speed+up+Your+Django+Sites+with+NginX%2C+Memcached%2C+and+django-compress';
  addthis_pub    = 'gallard';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>


<p>Related posts:</p><ol><li><a href='http://codespatter.com/2008/09/22/static-files-in-django-on-production-and-development/' rel='bookmark' title='Permanent Link: Static Files in Django on Production and Development'>Static Files in Django on Production and Development</a> <small>Update 200</small></li><li><a href='http://codespatter.com/2009/07/08/python-projects-in-users-home-directories-with-wsgi/' rel='bookmark' title='Permanent Link: Python Projects in Users&#8217; Home Directories with wsgi'>Python Projects in Users&#8217; Home Directories with wsgi</a> <small>Letting us</small></li><li><a href='http://codespatter.com/2008/10/15/setting-up-apache2-mod_python-mysql-and-django-on-debian-lenny-or-ubuntu-hardy-heron/' rel='bookmark' title='Permanent Link: Setting up Apache2, mod_python, MySQL, and Django on Debian Lenny or Ubuntu Hardy Heron'>Setting up Apache2, mod_python, MySQL, and Django on Debian Lenny or Ubuntu Hardy Heron</a> <small>Both Debia</small></li></ol><img src="http://feeds.feedburner.com/~r/CodeSpatter/~4/-GLBHBvluY8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://codespatter.com/2009/04/23/how-to-speed-up-your-django-sites/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		<feedburner:origLink>http://codespatter.com/2009/04/23/how-to-speed-up-your-django-sites/</feedburner:origLink></item>
		<item>
		<title>How to Add Locations to Python Path for Reusable Django Apps</title>
		<link>http://feedproxy.google.com/~r/CodeSpatter/~3/rouA10vZBtI/</link>
		<comments>http://codespatter.com/2009/04/10/how-to-add-locations-to-python-path-for-reusable-django-apps/#comments</comments>
		<pubDate>Fri, 10 Apr 2009 15:08:11 +0000</pubDate>
		<dc:creator>Greg Allard</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[How To]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://codespatter.com/?p=261</guid>
		<description><![CDATA[In my 
previous post I talk about reusable apps, but I don&#8217;t really explain it that much. If you have an app that might be useful in another project, it&#8217;s best to not refer to the project name in the application so you don&#8217;t have to search and remove it when adding to another project. [...]


Related posts:<ol><li><a href='http://codespatter.com/2009/07/08/python-projects-in-users-home-directories-with-wsgi/' rel='bookmark' title='Permanent Link: Python Projects in Users&#8217; Home Directories with wsgi'>Python Projects in Users&#8217; Home Directories with wsgi</a> <small>Letting us</small></li><li><a href='http://codespatter.com/2009/01/15/how-to-write-reusable-apps-for-pinax-and-django/' rel='bookmark' title='Permanent Link: How to Write Reusable Apps for Pinax and Django'>How to Write Reusable Apps for Pinax and Django</a> <small>
Pinax is </small></li><li><a href='http://codespatter.com/2009/04/01/getting-basecamp-api-working-with-python/' rel='bookmark' title='Permanent Link: Getting Basecamp API Working with Python'>Getting Basecamp API Working with Python</a> <small>I found 
o</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>In my 
<a  href="http://codespatter.com/2009/01/15/how-to-write-reusable-apps-for-pinax-and-django/">previous post I talk about reusable apps</a>, but I don&#8217;t really explain it that much. If you have an app that might be useful in another project, it&#8217;s best to not refer to the project name in the application so you don&#8217;t have to search and remove it when adding to another project. To never refer to your project name in your app&#8217;s code, you will need to put your app on the python path. I usually do <strong>project_folder/apps/app_folder</strong> so <em>apps</em> will need to be a location that python is checking when you are importing so that importing looks like the following:</p>

<div class="wp_syntax"><div class="code"><pre class="python"><span style="color: #ff7700;font-weight:bold;">from</span> appname.<span style="color: black;">filename</span> <span style="color: #ff7700;font-weight:bold;">import</span> foo</pre></div></div>

<p>There are a few places you might need to add an apps folder to the pythonpath.</p>
<h3>Add to settings.py</h3>
<p>This will add the apps directory in your project directory to the beginning of the path list. This will allow <strong>manage.py syncdb</strong> and <strong>manage.py runserver</strong> to know that the apps folder should be added.</p>

<div class="wp_syntax"><div class="code"><pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
PROJECT_ROOT = <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">dirname</span><span style="color: black;">&#40;</span>__file__<span style="color: black;">&#41;</span>
<span style="color: #dc143c;">sys</span>.<span style="color: black;">path</span>.<span style="color: black;">insert</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span>PROJECT_ROOT, <span style="color: #483d8b;">&quot;apps&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>That should be all you need to do to get most django projects working with your reusable apps, but if for any reason you need add to the path with mod python or mod wsgi, the following should work.</p>
<h3>Apache mod_python</h3>
<p>In the 
<a  href="http://codespatter.com/2008/10/15/setting-up-apache2-mod_python-mysql-and-django-on-debian-lenny-or-ubuntu-hardy-heron/">setting-up-everything post</a> I show an example httpd.conf file. In your apache configuration you will probably see something similar to what is below. To add the location <em>/var/www/myproject/apps</em> to the PythonPath I added it in the list.</p>

<div class="wp_syntax"><div class="code"><pre>SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE myproject.settings
PythonOption django.root /myproject
PythonDebug On
PythonPath &quot;['/var/www','/var/www/myproject/apps'] + sys.path&quot;</pre></div></div>

<h3>Apache mod_wsgi</h3>
<p>If you use mod wsgi instead of mod python, your apache config will be loading a wsgi file with a line like this <em>WSGIScriptAlias /var/www/myproject/myproject.wsgi</em>. You will need to edit that file to add to the path (django&#8217;s site has an 
<a  href="http://code.djangoproject.com/wiki/django_apache_and_mod_wsgi#dj_survey.wsgi" onclick="javascript:pageTracker._trackPageview('/external/code.djangoproject.com/wiki/django_apache_and_mod_wsgi?dj_survey.wsgi');" >example file</a>).</p>

<div class="wp_syntax"><div class="code"><pre class="python"><span style="color: #dc143c;">sys</span>.<span style="color: black;">path</span>.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'/var/www/myproject/apps'</span><span style="color: black;">&#41;</span></pre></div></div>

<p>You never know when you might want to use an app in another project, so always try to keep from mentioning the project name anywhere in the applications.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fcodespatter.com%2F2009%2F04%2F10%2Fhow-to-add-locations-to-python-path-for-reusable-django-apps%2F';
  addthis_title  = 'How+to+Add+Locations+to+Python+Path+for+Reusable+Django+Apps';
  addthis_pub    = 'gallard';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>


<p>Related posts:</p><ol><li><a href='http://codespatter.com/2009/07/08/python-projects-in-users-home-directories-with-wsgi/' rel='bookmark' title='Permanent Link: Python Projects in Users&#8217; Home Directories with wsgi'>Python Projects in Users&#8217; Home Directories with wsgi</a> <small>Letting us</small></li><li><a href='http://codespatter.com/2009/01/15/how-to-write-reusable-apps-for-pinax-and-django/' rel='bookmark' title='Permanent Link: How to Write Reusable Apps for Pinax and Django'>How to Write Reusable Apps for Pinax and Django</a> <small>
Pinax is </small></li><li><a href='http://codespatter.com/2009/04/01/getting-basecamp-api-working-with-python/' rel='bookmark' title='Permanent Link: Getting Basecamp API Working with Python'>Getting Basecamp API Working with Python</a> <small>I found 
o</small></li></ol><img src="http://feeds.feedburner.com/~r/CodeSpatter/~4/rouA10vZBtI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://codespatter.com/2009/04/10/how-to-add-locations-to-python-path-for-reusable-django-apps/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://codespatter.com/2009/04/10/how-to-add-locations-to-python-path-for-reusable-django-apps/</feedburner:origLink></item>
		<item>
		<title>Getting Basecamp API Working with Python</title>
		<link>http://feedproxy.google.com/~r/CodeSpatter/~3/242XXRb_am0/</link>
		<comments>http://codespatter.com/2009/04/01/getting-basecamp-api-working-with-python/#comments</comments>
		<pubDate>Wed, 01 Apr 2009 19:09:33 +0000</pubDate>
		<dc:creator>Greg Allard</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Authorization]]></category>
		<category><![CDATA[How To]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://codespatter.com/?p=359</guid>
		<description><![CDATA[I found 
one library that was linked everywhere, but it wasn&#8217;t working for me. I was always getting 400 Bad Request when using it. Chris Conover was able to get the following code working.

import urllib2
&#160;
protocol = 'https://'
url = 'example.com'
command = '/projects.xml'
headers = &#123;'Accept' : 'application/xml', 
'Content-type' : 'applications/xml'&#125;
username = 'x'
password = 'y'
&#160;
# Setup password stuff
passman [...]


Related posts:<ol><li><a href='http://codespatter.com/2009/07/08/python-projects-in-users-home-directories-with-wsgi/' rel='bookmark' title='Permanent Link: Python Projects in Users&#8217; Home Directories with wsgi'>Python Projects in Users&#8217; Home Directories with wsgi</a> <small>Letting us</small></li><li><a href='http://codespatter.com/2009/04/10/how-to-add-locations-to-python-path-for-reusable-django-apps/' rel='bookmark' title='Permanent Link: How to Add Locations to Python Path for Reusable Django Apps'>How to Add Locations to Python Path for Reusable Django Apps</a> <small>In my 
pre</small></li><li><a href='http://codespatter.com/2008/10/15/setting-up-apache2-mod_python-mysql-and-django-on-debian-lenny-or-ubuntu-hardy-heron/' rel='bookmark' title='Permanent Link: Setting up Apache2, mod_python, MySQL, and Django on Debian Lenny or Ubuntu Hardy Heron'>Setting up Apache2, mod_python, MySQL, and Django on Debian Lenny or Ubuntu Hardy Heron</a> <small>Both Debia</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>I found 
<a  href="http://homework.nwsnet.de/products/3cd4" onclick="javascript:pageTracker._trackPageview('/external/homework.nwsnet.de/products/3cd4');" >one library that was linked everywhere</a>, but it wasn&#8217;t working for me. I was always getting <strong>400 Bad Request</strong> when using it. Chris Conover was able to get the following code working.</p>

<div class="wp_syntax"><div class="code"><pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">urllib2</span>
&nbsp;
protocol = <span style="color: #483d8b;">'https://'</span>
url = <span style="color: #483d8b;">'example.com'</span>
command = <span style="color: #483d8b;">'/projects.xml'</span>
headers = <span style="color: black;">&#123;</span><span style="color: #483d8b;">'Accept'</span> : <span style="color: #483d8b;">'application/xml'</span>, 
<span style="color: #483d8b;">'Content-type'</span> : <span style="color: #483d8b;">'applications/xml'</span><span style="color: black;">&#125;</span>
username = <span style="color: #483d8b;">'x'</span>
password = <span style="color: #483d8b;">'y'</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Setup password stuff</span>
passman = <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">HTTPPasswordMgrWithDefaultRealm</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
passman.<span style="color: black;">add_password</span><span style="color: black;">&#40;</span><span style="color: #008000;">None</span>, url, username, password<span style="color: black;">&#41;</span>
authhandler = <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">HTTPBasicAuthHandler</span><span style="color: black;">&#40;</span>passman<span style="color: black;">&#41;</span>
opener = <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">build_opener</span><span style="color: black;">&#40;</span>authhandler<span style="color: black;">&#41;</span>
<span style="color: #dc143c;">urllib2</span>.<span style="color: black;">install_opener</span><span style="color: black;">&#40;</span>opener<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Send the request and get response</span>
req = <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">Request</span><span style="color: black;">&#40;</span>protocol + url + command, <span style="color: #008000;">None</span>, headers<span style="color: black;">&#41;</span>
response = <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">urlopen</span><span style="color: black;">&#40;</span>req<span style="color: black;">&#41;</span>
results = response.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">print</span> results</pre></div></div>

<p>I thought it was a problem with how the authorization was formed so based on the above code I modified the old basecamp.py file and I was able to get a response. The following is what I changed.</p>
<p>Around line 64</p>

<div class="wp_syntax"><div class="code"><pre class="python">    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, username, password, protocol, url<span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">baseURL</span> = protocol+url
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">self</span>.<span style="color: black;">baseURL</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">-1</span><span style="color: black;">&#93;</span> == <span style="color: #483d8b;">'/'</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">baseURL</span> = <span style="color: #008000;">self</span>.<span style="color: black;">baseURL</span><span style="color: black;">&#91;</span>:<span style="color: #ff4500;">-1</span><span style="color: black;">&#93;</span>
&nbsp;
        passman = <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">HTTPPasswordMgrWithDefaultRealm</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        passman.<span style="color: black;">add_password</span><span style="color: black;">&#40;</span><span style="color: #008000;">None</span>, url, username, password<span style="color: black;">&#41;</span>
        authhandler = <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">HTTPBasicAuthHandler</span><span style="color: black;">&#40;</span>passman<span style="color: black;">&#41;</span>
&nbsp;
        <span style="color: #008000;">self</span>.<span style="color: black;">opener</span> = <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">build_opener</span><span style="color: black;">&#40;</span>authhandler<span style="color: black;">&#41;</span></pre></div></div>

<p>And around line 142</p>

<div class="wp_syntax"><div class="code"><pre class="python">path = <span style="color: #483d8b;">'/projects.xml'</span></pre></div></div>

<p>With that I was able to use basecamp.py to retrieve a list of projects. Other modifications may be needed for other features, but that was all I planned on using.</p>
<p>Here is an example of using 
<a  href="http://effbot.org/zone/element-index.htm" onclick="javascript:pageTracker._trackPageview('/external/effbot.org/zone/element-index.htm');" >ElementTree</a> to parse the XML response to get the names of all of the projects returned from basecamp.</p>

<div class="wp_syntax"><div class="code"><pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> elementtree.<span style="color: black;">ElementTree</span> as ET
<span style="color: #ff7700;font-weight:bold;">from</span> basecamp <span style="color: #ff7700;font-weight:bold;">import</span> Basecamp
&nbsp;
protocol = <span style="color: #483d8b;">'https://'</span>
url = <span style="color: #483d8b;">'example.com'</span>
username = <span style="color: #483d8b;">'x'</span>
password = <span style="color: #483d8b;">'y'</span>
&nbsp;
bc = Basecamp<span style="color: black;">&#40;</span>username, password, protocol, url<span style="color: black;">&#41;</span>
projects = bc.<span style="color: black;">projects</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
tree = ET.<span style="color: black;">fromstring</span><span style="color: black;">&#40;</span>projects<span style="color: black;">&#41;</span>
tags = tree.<span style="color: black;">getiterator</span><span style="color: black;">&#40;</span>tag=<span style="color: #483d8b;">'project'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">for</span> t <span style="color: #ff7700;font-weight:bold;">in</span> tags:
    project_name = t.<span style="color: black;">findtext</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'name'</span><span style="color: black;">&#41;</span></pre></div></div>

<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fcodespatter.com%2F2009%2F04%2F01%2Fgetting-basecamp-api-working-with-python%2F';
  addthis_title  = 'Getting+Basecamp+API+Working+with+Python';
  addthis_pub    = 'gallard';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>


<p>Related posts:</p><ol><li><a href='http://codespatter.com/2009/07/08/python-projects-in-users-home-directories-with-wsgi/' rel='bookmark' title='Permanent Link: Python Projects in Users&#8217; Home Directories with wsgi'>Python Projects in Users&#8217; Home Directories with wsgi</a> <small>Letting us</small></li><li><a href='http://codespatter.com/2009/04/10/how-to-add-locations-to-python-path-for-reusable-django-apps/' rel='bookmark' title='Permanent Link: How to Add Locations to Python Path for Reusable Django Apps'>How to Add Locations to Python Path for Reusable Django Apps</a> <small>In my 
pre</small></li><li><a href='http://codespatter.com/2008/10/15/setting-up-apache2-mod_python-mysql-and-django-on-debian-lenny-or-ubuntu-hardy-heron/' rel='bookmark' title='Permanent Link: Setting up Apache2, mod_python, MySQL, and Django on Debian Lenny or Ubuntu Hardy Heron'>Setting up Apache2, mod_python, MySQL, and Django on Debian Lenny or Ubuntu Hardy Heron</a> <small>Both Debia</small></li></ol><img src="http://feeds.feedburner.com/~r/CodeSpatter/~4/242XXRb_am0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://codespatter.com/2009/04/01/getting-basecamp-api-working-with-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://codespatter.com/2009/04/01/getting-basecamp-api-working-with-python/</feedburner:origLink></item>
		<item>
		<title>The People Make SXSW Awesome</title>
		<link>http://feedproxy.google.com/~r/CodeSpatter/~3/lX-Q9zLors4/</link>
		<comments>http://codespatter.com/2009/03/25/the-people-make-sxsw-awesome/#comments</comments>
		<pubDate>Wed, 25 Mar 2009 18:04:46 +0000</pubDate>
		<dc:creator>Greg Allard</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://codespatter.com/?p=283</guid>
		<description><![CDATA[I didn&#8217;t hear much about 
SXSW before going. I knew there would be a lot of presentations to see and there would be a few parties. I never expected the parties to be more valuable than the presentations and I was completely surprised by that.
The evening events were a great chance to meet people that [...]


Related posts:<ol><li><a href='http://codespatter.com/2008/05/16/keep-friends-posted-while-on-the-road/' rel='bookmark' title='Permanent Link: Keep Friends Posted While on the Road'>Keep Friends Posted While on the Road</a> <small>Going on a</small></li><li><a href='http://codespatter.com/2008/08/27/just-heard-about-an-open-source-database-conference/' rel='bookmark' title='Permanent Link: Just Heard About an Open-Source Database Conference'>Just Heard About an Open-Source Database Conference</a> <small>Baron Schw</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>I didn&#8217;t hear much about 
<a  href="http://sxsw.com" onclick="javascript:pageTracker._trackPageview('/external/sxsw.com');" >SXSW</a> before going. I knew there would be a lot of presentations to see and there would be a few parties. I never expected the parties to be more valuable than the presentations and I was completely surprised by that.</p>
<p>The evening events were a great chance to meet people that are doing awesome things. There was the 
<a  href="http://unclasses.com/" onclick="javascript:pageTracker._trackPageview('/external/unclasses.com/');" >unclasses</a> guy and the 
<a  href="http://awe.sm/" onclick="javascript:pageTracker._trackPageview('/external/awe.sm/');" >awe.sm</a> guy that I met through 
<a  href="http://timrosenblatt.com/blog/" onclick="javascript:pageTracker._trackPageview('/external/timrosenblatt.com/blog/');" >Tim</a>. And then there was someone doing something more awesome than I ever could. He is a 
<a  href="http://happyjoel.com/" onclick="javascript:pageTracker._trackPageview('/external/happyjoel.com/');" >professional contest winner</a>. He enters funny videos into contests and wins things like trips around the world where he will make more videos and win more contests.</p>
<p>I met a lot of the Orlando crowd while in another city. I met and followed 
<a  href="http://twitter.com/xentek" onclick="javascript:pageTracker._trackPageview('/external/twitter.com/xentek');" >Eric</a> a few months ago and through him I was able to meet some of the people that go to 
<a  href="http://floridacreatives.com/" onclick="javascript:pageTracker._trackPageview('/external/floridacreatives.com/');" >Florida Creatives happy hour</a>. So that was a great chance to get to know everyone better.</p>
<p>There was also a presentation from the 
<a  href="http://railsenvy.com/" onclick="javascript:pageTracker._trackPageview('/external/railsenvy.com/');" >rails envy podcast</a> guy, Gregg Pollack from Orlando. Gregg&#8217;s was the only one I went to that wasn&#8217;t a panel. The panels could be a bit boring sometimes, but they gave a chance to hear from about 5 people with experience on the topic. The higher education panel started bad just like some of the other panels, but it got better as it went since they got into the important stuff. It would seem that I am still passionate about improving education and I hope that I will be able to work on something at UCF soon that will do just that. </p>
<p>There were a few other panels that weren&#8217;t that bad like How to Rawk SXSW where the panelists were experienced SXSWers and gave advice to the noobs. After my visit, the advice I would give is &#8220;Be ready to network&#8221; because that is the most important part of the conference. And the last panel I attended was how to rawk the rest of the year which had some advice like <em>keep in contact with the people that you&#8217;ve met here</em>. One easy way of doing that is finding out who they are on twitter (everyone at the event was on twitter by the end). One other piece of advice from the panel was <em>the parties aren&#8217;t the only place to meet people, hallways and streets work well too</em>. Maybe that would have been better advice at the beginning, but it arose from a question.</p>
<p>Hopefully I will get to run into a lot of the Orlando people again at the 
<a  href="http://floridacreatives.com/" onclick="javascript:pageTracker._trackPageview('/external/floridacreatives.com/');" >happy hours</a> and of course I&#8217;ll be at 
<a  href="http://www.barcamporlando.org/" onclick="javascript:pageTracker._trackPageview('/external/www.barcamporlando.org/');" >BarCampOrlando</a> on April 18th.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fcodespatter.com%2F2009%2F03%2F25%2Fthe-people-make-sxsw-awesome%2F';
  addthis_title  = 'The+People+Make+SXSW+Awesome';
  addthis_pub    = 'gallard';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>


<p>Related posts:</p><ol><li><a href='http://codespatter.com/2008/05/16/keep-friends-posted-while-on-the-road/' rel='bookmark' title='Permanent Link: Keep Friends Posted While on the Road'>Keep Friends Posted While on the Road</a> <small>Going on a</small></li><li><a href='http://codespatter.com/2008/08/27/just-heard-about-an-open-source-database-conference/' rel='bookmark' title='Permanent Link: Just Heard About an Open-Source Database Conference'>Just Heard About an Open-Source Database Conference</a> <small>Baron Schw</small></li></ol><img src="http://feeds.feedburner.com/~r/CodeSpatter/~4/lX-Q9zLors4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://codespatter.com/2009/03/25/the-people-make-sxsw-awesome/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://codespatter.com/2009/03/25/the-people-make-sxsw-awesome/</feedburner:origLink></item>
		<item>
		<title>How to Write Django Template Tags</title>
		<link>http://feedproxy.google.com/~r/CodeSpatter/~3/BftHbKAEqRc/</link>
		<comments>http://codespatter.com/2009/01/22/how-to-write-django-template-tags/#comments</comments>
		<pubDate>Thu, 22 Jan 2009 13:55:49 +0000</pubDate>
		<dc:creator>Greg Allard</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[How To]]></category>
		<category><![CDATA[Pinax]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://codespatter.com/?p=221</guid>
		<description><![CDATA[Template tags can be useful for making your applications more reusable by other projects. For this example I will be adding to the 
books project that I started in a previous post. Also, I&#8217;ve bundled the 
example files into a google code project.
Start off by creating a folder called templatetags in your app directory and [...]


Related posts:<ol><li><a href='http://codespatter.com/2009/01/15/how-to-write-reusable-apps-for-pinax-and-django/' rel='bookmark' title='Permanent Link: How to Write Reusable Apps for Pinax and Django'>How to Write Reusable Apps for Pinax and Django</a> <small>
Pinax is </small></li><li><a href='http://codespatter.com/2008/12/22/django-requestcontext-example/' rel='bookmark' title='Permanent Link: Django RequestContext Example'>Django RequestContext Example</a> <small>Browsing o</small></li><li><a href='http://codespatter.com/2008/09/13/quick-thumbnails-in-django/' rel='bookmark' title='Permanent Link: Quick Thumbnails in Django'>Quick Thumbnails in Django</a> <small>I normally</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>Template tags can be useful for making your applications more reusable by other projects. For this example I will be adding to the 
<a  href="http://codespatter.com/2009/01/15/how-to-write-reusable-apps-for-pinax-and-django/">books project that I started in a previous post</a>. Also, I&#8217;ve bundled the 
<a  href="http://code.google.com/p/django-books/" onclick="javascript:pageTracker._trackPageview('/external/code.google.com/p/django-books/');" >example files into a google code project</a>.</p>
<p>Start off by creating a folder called <strong>templatetags</strong> in your app directory and create two files in it. The first one named <strong>__init__.py</strong> and the second <strong>book_tags.py</strong>. There&#8217;s 3 things that we need to accomplish with our template tags. The first is to create a tag that will output the url for the action of the form. For example, <strong>{% get_book_form_url foo_object %}</strong>Next we need to get the form and assign it to a template variable that can be specified by the template variable. For example, <strong>{% book_form as bar_var %}</strong>. And the third template tag will get the books for an object and place in a template variable. For example, <strong>{% books_for_object foo_object as bar_var %}</strong>.</p>

<div class="wp_syntax"><div class="code"><pre class="python"><span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">template</span> <span style="color: #ff7700;font-weight:bold;">import</span> Library, Node, TemplateSyntaxError
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">template</span> <span style="color: #ff7700;font-weight:bold;">import</span> Variable, resolve_variable
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">utils</span>.<span style="color: black;">translation</span> <span style="color: #ff7700;font-weight:bold;">import</span> ugettext as _
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">contrib</span>.<span style="color: black;">contenttypes</span>.<span style="color: black;">models</span> <span style="color: #ff7700;font-weight:bold;">import</span> ContentType
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">core</span>.<span style="color: black;">urlresolvers</span> <span style="color: #ff7700;font-weight:bold;">import</span> reverse
<span style="color: #ff7700;font-weight:bold;">from</span> books.<span style="color: black;">models</span> <span style="color: #ff7700;font-weight:bold;">import</span> Book
&nbsp;
register = Library<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> get_contenttype_kwargs<span style="color: black;">&#40;</span>content_object<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Gets the basic kwargs necessary for form submission url
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    kwargs = <span style="color: black;">&#123;</span><span style="color: #483d8b;">'content_type_id'</span>:
        ContentType.<span style="color: black;">objects</span>.<span style="color: black;">get_for_model</span><span style="color: black;">&#40;</span>content_object<span style="color: black;">&#41;</span>.<span style="color: #008000;">id</span>,
    <span style="color: #483d8b;">'object_id'</span>:
        <span style="color: #008000;">getattr</span><span style="color: black;">&#40;</span>content_object, <span style="color: #483d8b;">'pk'</span>,
            <span style="color: #008000;">getattr</span><span style="color: black;">&#40;</span>content_object, <span style="color: #483d8b;">'id'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>,
    <span style="color: black;">&#125;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> kwargs
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> get_book_form_url<span style="color: black;">&#40;</span>content_object<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    prints url for form action
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    kwargs = get_contenttype_kwargs<span style="color: black;">&#40;</span>content_object<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> reverse<span style="color: black;">&#40;</span><span style="color: #483d8b;">'new_book'</span>, kwargs=kwargs<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> BooksForObjectsNode<span style="color: black;">&#40;</span>Node<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Get the books and add to the context
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, obj, context_var<span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">obj</span> = Variable<span style="color: black;">&#40;</span>obj<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">context_var</span> = context_var
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> render<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, context<span style="color: black;">&#41;</span>:
        content_type = ContentType.<span style="color: black;">objects</span>.<span style="color: black;">get_for_model</span><span style="color: black;">&#40;</span>
            <span style="color: #008000;">self</span>.<span style="color: black;">obj</span>.<span style="color: black;">resolve</span><span style="color: black;">&#40;</span>context<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #808080; font-style: italic;"># create the template var by adding to context</span>
        context<span style="color: black;">&#91;</span><span style="color: #008000;">self</span>.<span style="color: black;">context_var</span><span style="color: black;">&#93;</span> = \
            Book.<span style="color: black;">objects</span>.<span style="color: #008000;">filter</span><span style="color: black;">&#40;</span> <span style="color: #808080; font-style: italic;"># find all books for object</span>
                content_type__pk = content_type.<span style="color: #008000;">id</span>,
                object_id = <span style="color: #008000;">self</span>.<span style="color: black;">obj</span>.<span style="color: black;">resolve</span><span style="color: black;">&#40;</span>context<span style="color: black;">&#41;</span>.<span style="color: #008000;">id</span>
            <span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">''</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> books_for_object<span style="color: black;">&#40;</span><span style="color: #dc143c;">parser</span>, <span style="color: #dc143c;">token</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Retrieves a list of books for given object
    {% books_for_object foo_object as book_list %}
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">try</span>:
        bits = <span style="color: #dc143c;">token</span>.<span style="color: black;">split_contents</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">ValueError</span>:
        <span style="color: #ff7700;font-weight:bold;">raise</span> TemplateSyntaxError<span style="color: black;">&#40;</span>
            _<span style="color: black;">&#40;</span><span style="color: #483d8b;">'tag requires exactly two arguments'</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>bits<span style="color: black;">&#41;</span> <span style="color: #66cc66;">!</span>= <span style="color: #ff4500;">4</span>:
        <span style="color: #ff7700;font-weight:bold;">raise</span> TemplateSyntaxError<span style="color: black;">&#40;</span>
            _<span style="color: black;">&#40;</span><span style="color: #483d8b;">'tag requires exactly three arguments'</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> bits<span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span> <span style="color: #66cc66;">!</span>= <span style="color: #483d8b;">'as'</span>:
        <span style="color: #ff7700;font-weight:bold;">raise</span> TemplateSyntaxError<span style="color: black;">&#40;</span>
            _<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;second argument to tag must be 'as'&quot;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> BooksForObjectsNode<span style="color: black;">&#40;</span>bits<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>, bits<span style="color: black;">&#91;</span><span style="color: #ff4500;">3</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> book_form<span style="color: black;">&#40;</span><span style="color: #dc143c;">parser</span>, <span style="color: #dc143c;">token</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Adds a form to the context as given variable
    {% book_form as form %}
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    <span style="color: #808080; font-style: italic;"># take steps to ensure template var was formatted properly</span>
    <span style="color: #ff7700;font-weight:bold;">try</span>:
        bits = <span style="color: #dc143c;">token</span>.<span style="color: black;">split_contents</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">ValueError</span>:
        <span style="color: #ff7700;font-weight:bold;">raise</span> TemplateSyntaxError<span style="color: black;">&#40;</span>
            _<span style="color: black;">&#40;</span><span style="color: #483d8b;">'tag requires exactly two arguments'</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> bits<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span> <span style="color: #66cc66;">!</span>= <span style="color: #483d8b;">'as'</span>:
        <span style="color: #ff7700;font-weight:bold;">raise</span> TemplateSyntaxError<span style="color: black;">&#40;</span>
            _<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;second argument to tag must be 'as'&quot;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>bits<span style="color: black;">&#41;</span> <span style="color: #66cc66;">!</span>= <span style="color: #ff4500;">3</span>:
        <span style="color: #ff7700;font-weight:bold;">raise</span> TemplateSyntaxError<span style="color: black;">&#40;</span>
            _<span style="color: black;">&#40;</span><span style="color: #483d8b;">'tag requires exactly two arguments'</span><span style="color: black;">&#41;</span>
    <span style="color: #808080; font-style: italic;"># get the form</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> BookFormNode<span style="color: black;">&#40;</span>bits<span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> BookFormNode<span style="color: black;">&#40;</span>Node<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    Get the form and add it to the context
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, context_name<span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">context_name</span> = context_name
    <span style="color: #ff7700;font-weight:bold;">def</span> render<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, context<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">from</span> books.<span style="color: black;">forms</span> <span style="color: #ff7700;font-weight:bold;">import</span> NewBookForm
        form = NewBookForm<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #808080; font-style: italic;"># create the template var by adding to context</span>
        context<span style="color: black;">&#91;</span><span style="color: #008000;">self</span>.<span style="color: black;">context_name</span><span style="color: black;">&#93;</span> = form
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">''</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># register these tags for use in template files</span>
register.<span style="color: black;">tag</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'books_for_object'</span>, books_for_object<span style="color: black;">&#41;</span>
register.<span style="color: black;">tag</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'book_form'</span>, book_form<span style="color: black;">&#41;</span>
register.<span style="color: black;">simple_tag</span><span style="color: black;">&#40;</span>get_book_form_url<span style="color: black;">&#41;</span></pre></div></div>

<h3>Add this to your template</h3>
<p>To start adding books to an object, add this code to your template and change <strong>my_awesome_object_here</strong> to the template variable name of your object.</p>

<div class="wp_syntax"><div class="code"><pre>&lt;h2&gt;Books&lt;/h2&gt;
{% load book_tags %}
&nbsp;
{% books_for_object my_awesome_object_here as books %}
{% for book in books %}
&nbsp;
&lt;a href=&quot;{{ book.get_absolute_url }}&quot;&gt;{{ book }}&lt;/a&gt; -
        {{ book.description }}
&nbsp;
{% endfor %}
&lt;h2&gt;Add a book&lt;/h2&gt;
&lt;form action=&quot;{% get_book_form_url my_awesome_object_here %}&quot; method=&quot;post&quot;&gt;
{% book_form as form %}
{{ form }}
&lt;input type=&quot;submit&quot; value=&quot;Go&quot; /&gt;
&lt;/form&gt;</pre></div></div>

<p>You can get the template tags source code and the code from 
<a  href="http://codespatter.com/2009/01/15/how-to-write-reusable-apps-for-pinax-and-django/">the previous post</a> at the 
<a  href="http://code.google.com/p/django-books/" onclick="javascript:pageTracker._trackPageview('/external/code.google.com/p/django-books/');" >google code project page</a> or by doing</p>
<pre>svn co http://django-books.googlecode.com/svn/trunk books</pre>
<p>in a directory on the python path.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fcodespatter.com%2F2009%2F01%2F22%2Fhow-to-write-django-template-tags%2F';
  addthis_title  = 'How+to+Write+Django+Template+Tags';
  addthis_pub    = 'gallard';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>


<p>Related posts:</p><ol><li><a href='http://codespatter.com/2009/01/15/how-to-write-reusable-apps-for-pinax-and-django/' rel='bookmark' title='Permanent Link: How to Write Reusable Apps for Pinax and Django'>How to Write Reusable Apps for Pinax and Django</a> <small>
Pinax is </small></li><li><a href='http://codespatter.com/2008/12/22/django-requestcontext-example/' rel='bookmark' title='Permanent Link: Django RequestContext Example'>Django RequestContext Example</a> <small>Browsing o</small></li><li><a href='http://codespatter.com/2008/09/13/quick-thumbnails-in-django/' rel='bookmark' title='Permanent Link: Quick Thumbnails in Django'>Quick Thumbnails in Django</a> <small>I normally</small></li></ol><img src="http://feeds.feedburner.com/~r/CodeSpatter/~4/BftHbKAEqRc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://codespatter.com/2009/01/22/how-to-write-django-template-tags/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://codespatter.com/2009/01/22/how-to-write-django-template-tags/</feedburner:origLink></item>
		<item>
		<title>How to Write Reusable Apps for Pinax and Django</title>
		<link>http://feedproxy.google.com/~r/CodeSpatter/~3/xrZzSg9DM-s/</link>
		<comments>http://codespatter.com/2009/01/15/how-to-write-reusable-apps-for-pinax-and-django/#comments</comments>
		<pubDate>Thu, 15 Jan 2009 17:07:09 +0000</pubDate>
		<dc:creator>Greg Allard</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[OpenID]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Pinax]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://codespatter.com/?p=158</guid>
		<description><![CDATA[
Pinax is a collection of reusable django apps that brings together features that are common to many websites. It allows developers to focus on what makes their site unique. Here is an example of adding your own functionality to Pinax. It will also be an example of writing a reusable app since every individual app [...]


Related posts:<ol><li><a href='http://codespatter.com/2009/01/22/how-to-write-django-template-tags/' rel='bookmark' title='Permanent Link: How to Write Django Template Tags'>How to Write Django Template Tags</a> <small>Template t</small></li><li><a href='http://codespatter.com/2009/04/10/how-to-add-locations-to-python-path-for-reusable-django-apps/' rel='bookmark' title='Permanent Link: How to Add Locations to Python Path for Reusable Django Apps'>How to Add Locations to Python Path for Reusable Django Apps</a> <small>In my 
pre</small></li><li><a href='http://codespatter.com/2008/12/22/django-requestcontext-example/' rel='bookmark' title='Permanent Link: Django RequestContext Example'>Django RequestContext Example</a> <small>Browsing o</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>
<a  href="http://pinaxproject.com" onclick="javascript:pageTracker._trackPageview('/external/pinaxproject.com');" >Pinax</a> is a collection of reusable django apps that brings together features that are common to many websites. It allows developers to focus on what makes their site unique. Here is an example of adding your own functionality to Pinax. It will also be an example of <strong>writing a <em>reusable</em> app</strong> since every individual app currently in Pinax can be used separately. Also, I&#8217;ve bundled the 
<a  href="http://code.google.com/p/django-books/" onclick="javascript:pageTracker._trackPageview('/external/code.google.com/p/django-books/');" >example files into a google code project</a>.</p>
<p>My example will be to create a list of books and allow them to be tied to any object using 
<a  href="http://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/" onclick="javascript:pageTracker._trackPageview('/external/docs.djangoproject.com/en/dev/ref/contrib/contenttypes/');" >Django&#8217;s ContentType</a> framework. The books could be recommended reading for the members of a tribe (pinax group), a class, or anything in your project and will include title, description, and tags (requires 
<a  href="http://code.google.com/p/django-tagging/" onclick="javascript:pageTracker._trackPageview('/external/code.google.com/p/django-tagging/');" >django-tagging</a>). In another post I&#8217;ve shown 
<a  href="http://codespatter.com/2009/01/22/how-to-write-django-template-tags/">how to create template tags</a> to make it easy to show the list of books and a form to add a book. Obviously, there is a lot more that could be done with this app, but I will leave it out of the example to keep it simple.</p>
<h3>Starting the App</h3>
<p>Create a folder in the apps directory or any place that is on the python path (ex. /path/to/pinax/projects/complete_project/apps/books/)  and include these files:</p>
<ul>
<li>__init__.py even though it might be empty, it is required</li>
<li>forms.py</li>
<li>models.py</li>
<li>urls.py</li>
<li>views.py</li>
</ul>
<h3>models.py</h3>
<p>I will start with creating the model for the project. Below is all of the code I am placing in the file. I&#8217;ve added a lot of comments to explain everything that is happening.</p>

<div class="wp_syntax"><div class="code"><pre class="python"><span style="color: #808080; font-style: italic;">#import all of the things we will be using</span>
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">db</span>                          <span style="color: #ff7700;font-weight:bold;">import</span> models
<span style="color: #ff7700;font-weight:bold;">from</span> tagging.<span style="color: black;">fields</span>                     <span style="color: #ff7700;font-weight:bold;">import</span> TagField
<span style="color: #808080; font-style: italic;"># to help with translation of field names</span>
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">utils</span>.<span style="color: black;">translation</span>  <span style="color: #ff7700;font-weight:bold;">import</span> ugettext_lazy as _
<span style="color: #808080; font-style: italic;"># to have a generic foreign key for any model</span>
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">contrib</span>.<span style="color: black;">contenttypes</span>        <span style="color: #ff7700;font-weight:bold;">import</span> generic
<span style="color: #808080; font-style: italic;"># stores model info so this can be applied to any model</span>
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">contrib</span>.<span style="color: black;">contenttypes</span>.<span style="color: black;">models</span> <span style="color: #ff7700;font-weight:bold;">import</span> ContentType
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Book<span style="color: black;">&#40;</span>models.<span style="color: black;">Model</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    The details of a Book
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    <span style="color: #808080; font-style: italic;"># fields that describe this book</span>
    name        = models.<span style="color: black;">CharField</span><span style="color: black;">&#40;</span>_<span style="color: black;">&#40;</span><span style="color: #483d8b;">'name'</span><span style="color: black;">&#41;</span>, max_length=<span style="color: #ff4500;">48</span><span style="color: black;">&#41;</span>
    description = models.<span style="color: black;">TextField</span><span style="color: black;">&#40;</span>_<span style="color: black;">&#40;</span><span style="color: #483d8b;">'description'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># to add to any model</span>
    content_type   = models.<span style="color: black;">ForeignKey</span><span style="color: black;">&#40;</span>ContentType<span style="color: black;">&#41;</span>
    object_id      = models.<span style="color: black;">PositiveIntegerField</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    content_object = generic.<span style="color: black;">GenericForeignKey</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'content_type'</span>,
        <span style="color: #483d8b;">'object_id'</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># for the list of tags for this book</span>
    tags        = TagField<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># misc fields</span>
    deleted     = models.<span style="color: black;">BooleanField</span><span style="color: black;">&#40;</span>default=<span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
    created     = models.<span style="color: black;">DateTimeField</span><span style="color: black;">&#40;</span>auto_now_add=<span style="color: #008000;">True</span><span style="color: black;">&#41;</span>
    <span style="color: #808080; font-style: italic;"># so that {{book.get_absolute_url}} outputs the whole url</span>
    @models.<span style="color: black;">permalink</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> get_absolute_url<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;book_details&quot;</span>, <span style="color: black;">&#91;</span><span style="color: #008000;">self</span>.<span style="color: black;">pk</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
    <span style="color: #808080; font-style: italic;"># outputs name when printing this object as a string</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__unicode__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">name</span></pre></div></div>

<h3>forms.py</h3>
<p>Use Django&#8217;s ModelForm to create a form for our book model.</p>

<div class="wp_syntax"><div class="code"><pre class="python"><span style="color: #ff7700;font-weight:bold;">from</span> django <span style="color: #ff7700;font-weight:bold;">import</span> forms
<span style="color: #ff7700;font-weight:bold;">from</span> books.<span style="color: black;">models</span> <span style="color: #ff7700;font-weight:bold;">import</span> Book
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> NewBookForm<span style="color: black;">&#40;</span>forms.<span style="color: black;">ModelForm</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">class</span> Meta:
        model = Book
        exclude = <span style="color: black;">&#40;</span><span style="color: #483d8b;">'deleted'</span>, <span style="color: #483d8b;">'content_type'</span>,
            <span style="color: #483d8b;">'object_id'</span>, <span style="color: #483d8b;">'created'</span><span style="color: black;">&#41;</span></pre></div></div>

<h3>views.py</h3>
<p>In this file we create a view to show the details of a book and a view to create a new book for an object.</p>

<div class="wp_syntax"><div class="code"><pre class="python"><span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">shortcuts</span> <span style="color: #ff7700;font-weight:bold;">import</span> render_to_response
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">shortcuts</span> <span style="color: #ff7700;font-weight:bold;">import</span> get_object_or_404
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">http</span> <span style="color: #ff7700;font-weight:bold;">import</span> HttpResponseRedirect
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">template</span> <span style="color: #ff7700;font-weight:bold;">import</span> RequestContext
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">core</span>.<span style="color: black;">urlresolvers</span> <span style="color: #ff7700;font-weight:bold;">import</span> reverse
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">utils</span>.<span style="color: black;">translation</span> <span style="color: #ff7700;font-weight:bold;">import</span> ugettext_lazy as _
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">contrib</span>.<span style="color: black;">auth</span>.<span style="color: black;">decorators</span> <span style="color: #ff7700;font-weight:bold;">import</span> login_required
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> tribes.<span style="color: black;">models</span> <span style="color: #ff7700;font-weight:bold;">import</span> Tribe
<span style="color: #ff7700;font-weight:bold;">from</span> books.<span style="color: black;">models</span> <span style="color: #ff7700;font-weight:bold;">import</span> Book
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">contrib</span>.<span style="color: black;">contenttypes</span>.<span style="color: black;">models</span> <span style="color: #ff7700;font-weight:bold;">import</span> ContentType
&nbsp;
@login_required
<span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #dc143c;">new</span><span style="color: black;">&#40;</span>request, content_type_id, object_id,
            template_name=<span style="color: #483d8b;">&quot;books/new.html&quot;</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    creates a new book
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">from</span> books.<span style="color: black;">forms</span> <span style="color: #ff7700;font-weight:bold;">import</span> NewBookForm
&nbsp;
    <span style="color: #808080; font-style: italic;"># if a new book was posted</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> request.<span style="color: black;">method</span> == <span style="color: #483d8b;">'POST'</span>:
        book_form = NewBookForm<span style="color: black;">&#40;</span>request.<span style="color: black;">POST</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> book_form.<span style="color: black;">is_valid</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
            <span style="color: #808080; font-style: italic;"># create it</span>
            book = book_form.<span style="color: black;">save</span><span style="color: black;">&#40;</span>commit=<span style="color: #008000;">False</span><span style="color: black;">&#41;</span>
            content_type        = \
                ContentType.<span style="color: black;">objects</span>.<span style="color: black;">get</span><span style="color: black;">&#40;</span><span style="color: #008000;">id</span>=content_type_id<span style="color: black;">&#41;</span>
            content_object      = \
                content_type.<span style="color: black;">get_object_for_this_type</span><span style="color: black;">&#40;</span>
                <span style="color: #008000;">id</span>=object_id<span style="color: black;">&#41;</span>
            book.<span style="color: black;">content_object</span> = content_object
            book.<span style="color: black;">save</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
            request.<span style="color: #dc143c;">user</span>.<span style="color: black;">message_set</span>.<span style="color: black;">create</span><span style="color: black;">&#40;</span>
                message=
                _<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Successfully created book '%s'&quot;</span><span style="color: black;">&#41;</span>
                <span style="color: #66cc66;">%</span> book.<span style="color: black;">name</span><span style="color: black;">&#41;</span>
            <span style="color: #808080; font-style: italic;"># send to object page or book page</span>
            <span style="color: #ff7700;font-weight:bold;">try</span>:
                <span style="color: #ff7700;font-weight:bold;">return</span> HttpResponseRedirect<span style="color: black;">&#40;</span>
                    content_object.<span style="color: black;">get_absolute_url</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
                <span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">except</span>:
                <span style="color: #ff7700;font-weight:bold;">return</span> HttpResponseRedirect<span style="color: black;">&#40;</span>reverse<span style="color: black;">&#40;</span>
                    <span style="color: #483d8b;">'book_details'</span>, args=<span style="color: black;">&#40;</span>book.<span style="color: #008000;">id</span>,<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #808080; font-style: italic;"># if invalid, it gets displayed below</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>:
        book_form = NewBookForm<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">return</span> render_to_response<span style="color: black;">&#40;</span>template_name, <span style="color: black;">&#123;</span>
        <span style="color: #483d8b;">'book_form'</span>: book_form,
    <span style="color: black;">&#125;</span>, context_instance=RequestContext<span style="color: black;">&#40;</span>request<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
@login_required
<span style="color: #ff7700;font-weight:bold;">def</span> details<span style="color: black;">&#40;</span>request, book_id,
    template_name=<span style="color: #483d8b;">&quot;books/details.html&quot;</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;
    displays details of a book
    &quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
    book = get_object_or_404<span style="color: black;">&#40;</span>Book, <span style="color: #008000;">id</span>=book_id<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> render_to_response<span style="color: black;">&#40;</span>template_name, <span style="color: black;">&#123;</span>
        <span style="color: #483d8b;">'book'</span>: book,
    <span style="color: black;">&#125;</span>, context_instance=RequestContext<span style="color: black;">&#40;</span>request<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></div></div>

<h3>urls.py</h3>
<p>To tie our views to some urls, add this to the urls.py file.</p>

<div class="wp_syntax"><div class="code"><pre class="python"><span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">conf</span>.<span style="color: black;">urls</span>.<span style="color: black;">defaults</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">conf</span>.<span style="color: black;">urls</span>.<span style="color: black;">defaults</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
&nbsp;
urlpatterns = patterns<span style="color: black;">&#40;</span><span style="color: #483d8b;">''</span>,    
    <span style="color: #808080; font-style: italic;"># new book for object</span>
    url<span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'^new/(?P&lt;content_type_id&gt;<span style="color: #000099; font-weight: bold;">\d</span>+)/(?P&lt;object_id&gt;<span style="color: #000099; font-weight: bold;">\d</span>+)'</span>, 
        <span style="color: #483d8b;">'books.views.new'</span>, name=<span style="color: #483d8b;">&quot;new_book&quot;</span><span style="color: black;">&#41;</span>,
    <span style="color: #808080; font-style: italic;"># display details of a book</span>
    url<span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'^details/(?P&lt;book_id&gt;<span style="color: #000099; font-weight: bold;">\d</span>+)$'</span>, <span style="color: #483d8b;">'books.views.details'</span>, 
        name=<span style="color: #483d8b;">&quot;book_details&quot;</span><span style="color: black;">&#41;</span>,
<span style="color: black;">&#41;</span></pre></div></div>

<h3>More Features</h3>
<p>The rest of the application is described in the post titled: 
<a  href="http://codespatter.com/2009/01/22/how-to-write-django-template-tags/">How to Write Django Template Tags</a>. You can also check out all of the code from the 
<a  href="http://django-books.googlecode.com" onclick="javascript:pageTracker._trackPageview('/external/django-books.googlecode.com');" >google project</a> by doing the following command:</p>
<p>svn co http://django-books.googlecode.com/svn/trunk books</p>
<p>in a directory on the python path.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fcodespatter.com%2F2009%2F01%2F15%2Fhow-to-write-reusable-apps-for-pinax-and-django%2F';
  addthis_title  = 'How+to+Write+Reusable+Apps+for+Pinax+and+Django';
  addthis_pub    = 'gallard';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>


<p>Related posts:</p><ol><li><a href='http://codespatter.com/2009/01/22/how-to-write-django-template-tags/' rel='bookmark' title='Permanent Link: How to Write Django Template Tags'>How to Write Django Template Tags</a> <small>Template t</small></li><li><a href='http://codespatter.com/2009/04/10/how-to-add-locations-to-python-path-for-reusable-django-apps/' rel='bookmark' title='Permanent Link: How to Add Locations to Python Path for Reusable Django Apps'>How to Add Locations to Python Path for Reusable Django Apps</a> <small>In my 
pre</small></li><li><a href='http://codespatter.com/2008/12/22/django-requestcontext-example/' rel='bookmark' title='Permanent Link: Django RequestContext Example'>Django RequestContext Example</a> <small>Browsing o</small></li></ol><img src="http://feeds.feedburner.com/~r/CodeSpatter/~4/xrZzSg9DM-s" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://codespatter.com/2009/01/15/how-to-write-reusable-apps-for-pinax-and-django/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://codespatter.com/2009/01/15/how-to-write-reusable-apps-for-pinax-and-django/</feedburner:origLink></item>
		<item>
		<title>Django Settings Site Domain example.com</title>
		<link>http://feedproxy.google.com/~r/CodeSpatter/~3/_ZsiBvduVfg/</link>
		<comments>http://codespatter.com/2009/01/05/django-settings-site-domain-examplecom/#comments</comments>
		<pubDate>Mon, 05 Jan 2009 15:11:33 +0000</pubDate>
		<dc:creator>Greg Allard</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://codespatter.com/?p=199</guid>
		<description><![CDATA[It took me a while to figure out how to change from the default, example.com. Maybe it should have been obvious, but I was looking in all the wrong places and every search I did wouldn&#8217;t come up with an answer. As I discovered, it isn&#8217;t a setting in the settings.py file. It&#8217;s something that [...]


Related posts:<ol><li><a href='http://codespatter.com/2009/06/18/django-single-sign-on-or-a-solution-to-multi-domain-cookies/' rel='bookmark' title='Permanent Link: Django Single Sign On or a Solution to Multi-domain Cookies'>Django Single Sign On or a Solution to Multi-domain Cookies</a> <small>I&#8217;ve</small></li><li><a href='http://codespatter.com/2009/04/23/how-to-speed-up-your-django-sites/' rel='bookmark' title='Permanent Link: How to Speed up Your Django Sites with NginX, Memcached, and django-compress'>How to Speed up Your Django Sites with NginX, Memcached, and django-compress</a> <small>A lot of t</small></li><li><a href='http://codespatter.com/2009/04/10/how-to-add-locations-to-python-path-for-reusable-django-apps/' rel='bookmark' title='Permanent Link: How to Add Locations to Python Path for Reusable Django Apps'>How to Add Locations to Python Path for Reusable Django Apps</a> <small>In my 
pre</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>It took me a while to figure out how to change from the default, example.com. Maybe it should have been obvious, but I was looking in all the wrong places and every search I did wouldn&#8217;t come up with an answer. As I discovered, it isn&#8217;t a setting in the settings.py file. It&#8217;s something that is in the database. You can change it through the Django admin interface, phpMyAdmin, or how ever you feel comfortable. It&#8217;s in the django_site table. When setting SITE_ID in settings.py it is the ID in this table. And this is the information that Site.objects.get_current().domain uses. Which is awesome for rss feeds and e-mails that you send out or anytime you need the domain in a link.</p>

<div class="wp_syntax"><div class="code"><pre class="python"><span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">contrib</span>.<span style="color: black;">sites</span>.<span style="color: black;">models</span> <span style="color: #ff7700;font-weight:bold;">import</span> Site
domain = Site.<span style="color: black;">objects</span>.<span style="color: black;">get_current</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">domain</span></pre></div></div>

<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fcodespatter.com%2F2009%2F01%2F05%2Fdjango-settings-site-domain-examplecom%2F';
  addthis_title  = 'Django+Settings+Site+Domain+example.com';
  addthis_pub    = 'gallard';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>


<p>Related posts:</p><ol><li><a href='http://codespatter.com/2009/06/18/django-single-sign-on-or-a-solution-to-multi-domain-cookies/' rel='bookmark' title='Permanent Link: Django Single Sign On or a Solution to Multi-domain Cookies'>Django Single Sign On or a Solution to Multi-domain Cookies</a> <small>I&#8217;ve</small></li><li><a href='http://codespatter.com/2009/04/23/how-to-speed-up-your-django-sites/' rel='bookmark' title='Permanent Link: How to Speed up Your Django Sites with NginX, Memcached, and django-compress'>How to Speed up Your Django Sites with NginX, Memcached, and django-compress</a> <small>A lot of t</small></li><li><a href='http://codespatter.com/2009/04/10/how-to-add-locations-to-python-path-for-reusable-django-apps/' rel='bookmark' title='Permanent Link: How to Add Locations to Python Path for Reusable Django Apps'>How to Add Locations to Python Path for Reusable Django Apps</a> <small>In my 
pre</small></li></ol><img src="http://feeds.feedburner.com/~r/CodeSpatter/~4/_ZsiBvduVfg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://codespatter.com/2009/01/05/django-settings-site-domain-examplecom/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://codespatter.com/2009/01/05/django-settings-site-domain-examplecom/</feedburner:origLink></item>
	</channel>
</rss><!-- Dynamic page generated in 7.179 seconds. --><!-- Cached page generated by WP-Super-Cache on 2009-07-15 14:30:31 --><!-- Compression = gzip -->
