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

<channel>
	<title>if(is_geek)... &#187; Projects</title>
	<atom:link href="http://www.ifisgeek.com/tag/projects/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.ifisgeek.com</link>
	<description>Look! A New Doot!</description>
	<lastBuildDate>Thu, 03 Sep 2009 04:51:49 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Running JSLint in Automated Build Scripts</title>
		<link>http://www.ifisgeek.com/2009/05/05/running-jslint-in-automated-build-scripts/</link>
		<comments>http://www.ifisgeek.com/2009/05/05/running-jslint-in-automated-build-scripts/#comments</comments>
		<pubDate>Tue, 05 May 2009 18:29:14 +0000</pubDate>
		<dc:creator>Jeffery Read</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[VendAsta]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[build scripts]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://www.ifisgeek.com/?p=224</guid>
		<description><![CDATA[At VendAsta we use automated build scripts and a TeamCity server for continuous integration. Whenever someone commits code to a project, a whole suite of automated build targets are run against the code base to check things like unit tests, python syntax (via pylint) and code coverage. One thing that was missing from the mix [...]]]></description>
			<content:encoded><![CDATA[<p>At <a href="http://www.vendasta.com">VendAsta</a> we use automated build scripts and a <a href="http://www.jetbrains.com/teamcity/">TeamCity</a> server for continuous integration. Whenever someone commits code to a project, a whole suite of automated build targets are run against the code base to check things like unit tests, python syntax (via pylint) and code coverage. One thing that was missing from the mix was the automated running of jslint to check the syntax of our ever-increasing corpus of JavaScript code. As it turns out, adding this to our ANT targets wasn&#8217;t all that difficult.</p>
<p>The only real difficulty you are likely to encounter in creating a JSLint target for your build scripts is that JSLint is, itself, written in JavaScript. Other helpful libraries such as JSMin or the YUICompressor from Yahoo are distributed as jar files and can be executed easily with an <code>exec</code> block with the executable set to java. With JSLint, however, you are going to need a JavaScript engine which you can execute from the command line in order to run the JSLint script to validate your JavaScript code. THis actually sounds harder than it is.</p>
<p>For our implementation, I chose to use the <a href="http://www.mozilla.org/rhino/">Rhino</a> engine since there is documented support for JSLint on it, and even a handy helper file to include in your system: <a href="http://www.JSLint.com/rhino/rhino.js">rhino.js</a>. Grab a copy of Rhino (the actual file you&#8217;ll want to include is js.jar), the Rhino helper script I just mentioned and <a href="http://www.JSLint.com/fulljslint.js">JSLint itself</a>. Place them all together into some sort of tools directory in your project. Ours is located in /tools/ant.</p>
<p>Now comes the fun part, writing the actual target in ANT. For our purposes, we want to process all .js files contained in a particular location, as defined in a build property called <code>jsdir</code>. We also want to ignore any files that are contained in a vendor subdirectory of <code>jsdir</code>, as we should not need to worry about third-party scripts that don&#8217;t pass JSLint. Let&#8217;s get things started with our basic, empty target:</p>
<p>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">&lt;!-- </span>
<span style="color: #808080; font-style: italic;">jslint - Runs lint checks on js files</span>
<span style="color: #808080; font-style: italic;">--&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;target</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;jslint&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/target<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<h5>Listing 1: The basic, empty jslint target</h5>
</p>
<p>Within the target there are two things we are going to need. First a way to reference all of the files we want to operate over and second, the actual call to run JSLint on those files. For the first requirement we&#8217;ll use a <code>pathconvert</code> tag with a nested <code>fileset</code>. The <code>pathconvert</code> will allow us to generate a space-separated list of files and stuff that into a property which we&#8217;ll call <code>jsfiles</code>. The <code>fileset</code> block will do the actual work of finding the files in question. It will operate over <code>${jsdir}</code> including all .js files and excluding all .js files in the vendor subdirectory. Listing 2 shows the <code>pathconvert</code> block added to our empty target.</p>
<p>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">&lt;!-- </span>
<span style="color: #808080; font-style: italic;">jslint - Runs lint checks on js files</span>
<span style="color: #808080; font-style: italic;">--&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;target</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;jslint&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;pathconvert</span> <span style="color: #000066;">pathsep</span>=<span style="color: #ff0000;">&quot; &quot;</span> <span style="color: #000066;">property</span>=<span style="color: #ff0000;">&quot;jsfiles&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${jsdir}&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;include</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;**/*.js&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;exclude</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;vendor/**/*.js&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/fileset<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/pathconvert<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/target<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<h5>Listing 2: The <code>pathconvert</code> block added to our target.</h5>
</p>
<p>Finally, it is time to add the actual call to JSLint. To allow our build scripts to work for multiple projects, we have pushed as much information into properties that get defined in project-specific files as possible. The location of the Rhino jar (js.jar) is placed into the property <code>js.jar</code> and the location of the JSLint script (jslint.js) is placed into the property <code>jslint.js</code>. With those properties suitably defined elsewhere, we have the final piece of our puzzle: the <code>exec</code> block. We have the executable set to java and failonerror set to true, so that our target will appropriately fail when JSLint fails to give our code a passing grade. The final target, including the <code>exec</code> block can be seen in listing 3.</p>
<p>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">&lt;!-- </span>
<span style="color: #808080; font-style: italic;">jslint - Runs lint checks on js files</span>
<span style="color: #808080; font-style: italic;">--&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;target</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;jslint&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;pathconvert</span> <span style="color: #000066;">pathsep</span>=<span style="color: #ff0000;">&quot; &quot;</span> <span style="color: #000066;">property</span>=<span style="color: #ff0000;">&quot;jsfiles&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fileset</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${jsdir}&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;include</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;**/*.js&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;exclude</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;vendor/**/*.js&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/fileset<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/pathconvert<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;exec</span> <span style="color: #000066;">dir</span>=<span style="color: #ff0000;">&quot;${jsdir}&quot;</span> <span style="color: #000066;">executable</span>=<span style="color: #ff0000;">&quot;java&quot;</span> <span style="color: #000066;">failonerror</span>=<span style="color: #ff0000;">&quot;true&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;arg</span> <span style="color: #000066;">line</span>=<span style="color: #ff0000;">&quot;-jar ${js.jar} ${jslint.js} ${jsfiles}&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/exec<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/target<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<h5>Listing 3: The final target.</h5>
</p>
<p>Put all together, the <code>pathconvert</code> block stuffs the list of files to work on into the property <code>${jsfiles}</code> which is then passed as an argument to the jslint.js file. The jslint.js file is itself the first argument passed to the Rhino JavaScript engine (js.jar) which is run directly by java. Running your <code>ant jslint</code> target should give you some nice feedback on the syntax of your JavaScript code.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ifisgeek.com/2009/05/05/running-jslint-in-automated-build-scripts/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Monitor and Manage Your Rep With StepRep</title>
		<link>http://www.ifisgeek.com/2009/01/27/monitor-and-manage-your-rep-with-steprep/</link>
		<comments>http://www.ifisgeek.com/2009/01/27/monitor-and-manage-your-rep-with-steprep/#comments</comments>
		<pubDate>Wed, 28 Jan 2009 04:01:37 +0000</pubDate>
		<dc:creator>Jeffery Read</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Teh Intertubes]]></category>
		<category><![CDATA[VendAsta]]></category>
		<category><![CDATA[MyFrontSteps]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[StepRep]]></category>

		<guid isPermaLink="false">http://www.ifisgeek.com/?p=190</guid>
		<description><![CDATA[I work with an amazing group of people. The project I am working on is called MyFrontSteps which is a social media application for getting and sharing ]]></description>
			<content:encoded><![CDATA[<p>I work with an amazing group of people. The project I am working on is called <a href="http://ww.myfrontsteps.com">MyFrontSteps</a> which is a social media application for getting and sharing <a href="http://www.myfrontsteps.com>Home Inspiration<a/> and <a href="http://www.myfrontsteps.com">Trusted Referrals</a> to service providers in your area. We&#8217;re working on some pretty challenging stuff and, even though we are progressing rapidly, we are not quite to the point where we have anything public-beta worthy. Our colleagues at the far end of the building, the <a href="http://steprep.myfrontsteps.com">StepRep</a> team, <em>have</em> reached their public beta and it is really impressive!</p>
<p>Whereas the side of the project I work on is focused on dealing with home owners, StepRep is a tool for <a href="http://steprep.myfrontsteps.com">Online Reputation Management</a>, primarily targeted at the service providers that our system will help you recommend to your friends. Of course, it isn&#8217;t just people in the home improvement or real estate industries that have online reputations they need to manage. In fact, software developers and hardcore geeks have online reputations! <em>I</em> have an online reputation! That&#8217;s why I signed up for the beta at <a href="http://steprep.myfrontsteps.com">http://steprep.myfrontsteps.com</a>. I know that I am a little biased by the fact that I work with the people that developed all of this, but I am very impressed with what they have done. From a technical standpoint there is a lot going on that even I find overwhelming and a little &#8220;magical&#8221;.</p>
<div class="right_cutout">
<h4>My Personal StepRep Widget</h4>
<div style="text-align: center;"><iframe frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="http://steprep.myfrontsteps.com/widget/v1?id=63c492ec3fdfc4499cdbe30b3e15f92e&#038;bgColor=eeeeee&#038;borderColor=000000&#038;fontColor=111111&#038;linkColor=222222&#038;vlinkColor=333333&#038;title=My%20StepRep%20Widget&#038;size=small" width="185" height="314"></iframe>
<div><a href="http://steprep.myfrontsteps.com/Saskatoon/Communications-Networking/Computers-Electronics-Internet/Jeffery-Read">Jeffery Read</a></div>
</div>
</div>
<p>The main purpose of StepRep is to allow you to see what people are saying about you and your business on the Internet. This includes anywhere and everywhere that someone might be talking about you. StepRep presents you with this information and allows you to categorize the items as good or bad. The good ones are things that you can use to convince new people that you are the right choice for the work they need done. You can even place these items into a widget that can be slapped on your company website, your personal blog &#8211; anywhere you want to trumpet your achievements and build your reputation. As for the items you think reflect poorly on you, well, obviously you wouldn&#8217;t want to put them in your widget, but you can see where past customers might not have been completely satisfied and do something to change their mind. Flip them to a positive and then slap them in your widget for all to see.</p>
<p>I won&#8217;t even try to discuss anything about how StepRep does what it does so well. Honestly, this is because I don&#8217;t understand a lot of it. The team working on it are very smart and very skilled at what they do. Starting with the next development sprint my team is going to be working closely with that team as we bring the two systems together to help service providers reach a wider audience through the friends of their customers and to help home owners find the best service providers through people they trust. It&#8217;s going to be very exciting and I am hoping that I&#8217;ll be able to learn a few things about how StepRep works.</p>
<p>One last thing I want to mention is how much I love the design work that was done for the StepRep site. I got to see some preliminary designs for the MyFrontSteps site today as well and they blew me away. Marie-Louise has really done an awesome job. This is something I really love about working at VendAsta. I work with people who are very skilled at designing for the web and for maximum usability. The wireframing, mockups and designs that I have seen done in my short time there have amazed me. I came to VendAsta from a company that had plenty of graphic designers in the Marketing department. They were all firmly rooted in the world of print advertising. There were some definite growing pains going on as they started to embrace the new world of web design. Now I am working with people who understand the web and the best practices for developing rich, engaging applications for the web. It&#8217;s freaking awesome!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ifisgeek.com/2009/01/27/monitor-and-manage-your-rep-with-steprep/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Splitting Django Models Into Separate Files</title>
		<link>http://www.ifisgeek.com/2009/01/26/splitting-django-models-into-separate-files/</link>
		<comments>http://www.ifisgeek.com/2009/01/26/splitting-django-models-into-separate-files/#comments</comments>
		<pubDate>Tue, 27 Jan 2009 04:16:38 +0000</pubDate>
		<dc:creator>Jeffery Read</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[VendAsta]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://www.ifisgeek.com/?p=182</guid>
		<description><![CDATA[A little while ago I wrote a post about getting Django unittests to work on DreamHost. The particular problem with the DreamHost setup is that they don&#8217;t allow you to programmatically create and drop databases and the default Django unittest behaviour is to do just that: create a brand new test db, use it and [...]]]></description>
			<content:encoded><![CDATA[<p>A little while ago I wrote a post about <a href="http://www.ifisgeek.com/2008/12/27/django-unittesting-on-dreamhost/">getting Django unittests to work on DreamHost</a>. The particular problem with the DreamHost setup is that they don&#8217;t allow you to programmatically create and drop databases and the default Django unittest behaviour is to do just that: create a brand new test db, use it and then drop it. Since I wrote that post I have begun migrating all of my domains away from DreamHost but I have still found that technique to be useful with new projects.</p>
<p>I first started using Django when I started at VendAsta and this issue didn&#8217;t creep up there because we are use Google App Engine and its DataStore on the backend instead of a traditional database. With no database there was no issue with creating/dropping anything. It was only when I started using Django on my own that I came across that problem. There was one more issue with Django that I came across only when I started doing things outside of work: Django expects all of your models to be in a single file called models.py. I hate that. A lot.</p>
<p>I did some googling about the problem and found that there were a bunch of other people who didn&#8217;t like it much either. There were a few solutions but they all involved manually mucking about with the __all__ attribute in the __init__.py file of your models directory. Sure, it works, but I don&#8217;t like having to define a model in two places to use it. Oddly enough it was in some test code at work that I found the answer.</p>
<p>For our project at VendAsta we are using the Django App Engine Helper to provide a nice easy interface to the DataStore on the backend. A part of this is a small __init__.py file which allows you to spread your tests out in multiple files. Django likes its tests to be in a single tests.py file just like it likes its models to be in models.py. The wee bit of Google code is shown in Listing 1.</p>
<p>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/python2.4</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;"># Copyright 2008 Google Inc.</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;"># Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);</span>
<span style="color: #808080; font-style: italic;"># you may not use this file except in compliance with the License.</span>
<span style="color: #808080; font-style: italic;"># You may obtain a copy of the License at</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;">#     http://www.apache.org/licenses/LICENSE-2.0</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;"># Unless required by applicable law or agreed to in writing, software</span>
<span style="color: #808080; font-style: italic;"># distributed under the License is distributed on an &quot;AS IS&quot; BASIS,</span>
<span style="color: #808080; font-style: italic;"># WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span>
<span style="color: #808080; font-style: italic;"># See the License for the specific language governing permissions and</span>
<span style="color: #808080; font-style: italic;"># limitations under the License.</span>
&nbsp;
&nbsp;
&nbsp;
&nbsp;
<span style="color: #483d8b;">&quot;&quot;&quot;Loads all the _test.py files into the top level of the package.
&nbsp;
This file is a hack around the fact that Django expects the tests &quot;module&quot; to
be a single tests.py file and cannot handle a tests package inside an
application.
&nbsp;
All _test.py files inside this package are imported and any classes derived
from unittest.TestCase are then referenced from this file itself so that they
appear at the top level of the tests &quot;module&quot; that Django will import.
&quot;&quot;&quot;</span>
&nbsp;
<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;">re</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">types</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">unittest</span>
&nbsp;
PACKAGE = <span style="color: #483d8b;">'appname.tests'</span>
TEST_RE = r<span style="color: #483d8b;">&quot;^.*_test.py$&quot;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Search through every file inside this package.</span>
test_names = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
test_dir = <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: #ff7700;font-weight:bold;">for</span> filename <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">listdir</span><span style="color: black;">&#40;</span>test_dir<span style="color: black;">&#41;</span>:
  <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">match</span><span style="color: black;">&#40;</span>TEST_RE, filename<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">continue</span>
  <span style="color: #808080; font-style: italic;"># Import the test file and find all TestClass clases inside it.</span>
  test_module = <span style="color: #008000;">__import__</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'%s.%s'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>PACKAGE, filename<span style="color: black;">&#91;</span>:-3<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>, 
                           <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>, <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>,
                           filename<span style="color: black;">&#91;</span>:-3<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
  <span style="color: #ff7700;font-weight:bold;">for</span> name <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">dir</span><span style="color: black;">&#40;</span>test_module<span style="color: black;">&#41;</span>:
    item = <span style="color: #008000;">getattr</span><span style="color: black;">&#40;</span>test_module, name<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: black;">&#40;</span><span style="color: #008000;">isinstance</span><span style="color: black;">&#40;</span>item, <span style="color: black;">&#40;</span><span style="color: #008000;">type</span>, <span style="color: #dc143c;">types</span>.<span style="color: black;">ClassType</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">and</span>
            <span style="color: #008000;">issubclass</span><span style="color: black;">&#40;</span>item, <span style="color: #dc143c;">unittest</span>.<span style="color: black;">TestCase</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>:
      <span style="color: #ff7700;font-weight:bold;">continue</span>
    <span style="color: #808080; font-style: italic;"># Found a test, bring into the module namespace.</span>
    <span style="color: #ff7700;font-weight:bold;">exec</span> <span style="color: #483d8b;">&quot;%s = item&quot;</span> <span style="color: #66cc66;">%</span> name
    test_names.<span style="color: black;">append</span><span style="color: black;">&#40;</span>name<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Hide everything other than the test cases from other modules.</span>
__all__ = test_names</pre></td></tr></table></div>

<h5>Listing 1: __init__.py file from Google for a tests module</h5>
</p>
<p>Essentially what this file does is loop through all files in the same directory and for each on that matches the pattern listed on line 40 (in this case, files that end in &#8216;_test.py&#8217;) and import all of the Classes from those files that are subclasses of the TestCase class. Finally, the code on line 62 does the magic with __all__ that I wanted to avoid doing manually for my models. It was this line that caught my attention and started me wondering if this code could be used for spreading models across multiple files.</p>
<p>In order for this to work for models there are a few things that need to be changed. First of all, on line 40, the pattern should be changed to match on *.py to grab all of the python files in the directory. Then, on line 46, add<br />
<blockquote> or filename == &#8220;__init__.py&#8221;</p></blockquote>
<p> to ensure that we don&#8217;t try to import the file we are in. Finally, remove the subclass requirement from line 55, as we are just concerned with importing classes here not what they inherit from. Putting it all together results in Listing 2. Place that in the __init__.py of a directory called models and you&#8217;ll not have to manually manage the __all__ list for your models in separate files.</p>
<p>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/python2.4</span>
&nbsp;
<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;">re</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">types</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">unittest</span>
&nbsp;
PACKAGE = <span style="color: #483d8b;">'my_app.models'</span>
MODEL_RE = r<span style="color: #483d8b;">&quot;^.*.py$&quot;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Search through every file inside this package.</span>
model_names = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
model_dir = <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: #ff7700;font-weight:bold;">for</span> filename <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">listdir</span><span style="color: black;">&#40;</span>model_dir<span style="color: black;">&#41;</span>:
  <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">match</span><span style="color: black;">&#40;</span>MODEL_RE, filename<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">or</span> filename == <span style="color: #483d8b;">&quot;__init__.py&quot;</span>:
    <span style="color: #ff7700;font-weight:bold;">continue</span>
  <span style="color: #808080; font-style: italic;"># Import the model file and find all clases inside it.</span>
  model_module = <span style="color: #008000;">__import__</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'%s.%s'</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>PACKAGE, filename<span style="color: black;">&#91;</span>:-3<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>,
                           <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>, <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>,
                           filename<span style="color: black;">&#91;</span>:-3<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
  <span style="color: #ff7700;font-weight:bold;">for</span> name <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">dir</span><span style="color: black;">&#40;</span>model_module<span style="color: black;">&#41;</span>:
    item = <span style="color: #008000;">getattr</span><span style="color: black;">&#40;</span>model_module, name<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">isinstance</span><span style="color: black;">&#40;</span>item, <span style="color: black;">&#40;</span><span style="color: #008000;">type</span>, <span style="color: #dc143c;">types</span>.<span style="color: black;">ClassType</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>:
      <span style="color: #ff7700;font-weight:bold;">continue</span>
    <span style="color: #808080; font-style: italic;"># Found a model, bring into the module namespace.</span>
    <span style="color: #ff7700;font-weight:bold;">exec</span> <span style="color: #483d8b;">&quot;%s = item&quot;</span> <span style="color: #66cc66;">%</span> name
    model_names.<span style="color: black;">append</span><span style="color: black;">&#40;</span>name<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Hide everything other than the classes from other modules.</span>
__all__ = model_names</pre></td></tr></table></div>

<h5>Listing 2: __init__.py file modified for a models module</h5>
</p>
<p>Now, there is one last thing that you are going to need to do in order for everything to run properly in Django. It is a very simple addition to the end of each of your classes. I have seem some people complaining about the need to do this in various forums, but honestly, if you are using any form of modern text editing application, it should only take you about 2 minutes to create a new template for a model that has the little piece of code shown in Listing 3 at the bottom of the class (replace your_app_name with your actual app name).</p>
<p>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> Meta:
        <span style="color: #483d8b;">&quot;&quot;&quot;Meta Class for your model.&quot;&quot;&quot;</span>
        app_label = <span style="color: #483d8b;">'your_app_name'</span></pre></td></tr></table></div>

<h5>Listing 3: Meta class required at the end of each model for proper functioning.</h5></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ifisgeek.com/2009/01/26/splitting-django-models-into-separate-files/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
