<?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:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Gary Wilson &#187; Django</title>
	<atom:link href="http://gdub.wordpress.com/category/django/feed/" rel="self" type="application/rss+xml" />
	<link>http://gdub.wordpress.com</link>
	<description></description>
	<pubDate>Mon, 28 Apr 2008 15:09:52 +0000</pubDate>
	<generator>http://wordpress.org/?v=MU</generator>
	<language></language>
			<item>
		<title>Texas Python Regional Unconference</title>
		<link>http://gdub.wordpress.com/2007/09/03/texas-python-regional-unconference/</link>
		<comments>http://gdub.wordpress.com/2007/09/03/texas-python-regional-unconference/#comments</comments>
		<pubDate>Mon, 03 Sep 2007 15:47:40 +0000</pubDate>
		<dc:creator>Gary</dc:creator>
		
		<category><![CDATA[Django]]></category>

		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://gdub.wordpress.com/2007/09/03/texas-python-regional-unconference/</guid>
		<description><![CDATA[Just a quick announcement for all the Houston and surrounding area Python lovers out there.  There is a Texas Python Regional Unconference being held in a couple weeks (Sept. 15 - 16) at the University of Houston main campus.  Registration is free and as simple as adding your name to the registration wiki [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Just a quick announcement for all the Houston and surrounding area Python lovers out there.  There is a <a href="http://pycamp.python.org/Texas/HomePage">Texas Python Regional Unconference</a> being held in a couple weeks (Sept. 15 - 16) at the University of Houston main campus.  Registration is free and as simple as adding your name to the <a href="http://pycamp.python.org/Texas/Registration">registration wiki page</a>.  I&#8217;ll be there to talk or hack Django with anyone interested.  See you there!</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/gdub.wordpress.com/23/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/gdub.wordpress.com/23/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gdub.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gdub.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gdub.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gdub.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gdub.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gdub.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gdub.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gdub.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gdub.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gdub.wordpress.com/23/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gdub.wordpress.com&blog=111318&post=23&subd=gdub&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://gdub.wordpress.com/2007/09/03/texas-python-regional-unconference/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Hacking Django, how Bazaar</title>
		<link>http://gdub.wordpress.com/2007/01/11/hacking-django-how-bazaar/</link>
		<comments>http://gdub.wordpress.com/2007/01/11/hacking-django-how-bazaar/#comments</comments>
		<pubDate>Thu, 11 Jan 2007 06:08:05 +0000</pubDate>
		<dc:creator>Gary</dc:creator>
		
		<category><![CDATA[Django]]></category>

		<guid isPermaLink="false">http://gdub.wordpress.com/2007/01/11/hacking-django-how-bazaar/</guid>
		<description><![CDATA[A short while ago, I went on a mission to find a better way to hack Django.  I needed a way to keep my patches organized and updated.  So, in this article I discuss my experiences with a tool I found to help me achieve these goals&#8230;
Enter Bazaar, one of the several distributed [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>A short while ago, I went on a mission to find a better way to hack <a href="http://www.djangoproject.com/">Django</a>.  I needed a way to keep my patches organized and updated.  So, in this article I discuss my experiences with a tool I found to help me achieve these goals&#8230;</p>
<p>Enter <a href="http://bazaar-vcs.org/">Bazaar</a>, one of the several <a href="http://en.wikipedia.org/wiki/Version_control_system#Distributed_version_control">distributed version control systems</a> that have been getting some hype recently.  With <a href="http://en.wikipedia.org/wiki/Comparison_of_revision_control_software">so many to choose from</a>, why did I choose Bazaar?  Well, maybe it was because of the cool name, or maybe it was the pretty website, or maybe just because it&#8217;s written in the language I love &mdash; <a href="http://www.python.org/">Python</a>.  If you are familiar with <a href="http://subversion.tigris.org/">Subversion</a>, then you will feel right at home with Bazaar.  This is because Bazaar uses most of the same commands as Subversion (e.g. <code>svn ci = bzr ci</code>, <code>svn st = bzr st</code>, etc.).</p>
<p>Following <a href="http://jameswestby.net/tips/tips/hacking-a-project-with-bzr.html">this guide for hacking an open source project using bzr</a>, I created a <code>django</code> directory to stash my django hacks.  After using svn to check out the latest Django code to a directory named <code>upstream</code>, and turning <code>upstream</code> into a bzr repository too, it was time to start the real work.  To re-iterate in command line speak, here is what I did:</p>
<p><strong>Update:</strong> The steps below have been updated to reflect changes with bzr commands (versions &gt;=0.15rc2).</p>
<pre><code>mkdir django
cd django
bzr init-repo .            # use "bzr init-repo --trees ." here instead if using a version &lt;0.15rc2
svn co http://code.djangoproject.com/svn/django/trunk/ upstream
cd upstream
bzr init
echo ".svn" &gt; .bzrignore   # do not store svn metadata in our bzr repo
bzr add
bzr ci -m 'Initial import of Django.'
</code></pre>
<p>Usually, when you want to add a new feature to some code, you create a branch.  The purpose of these, so called, feature branches is to keep the features separated.  Trying to create multiple features in the same branch would just be a big mess.  Creating branches in a Subversion repository is easy enough, you just <code>svn cp</code> the code to a new location.  It&#8217;s the keeping your branch in sync with the trunk that&#8217;s not as easy.</p>
<p>With Subversion, you have to keep track of the revisions that have already been merged to your branch and make sure to only merge the changes that haven&#8217;t already been merged.  Not so with Bazaar; Bazaar keeps track of this for you.  A simple <code>bzr merge</code> will pull in upstream changes that have not been merged yet.</p>
<p>So, when I wanted to start working on a patch for <a href="http://code.djangoproject.com/ticket/2473">ticket #2473</a>, I created a branch:</p>
<pre><code>bzr branch upstream in-and-empty-list-2473</code></pre>
<p>After <code>cd</code>&#8216;ing into my new branch and committing my changes, I created a diff to attach to the ticket with the command:</p>
<pre><code>bzr diff -r branch:../upstream</code></pre>
<p>So far, working with Bazaar has been a breeze.  Without it, <a href="http://code.djangoproject.com/ticket/2473">my</a> <a href="http://code.djangoproject.com/ticket/2756">Django</a> <a href="http://code.djangoproject.com/ticket/3180">holiday</a> <a href="http://code.djangoproject.com/ticket/3182">hacking</a> wouldn&#8217;t have been nearly as fun.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/gdub.wordpress.com/14/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/gdub.wordpress.com/14/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gdub.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gdub.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gdub.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gdub.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gdub.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gdub.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gdub.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gdub.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gdub.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gdub.wordpress.com/14/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gdub.wordpress.com&blog=111318&post=14&subd=gdub&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://gdub.wordpress.com/2007/01/11/hacking-django-how-bazaar/feed/</wfw:commentRss>
		</item>
		<item>
		<title>is_authenticated() vs. is_anonymous()</title>
		<link>http://gdub.wordpress.com/2006/09/23/is_authenticated-vs-is_anonymous/</link>
		<comments>http://gdub.wordpress.com/2006/09/23/is_authenticated-vs-is_anonymous/#comments</comments>
		<pubDate>Sat, 23 Sep 2006 17:45:28 +0000</pubDate>
		<dc:creator>Gary</dc:creator>
		
		<category><![CDATA[Django]]></category>

		<guid isPermaLink="false">http://gdub.wordpress.com/2006/09/23/is_authenticated-vs-is_anonymous/</guid>
		<description><![CDATA[A warning for those who might not of noticed the change.  About a month ago (in [3360]), an is_authenticated method was added to the User and AnonymousUser classes.  These are the classes used for Django&#8217;s default authentication system.
Previously, the template code used for displaying content based on whether or not a user had [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>A warning for those who might not of noticed the change.  About a month ago (in <a href="http://code.djangoproject.com/changeset/3360">[3360]</a>), an <code>is_authenticated</code> method was added to the User and AnonymousUser classes.  These are the classes used for Django&#8217;s default authentication system.</p>
<p>Previously, the template code used for displaying content based on whether or not a user had authenticated went something like:</p>
<blockquote>
<pre>
{% if not user.is_anonymous %}
Content for logged in users.
{% else %}
Content for non-logged in users.
{% endif %}
</pre>
</blockquote>
<p>The problem with this code is that if, somehow, the <code>user</code> template variable did not get populated, your template would treat the requesting user as if they were logged in.</p>
<p>Notice that this sort of behavior will be seen for <strong>all</strong> negative if statements.  The template code <code>{% if not variable %}</code> will always evaluate to True if <code>variable</code> doesn&#8217;t exist in the context.  This is because Django uses the <a href="http://www.djangoproject.com/documentation/settings/#template-string-if-invalid">settings.TEMPLATE_STRING_IF_INVALID </a> value for non-existent template variables; by default, TEMPLATE_STRING_IF_INVALID is <code>''</code>, which evaluates to False (and not False is True).</p>
<p>Notice also that even using the template code:</p>
<blockquote>
<pre>
{% if user.is_anonymous %}
Content for non-logged in users.
{% else %}
Content for logged in users.
{% endif %}
</pre>
</blockquote>
<p>(without the &#34;not&#34; ) will not work in this case because if the <code>user</code> variable is non-existent, the requesting user will still be treated as if they were authenticated.</p>
<p>The new recommended way for checking that a requesting user has been authenticated in your templates is:</p>
<blockquote>
<pre>
{% if user.is_authenticated %}
Content for logged in users.
{% else %}
Content for non-logged in users
{% endif %}
</pre>
</blockquote>
<p>Here, if the <code>user</code> template variable were to not exist your template would treat the requesting user as non-authenticated, just as we would want.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/gdub.wordpress.com/13/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/gdub.wordpress.com/13/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gdub.wordpress.com/13/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gdub.wordpress.com/13/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gdub.wordpress.com/13/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gdub.wordpress.com/13/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gdub.wordpress.com/13/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gdub.wordpress.com/13/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gdub.wordpress.com/13/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gdub.wordpress.com/13/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gdub.wordpress.com/13/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gdub.wordpress.com/13/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gdub.wordpress.com&blog=111318&post=13&subd=gdub&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://gdub.wordpress.com/2006/09/23/is_authenticated-vs-is_anonymous/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Using CrackLib to require stronger passwords</title>
		<link>http://gdub.wordpress.com/2006/08/26/using-cracklib-to-require-stronger-passwords/</link>
		<comments>http://gdub.wordpress.com/2006/08/26/using-cracklib-to-require-stronger-passwords/#comments</comments>
		<pubDate>Sun, 27 Aug 2006 02:57:00 +0000</pubDate>
		<dc:creator>Gary</dc:creator>
		
		<category><![CDATA[Django]]></category>

		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">https://gdub.wordpress.com/2006/08/26/using-cracklib-to-require-stronger-passwords/</guid>
		<description><![CDATA[Let&#8217;s face it, humans are not well adapted to memorizing strings of random characters; and hence, the average computer user is not very good at creating secure passwords.  Most users create passwords made up of easy-to-remember words, like the name of a favorite sports team or maybe the name of a significant other.  [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Let&#8217;s face it, humans are not well adapted to memorizing strings of random characters; and hence, the average computer user is not very good at creating <a href="http://www.usewisdom.com/computer/passwords.html">secure passwords</a>.  Most users create passwords made up of easy-to-remember words, like the name of a <a href="http://www.mackbrown-texasfootball.com/">favorite sports team</a> or maybe the name of a significant other.  In this article I will show you how you can make Django require better passwords from your users.</p>
<p>Here are the packages you will need:</p>
<ul>
<li><a href="http://sourceforge.net/projects/cracklib/">CrackLib</a></li>
<li><a href="http://www.nongnu.org/python-crack/">python-crack</a></li>
</ul>
<h2>Installing the required packages</h2>
<p><strong>Step 1: Install CrackLib.</strong><br />
CrackLib is a library for checking that passwords are not easily crackable, or in other words, it makes sure that a password is not based on a simple character pattern or on a dictionary word.  CrackLib is a common package that you should be able to find in your distribution&#8217;s package manager (or, quite possibly, it could already be installed).  Alternatively, you could download the source and follow the installation instructions in the README file.  By default, CrackLib installs a python package named cracklib, but it does not have as many features as python-crack.  (Redhat does not include the cracklib python package in its cracklib package.)</p>
<p><strong>Step 2 (optional, but recommended): Install extra word dictionaries.</strong><br />
Packaged with CrackLib is a file name <code>cracklib-small</code>.  (Some distributions, like RedHat, don&#8217;t include this file in their cracklib package, in which case keep reading&#8230;&#41;  This file is a dictionary of words, simply a long list of words with one word per line.  These 50,000 words are a good start, but we can do better.  On the <a href="http://sourceforge.net/project/showfiles.php?group_id=130213">CrackLib download page</a>, there is also a package named cracklib-words.  After downloading and extracting the package, you will have a single file containing 1,648,379 &#8220;words&#8221;.  Many distributions also have a cracklib-dicts or cracklib-words package that maybe the same or similar to the cracklib-words file on the CrackLib website.</p>
<p>For even more dictionaries, take a look at <a href="http://www.cotse.com/tools/wordlists.htm">these word lists</a>.  It might also be a good idea to create your own list of words.  For example, if you work for a company in the financial industry, it would be a good idea to make a list of words and slang specific to that industry.  If you will be dealing with non-english speaking users, it would be a good idea to find some dictionaries in other languages.</p>
<p><strong>Step 3: Create the word indexes that get used by CrackLib.</strong><br />
Now that we have our dictionaries, we need to compile them into an index that CrackLib uses.  So, put all your dictionaries in one directory (<code>/usr/share/dict/</code> is a common place).  Depending on your distribution, there will be different commands to run.  On gentoo (or if you installed from source), the following (as root) should do the trick:</p>
<blockquote><p>create-cracklib-dict /usr/share/dict/*</p></blockquote>
<p>And on RedHat:</p>
<blockquote><p>mkdict /usr/share/dict/* | packer /usr/lib/cracklib_dict</p></blockquote>
<p>These commands should create the following files:</p>
<blockquote><p>
/usr/lib/cracklib_dict.hwm<br />
/usr/lib/cracklib_dict.pwd<br />
/usr/lib/cracklib_dict.pwi
</p></blockquote>
<p><strong>Step 4: Install python-crack</strong><br />
If your distribution&#8217;s package manager doesn&#8217;t include python-crack, then you will have to download and install it yourself.  Neither Gentoo nor RedHat include this package, so I will walk you through the install.  <a href="http://www.nongnu.org/python-crack/">Download</a> and unpack python-crack.  Now, <code>cd</code> into the directory and run</p>
<blockquote><p>./configure</p></blockquote>
<p>By default, configure will setup python-crack&#8217;s files to be installed to <code>/usr/local</code>.  This means that you will have to add <code>/usr/local/lib/python2.4/site-packages</code> to your <code>PYTHONPATH</code>.  Alternatively, you could add a <code>--prefix=/usr</code> to the end of the configure command to install python-crack&#8217;s files to the usual <code>/usr/lib/python2.4/site-packages</code> directory.</p>
<p>If you get this error:</p>
<blockquote><p>
checking for prefix of the default cracklib dictionary database&#8230; unknown<br />
configure: error: crack.h does not define CRACKLIB_DICTPATH. Please use DEFAULT_DICTPATH, see ./configure &#8211;help
</p></blockquote>
<p>then set the DEFAULT_DICTPATH variable when running configure, like so</p>
<blockquote><p>./configure DEFAULT_DICTPATH=/usr/lib/cracklib_dict</p></blockquote>
<p>Now run</p>
<blockquote><p>
make<br />
make install
</p></blockquote>
<p>Now that we are finished installing, lets test out python-crack</p>
<blockquote><p>
$ python<br />
Python 2.4.3 (#1, Jun 28 2006, 23:41:37)<br />
[GCC 3.4.6 (Gentoo 3.4.6-r1, ssp-3.4.5-1.0, pie-8.7.9)] on linux2<br />
Type &#8220;help&#8221;, &#8220;copyright&#8221;, &#8220;credits&#8221; or &#8220;license&#8221; for more information.<br />
&gt;&gt;&gt; import crack<br />
&gt;&gt;&gt; crack.VeryFascistCheck(&#8217;foo&#8217;&#41;<br />
[snip]<br />
ValueError: it is WAY too short<br />
&gt;&gt;&gt; crack.VeryFascistCheck(&#8217;foobar&#8217;&#41;<br />
[snip]<br />
ValueError: it is based on a dictionary word<br />
&gt;&gt;&gt; crack.VeryFascistCheck(&#8217;3#hsad2U&gt;u2u&#8217;&#41;<br />
&#8216;3#hsad2U&gt;u2u&#8217;
</p></blockquote>
<p><code>VeryFascistCheck()</code> raises a value error and prints an explaination if the password is not strong enough, otherwise it echos back the password.</p>
<h2>Creating the Django Manipulator</h2>
<blockquote>
<pre>
from django import forms

class NewUserForm(forms.Manipulator):
    def __init__(self):
        self.fields = [
            forms.TextField(field_name="username", length=20, maxlength=20, is_required=True),
            forms.PasswordField(field_name="password", length=20, maxlength=50, is_required=True,
                validator_list=[isStrongPassword]),
            forms.PasswordField(field_name="confirm_password", length=20, maxlength=50, is_required=True,
                validator_list=[forms.validators.RequiredIfOtherFieldGiven("password", "You must confirm password"),
                                forms.validators.AlwaysMatchesOtherField("password", "Passwords did not match"),]),
        ]

def isStrongPassword(field_data, all_data):
    """Test the password with cracklib to make sure it is strong."""

    import crack
    # Increase the number of credits required from the default of 8 if you want.
    #crack.min_length = 11
    try:
        crack.VeryFascistCheck(field_data)
    except ValueError, message:
        raise forms.validators.ValidationError, "Password %s." % str(message)[3:]
</pre>
</blockquote>
<p>Notice that I added <code>isStrongPassword</code> to the password field&#8217;s <code>validator_list</code>.  Now you are ready to put the NewUserForm manipulator to use in your you <code>views.py</code>.  After running the manipulator&#8217;s <code>get_validation_errors()</code>, bad passwords will generate errors like &#8220;Password is based on a dictionary word&#8221; or &#8220;Password does not contain enough DIFFERENT characters.&#8221;  For help on using manipulators in your view, see the <a href="http://www.djangoproject.com/documentation/forms/">Forms, fields, and manipulators</a> documentation.</p>
<p>If you want to make Django&#8217;s built-in authentication require stronger passwords, then you could add <code>validator_list=[isStrongPassword]</code> to the password field of <code>django.contrib.auth.models.User</code>.</p>
<p>Now, go forth and require strong passwords.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/gdub.wordpress.com/9/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/gdub.wordpress.com/9/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gdub.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gdub.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gdub.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gdub.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gdub.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gdub.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gdub.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gdub.wordpress.com/9/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gdub.wordpress.com/9/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gdub.wordpress.com/9/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gdub.wordpress.com&blog=111318&post=9&subd=gdub&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://gdub.wordpress.com/2006/08/26/using-cracklib-to-require-stronger-passwords/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Cyclomatic complexity of Django</title>
		<link>http://gdub.wordpress.com/2006/07/09/cyclomatic-complexity-of-django/</link>
		<comments>http://gdub.wordpress.com/2006/07/09/cyclomatic-complexity-of-django/#comments</comments>
		<pubDate>Sun, 09 Jul 2006 06:48:51 +0000</pubDate>
		<dc:creator>Gary</dc:creator>
		
		<category><![CDATA[Django]]></category>

		<category><![CDATA[software development]]></category>

		<guid isPermaLink="false">https://gdub.wordpress.com/?p=11</guid>
		<description><![CDATA[Adrian&#8217;s recent post on the dev mailing list about the code within django.db.models got me remembering some other &#8220;monstrous&#8221; functions I&#8217;ve seen while browsing the Django source.  Guess no more as to the most monstrous functions of Django because below are the results of my previously posted complexity.py script when run on the Django [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><a href="http://groups.google.com/group/django-developers/browse_thread/thread/1026181083385c58/">Adrian&#8217;s recent post</a> on the dev mailing list about the code within <code>django.db.models</code> got me remembering some other &#8220;monstrous&#8221; functions I&#8217;ve seen while browsing the Django source.  Guess no more as to the most monstrous functions of Django because below are the results of my <a href="http://gdub.wordpress.com/2006/07/09/cyclomatic-complexity-for-python-code/">previously posted <code>complexity.py</code> script</a> when run on the Django source.</p>
<p>Adjust your window until you can see all of the following line:</p>
<blockquote>
<pre>
#===============================================================================================================#
</pre>
</blockquote>
<p>Here are all 80 of the functions and methods of Django that are of moderate risk or higher:</p>
<blockquote>
<pre>
Showing functions/methods with complexity greater than or equal to 11:

Filename                                    Function/Method                              Lines of Code Complexity
./core/management.py                        get_validation_errors                                  146         78
./db/models/manipulators.py                 AutomaticManipulator.save                               97         43
./contrib/comments/templatetags/comments.py DoCommentForm.__call__                                  51         31
./views/i18n.py                             javascript_catalog                                      68         28
./contrib/admin/views/main.py               change_stage                                            75         28
./utils/translation/trans_real.py           translation                                             62         26
./bin/make-messages.py                      make_messages                                          114         26
./contrib/admin/views/main.py               _get_deleted_objects                                    65         25
./core/handlers/base.py                     BaseHandler.get_response                                50         24
./views/defaults.py                         shortcut                                                40         23
./contrib/auth/create_superuser.py          createsuperuser                                         64         23
./core/management.py                        inspectdb                                               84         23
./contrib/admin/views/doc.py                model_detail                                            64         22
./templatetags/i18n.py                      do_block_translate                                      41         21
./core/management.py                        syncdb                                                  61         21
./core/management.py                        execute_from_command_line                               74         21
./views/generic/create_update.py            update_object                                           54         20
./contrib/admin/views/decorators.py         staff_member_required                                   44         20
./utils/simplejson/decoder.py               scanstring                                              41         19
./contrib/admin/views/main.py               add_stage                                               51         19
./core/validators.py                        RelaxNGCompact.__call__                                 51         19
./db/models/query.py                        lookup_inner                                           107         19
./db/models/query.py                        delete_objects                                          48         19
./template/__init__.py                      TokenParser.value                                       61         18
./utils/simplejson/decoder.py               JSONObject                                              37         18
./utils/decorators.py                       decorator_from_middleware                               25         18
./contrib/comments/templatetags/comments.py DoGetCommentList.__call__                               31         18
./contrib/comments/views/comments.py        post_comment                                            66         18
./utils/translation/trans_real.py           get_language_from_request                               40         17
./core/mail.py                              send_mass_mail                                          31         17
./views/generic/create_update.py            create_object                                           38         16
./views/static.py                           serve                                                   28         16
./core/servers/fastcgi.py                   runfastcgi                                              56         16
./core/management.py                        get_sql_delete                                          49         16
./db/models/query.py                        QuerySet.__getitem__                                    38         16
./utils/simplejson/encoder.py               floatstr                                                17         15
./utils/simplejson/encoder.py               JSONEncoder._iterencode_dict                            49         15
./views/generic/create_update.py            delete_object                                           36         15
./contrib/comments/templatetags/comments.py DoCommentCount.__call__                                 25         15
./db/models/fields/related.py               create_many_related_manager                             73         15
./db/models/query.py                        QuerySet._get_sql_clause                                54         15
./middleware/common.py                      CommonMiddleware.process_request                        22         14
./template/__init__.py                      Parser.parse                                            35         14
./template/defaulttags.py                   do_if                                                   33         14
./template/defaulttags.py                   cycle                                                   25         14
./views/generic/date_based.py               object_detail                                           43         14
./contrib/comments/views/comments.py        post_free_comment                                       41         14
./contrib/admin/templatetags/admin_list.py  items_for_result                                        59         14
./contrib/admin/views/main.py               get_javascript_imports                                  23         14
./contrib/admin/views/main.py               ChangeList.get_query_set                                39         14
./core/handlers/base.py                     BaseHandler.load_middleware                             32         14
./db/models/base.py                         Model.__init__                                          33         14
./template/defaulttags.py                   SsiNode.render                                          21         13
./views/generic/list_detail.py              object_list                                             46         13
./contrib/auth/handlers/modpython.py        authenhandler                                           28         13
./db/models/fields/__init__.py              Field.get_manipulator_fields                            24         13
./db/models/base.py                         ModelBase.__new__                                       26         13
./dispatch/saferef.py                       safeRef                                                 65         12
./dispatch/dispatcher.py                    _removeOldBackRefs                                      20         12
./template/loader.py                        find_template_source                                    26         12
./template/defaulttags.py                   IfNode.render                                           21         12
./utils/timesince.py                        timesince                                               34         12
./views/generic/date_based.py               archive_month                                           36         12
./core/management.py                        _get_sql_model_create                                   44         12
./conf/__init__.py                          Settings.__init__                                       26         12
./db/models/fields/__init__.py              DateTimeField.to_python                                 14         12
./db/models/related.py                      RelatedObject.get_list                                  21         12
./db/models/options.py                      Options.has_field_type                                  16         12
./dispatch/dispatcher.py                    connect                                                 34         11
./template/defaultfilters.py                pluralize                                               18         11
./utils/simplejson/decoder.py               JSONArray                                               21         11
./views/generic/list_detail.py              object_detail                                           33         11
./views/generic/date_based.py               archive_week                                            31         11
./views/generic/date_based.py               archive_day                                             34         11
./contrib/redirects/middleware.py           RedirectFallbackMiddleware.process_response             17         11
./contrib/admin/templatetags/log.py         DoGetAdminLog.__call__                                  11         11
./db/backends/postgresql/base.py            DatabaseWrapper.cursor                                  21         11
./db/backends/postgresql_psycopg2/base.py   DatabaseWrapper.cursor                                  21         11
./db/models/fields/related.py               ReverseSingleRelatedObjectDescriptor.__get__            19         11
./db/models/query.py                        get_where_clause                                        18         11
</pre>
</blockquote>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/gdub.wordpress.com/11/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/gdub.wordpress.com/11/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gdub.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gdub.wordpress.com/11/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gdub.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gdub.wordpress.com/11/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gdub.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gdub.wordpress.com/11/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gdub.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gdub.wordpress.com/11/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gdub.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gdub.wordpress.com/11/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gdub.wordpress.com&blog=111318&post=11&subd=gdub&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://gdub.wordpress.com/2006/07/09/cyclomatic-complexity-of-django/feed/</wfw:commentRss>
		</item>
		<item>
		<title>News sites that don&#8217;t suck</title>
		<link>http://gdub.wordpress.com/2006/05/20/news-sites-that-dont-suck/</link>
		<comments>http://gdub.wordpress.com/2006/05/20/news-sites-that-dont-suck/#comments</comments>
		<pubDate>Sat, 20 May 2006 07:19:26 +0000</pubDate>
		<dc:creator>Gary</dc:creator>
		
		<category><![CDATA[Austin]]></category>

		<category><![CDATA[Django]]></category>

		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">https://gdub.wordpress.com/2006/05/20/news-sites-that-dont-suck/</guid>
		<description><![CDATA[I sure wish there were news sites in my city that didn&#8217;t suck.  How happy I would be if I could have sites such as the Django-powered 49abcnews or LJWorld to give my attention to each evening.  Instead, I&#8217;m stuck with crappy news site after crappy news site after crappy news site.  [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I sure wish there were news sites in my city that didn&#8217;t suck.  How happy I would be if I could have sites such as the <a href="http://www.djangoproject.com">Django</a>-powered <a href="http://www.49abcnews.com/">49abcnews</a> or <a href="http://www.ljworld.com/">LJWorld</a> to give my attention to each evening.  Instead, I&#8217;m stuck with <a href="http://www.news8austin.com/">crappy news site</a> after <a href="http://www.statesman.com/">crappy news site</a> after <a href="http://www.kvue.com/">crappy news site</a>.  Popups, popovers, registrations, and URLs that make you cringe&#8230;<br />
<code><br />
http://sports.statesman.com/merge/tsnform.aspx?c=statesman&amp;page=mlb/news/index.aspx?sport=AA<br />
http://www.kvue.com/news/top/stories/051906cckrKvurescape.2b620a4.html<br />
</code><br />
Oh my!</p>
<p>To be fair, <a href="http://www.statesman.com">Statesman.com</a> (and its <a href="http://www.austin360.com">Austin360.com</a> entertainment site) is now much more pleasing on the eye due to a major redesign last December.  The redesign seems to have paid off, with the Statesman&#8217;s web site duo recently receiving the top ranking by the <a href="http://www.naa.org/"><acronym title="Newspaper Association of America">NAA</acronym></a> for the greatest local reach among large newspaper sites.  With a monthly readership of 31 percent of Austinites, it edged out <a href="http://www.washingtonpost.com">The Washington Post</a> (27 percent) and the <a href="http://www.signonsandiego.com">San Diego Union-Tribune</a> (23 percent).</p>
<p>In my mind though, Statesman.com fails to deliver the news.  All those headlines on the home page are just a tease to get me to register.  I just want to be able to read the news and <a href="http://www.timesonline.co.uk/article/0,,2-1459390,00.html">find Rolexes in supermarkets</a> without getting hassled.  Is that so much to ask?</p>
<p>LJWorld gets it.  There&#8217;s plenty of content here just begging to be Django-ed.  With Austin being the state&#8217;s capital, land of the <a href="http://www.siliconmaps.com/hills3.html">silicon hills</a>, a <a href="http://www.kiplinger.com/personalfinance/features/archives/2006/05/intro.html">smart place to live</a>, home to <a href="http://www.utexas.edu">one of the largest universities</a> in the U.S. (with plenty of <a href="http://video.google.com/videoplay?docid=-70449010942275062">college girls making out (04:43)</a>), and then there&#8217;s always the <a href="http://www.austintexas.org/music/">Live Music Capital of the World</a> bit.  Austin news sites don&#8217;t get it.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/gdub.wordpress.com/8/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/gdub.wordpress.com/8/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gdub.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gdub.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gdub.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gdub.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gdub.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gdub.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gdub.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gdub.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gdub.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gdub.wordpress.com/8/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gdub.wordpress.com&blog=111318&post=8&subd=gdub&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://gdub.wordpress.com/2006/05/20/news-sites-that-dont-suck/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Form validators that always get tested</title>
		<link>http://gdub.wordpress.com/2006/02/28/form-validators-that-always-get-tested/</link>
		<comments>http://gdub.wordpress.com/2006/02/28/form-validators-that-always-get-tested/#comments</comments>
		<pubDate>Tue, 28 Feb 2006 06:17:21 +0000</pubDate>
		<dc:creator>Gary</dc:creator>
		
		<category><![CDATA[Django]]></category>

		<guid isPermaLink="false">http://gdub.wordpress.com/2006/02/28/form-validators-that-always-get-tested/</guid>
		<description><![CDATA[
I needed to make a form that had two inputs, and wanted to require that one or both fields be filled in.  While poking around in django.core.formfields, I noticed the following check:


 if field.is_required or new_data.get(field.field_name, False) or hasattr(validator, 'always_test'):


Ah ha!  What is this always_test I see here?  The devs must have [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>
I needed to make a form that had two inputs, and wanted to require that one or both fields be filled in.  While poking around in django.core.formfields, I noticed the following check:
</p>
<pre>
 if field.is_required or new_data.get(field.field_name, False) or hasattr(validator, 'always_test'):
</pre>
<p>
Ah ha!  What is this <code>always_test</code> I see here?  The devs must have already thought of a situation like this, but just failed to mention it in the <a href="http://www.djangoproject.com/documentation/forms/">documentation</a>.  Anyway, on to the to the custom form:
</p>
<pre>
from django.core import formfields, validators

class ItemAddForm(formfields.Manipulator):
    def __init__(self):
        self.fields = [
            formfields.TextField(field_name="name", length=50, maxlength=100,
                validator_list=[self.oneIsRequried]),
            formfields.URLField(field_name="url",
                validator_list=[self.oneIsRequried]),
        ]

    def oneIsRequried(self, field_data, all_data):
        if not all_data['name'] and not all_data['url']:
            raise validators.ValidationError, "One of either name or URL must be filled in."
    oneIsRequried.always_test = True
</pre>
<p>
After defining the <code>oneIsRequired</code> method, I set its <code>always_test</code> attribute to <code>True</code>.  You see, normally, a field&#8217;s validators will not get run if the field is left blank.  Here, the two fields will always get tested against the <code>oneIsRequired</code> validator method, blank or not.
</p>
<p>
<em>Note: Technically, I did not need to put the <code>oneIsRequired</code> in both fields&#8217; <code>validator_list</code> parameters, but by listing it in both, each field will get the error message in the form.errors dict.</em></p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/gdub.wordpress.com/3/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/gdub.wordpress.com/3/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/gdub.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/gdub.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/gdub.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/gdub.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/gdub.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/gdub.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/gdub.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/gdub.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/gdub.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/gdub.wordpress.com/3/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=gdub.wordpress.com&blog=111318&post=3&subd=gdub&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://gdub.wordpress.com/2006/02/28/form-validators-that-always-get-tested/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>