<?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>Webmonkey &#187; python</title>
    <atom:link href="http://www.webmonkey.com/tag/python/feed/" rel="self" type="application/rss+xml" />
    <link>http://www.webmonkey.com</link>
    <description>The Web Developer&#039;s Resource</description>
    <lastBuildDate>Fri, 05 Apr 2013 20:20:46 +0000</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <generator>http://wordpress.org/?v=3.4.2</generator>
    
    <item>
        <title>Video: Parsing Horrible Things with Python</title>
        <link>http://www.webmonkey.com/2012/11/video-parsing-horrible-things-with-python/</link>
        <comments>http://www.webmonkey.com/2012/11/video-parsing-horrible-things-with-python/#comments</comments>
        <pubDate>Thu, 08 Nov 2012 21:26:15 +0000</pubDate>

                <dc:creator>Scott Gilbertson</dc:creator>

        <guid isPermaLink="false">http://www.webmonkey.com/?p=59883</guid>
        		<category><![CDATA[Programming]]></category>
		<category><![CDATA[python]]></category>
        <description><![CDATA[The &#8220;horrible thing&#8221; in developer Erik Rose&#8217;s talk from this year&#8217;s PyCon is the Mediawiki syntax, but that&#8217;s just a jumping off point for one of the best overviews of data parsing that I&#8217;ve run across. If you&#8217;ve got a project that involves parsing, or are, like me, considering one, this talk is a must-watch. [...]]]></description>

            <content:encoded><![CDATA[<p><!-- wpautop enabled -->
<p><iframe width="580" height="435" src="https://www.youtube-nocookie.com/embed/tCUdeLIj4hE" frameborder="0" allowfullscreen></iframe></p>
<p>The &#8220;horrible thing&#8221; in developer Erik Rose&#8217;s <a href="https://www.youtube.com/watch?v=tCUdeLIj4hE">talk from this year&#8217;s PyCon</a> is the Mediawiki syntax, but that&#8217;s just a jumping off point for one of the best overviews of data parsing that I&#8217;ve run across. If you&#8217;ve got a project that involves parsing, or are, like me, considering one, this talk is a must-watch.</p>
<p>This is PyCon, so much of the talk focuses on parsing in Python, but there&#8217;s plenty of broader, dare I say, &#8220;parsing philosophy&#8221; that make it well worth a watch even if you don&#8217;t end up using the specific Python parsing libraries Rose mentions.</p>
<div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2012/11/video-parsing-horrible-things-with-python/feed/</wfw:commentRss>
        <slash:comments>2</slash:comments>

        
    </item>
    
    <item>
        <title>Amazon&#8217;s &#8216;Elastic Beanstalk,&#8217; Now With Python Power</title>
        <link>http://www.webmonkey.com/2012/08/amazons-elastic-beanstalk-now-with-python-power/</link>
        <comments>http://www.webmonkey.com/2012/08/amazons-elastic-beanstalk-now-with-python-power/#comments</comments>
        <pubDate>Mon, 20 Aug 2012 17:19:20 +0000</pubDate>

                <dc:creator>Scott Gilbertson</dc:creator>

        <guid isPermaLink="false">http://www.webmonkey.com/?p=58549</guid>
        		<category><![CDATA[Web Services]]></category>
		<category><![CDATA[app engine]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[python]]></category>
            <enclosure url="http://www.webmonkey.com/wp-content/uploads/2012/08/clouds-200x100.jpg" type="image/jpeg" length="48000" />
                    <description><![CDATA[<div class="rss_thumbnail"><img src="http://www.webmonkey.com/wp-content/uploads/2012/08/clouds.jpg" alt="Amazon&#8217;s &#8216;Elastic Beanstalk,&#8217; Now With Python Power" /></div>Amazon Web Services just made it even easier to get your Python-powered applications to the cloud with support for Python in Elastic Beanstalk. That means getting a your Django or Fabric app up and running on AWS is easier than ever.]]></description>

            <content:encoded><![CDATA[<p><!-- wpautop enabled --><div id="attachment_58551" class="wp-caption alignnone" style="width: 610px"><a href="http://www.flickr.com/photos/nirak/644336486/"><img src="http://www.webmonkey.com/wp-content/uploads/2012/08/clouds.jpg" alt="" title="clouds" width="600" class="size-full wp-image-58551" /></a><p class="wp-caption-text">Elastic Beanstalk, making easier to get your Python apps to the cloud. <em>Image: <a href="http://www.flickr.com/photos/nirak/644336486/">Karin Dalziel/Flickr</a></em>.</p></div></p>
<p>Python developers, there&#8217;s a new way to get your apps running in the cloud &#8212; Amazon&#8217;s <a href="http://aws.typepad.com/aws/2012/08/announcing-aws-elastic-beanstalk-support-for-python-and-seamless-database-integration.html">Elastic Beanstalk service now supports Python</a>. Elastic Beanstalk previously supported PHP, Java and .NET apps.</p>
<p>The new Python support means that popular web frameworks like <a href="https://www.djangoproject.com">Django</a> (which powers Instagram, Everyblock and other popular sites) are easier to deploy across Amazon&#8217;s suite of cloud services. </p>
<p>It also means that Amazon and Google App Engine are once again <a href="http://www.wired.com/wiredenterprise/2012/06/google-cloud-platform/">going head to head</a>, this time over Google App Engine&#8217;s territory. Thanks to its Python-friendly environment, App Engine has been a favorite with Python developers looking to deploy apps on hosted services. </p>
<p>While it&#8217;s always been possible to host Python apps on Amazon, setting up and configuring apps can be a pain. That&#8217;s where Beanstalk comes in. For those who haven&#8217;t tried it, Elastic Beanstalk greatly simplifies the process of deploying your app to Amazon&#8217;s various cloud services, including setting up new EC2 instances, load balancing with Elastic Load Balancing, as well as scaling and managing your app after it&#8217;s deployed. Beanstalk also integrates with Git and virtualenv.</p>
<p>Originally Beanstalk had a distinctly Java bias to it, but since then it has expanded to handle Java, .NET and now Python as well. For more details on exactly how Beanstalk&#8217;s new Python support works, check out the <a href="http://aws.amazon.com/elasticbeanstalk/">Beanstalk overview page</a>. Django developers should also read through Amazon&#8217;s guide to <a href="http://docs.amazonwebservices.com/elasticbeanstalk/latest/dg/create_deploy_Python_django.html">deploying a Django application to AWS Elastic Beanstalk</a>.</p>
<div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2012/08/amazons-elastic-beanstalk-now-with-python-power/feed/</wfw:commentRss>
        <slash:comments>1</slash:comments>

        
    </item>
    
    <item>
        <title>Get Started With Python</title>
        <link>http://www.webmonkey.com/2010/02/get_started_with_python/</link>
        <comments>http://www.webmonkey.com/2010/02/get_started_with_python/#comments</comments>
        <pubDate>Tue, 16 Feb 2010 01:45:47 +0000</pubDate>

                <dc:creator>Webmonkey Staff</dc:creator>

        <guid isPermaLink="false">http://stag.wired.com/primate/?p=828</guid>
        		<category><![CDATA[Programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[The scripting language Python is named after the Monty Python British Comedy series, although the language takes after its reptilian namesake as well &#8212; it&#8217;s simple by design, yet flexible and powerful. It can&#8217;t exactly swallow large rodents whole, but it can be used for a wide variety of applications. Whether you need to automate [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p>The scripting language Python is named after the Monty Python British Comedy series, although the language takes after its reptilian namesake as well &#8212; it&#8217;s simple by design, yet flexible and powerful. It can&#8217;t exactly swallow large rodents whole, but it can be used for a wide variety of applications. Whether you need to automate some part of you desktop workflow, create a website or build a full-fledged desktop application, Python is a strong candidate for the job.

</p><span id="more-828"></span><p><br />

</p>

<table id="toc" class="toc" summary="Contents"><tbody><tr><td><div id="toctitle"><h2>Contents</h2> </div>



<ol>

<li><a href="#What_Is_Python.3F">What Is Python?</a>

<ol>

<li><a href="#Advantages">Advantages</a></li>

<li><a href="#Uses">Uses</a></li>

</ol>

</li>

<li><a href="#Installing_Python">Installing Python</a></li>



<li><a href="#Python_Differences">Python Differences</a>

<ol>

<li><a href="#Spaces_versus_Tabs">Spaces versus Tabs</a></li>

</ol>

</li>

<li><a href="#Getting_Started">Getting Started</a></li>

<li><a href="#More_Strings.2C_Formatting_and_Comments">More Strings, Formatting and Comments</a></li>



<li><a href="#Lists.2C_Dictionaries_and_Tuples">Lists, Dictionaries and Tuples</a>

<ol>

<li><a href="#Lists">Lists</a></li>

<li><a href="#Dictionaries">Dictionaries</a></li>

<li><a href="#Tuples">Tuples</a></li>



</ol>

</li>

<li><a href="#Assigning_Multiple_Values_at_Once">Assigning Multiple Values at Once</a></li>

<li><a href="#The_Python_for_Loop">The Python for Loop</a></li>

<li><a href="#Suggested_readings">Suggested readings</a></li>

<li><a href="#Conclusion">Conclusion</a></li>



</ul>

</td></tr></tbody></table>



<a name="What_Is_Python.3F"></a><h2> <span class="mw-headline">What Is Python?</span></h2>

<p>Python is a dynamic object-oriented programming language that can be used for many kinds of software development. It offers strong support for integration with other languages and tools, comes with extensive standard libraries, and can be learned in a few days. Many Python programmers report substantial productivity gains and feel the language encourages the development of higher quality, more maintainable code. [source: python.org]

</p><p>Python was created by Guido van Rossum, who now works for Google. As a result, the company uses Python extensively in its various web services, most recently <a href="http://code.google.com/appengine/" class="external text" title="http://code.google.com/appengine/" rel="nofollow">App Engine</a>. Even though we joked around about Python exhibiting some likeness to its slithering namesake, the language takes its name from Monty Python&#8217;s Flying Circus, which is why many Python tutorials feature shameless Monty Python puns. This one is no exception.

</p><p><br />

</p>

<a name="Advantages"></a><h3> <span class="mw-headline">Advantages</span></h3>

<p><b>Simple Clean Syntax</b><br />



Python has an extremely simple syntax. It has comparatively few keywords and well written code in Python tends to remain extremely readable years after it was written. Much has been made about using white space to denote code blocks in Python, however users of the language will note this adds to readability and standardizes code formatting across the Python community.

</p><p><b>Object Oriented</b><br />

Python has advantages over other object-oriented languages. In Python everything is object. In some object oriented languages like Java, almost everything is object, but there almost always seems to be an exception. This creates some rather clunky syntactical maneuvering. There is no such problem in Python. In Python, the so-called primitive types are objects, functions are objects and code blocks are objects &#8212; this allows for a more natural programming style.

</p><p><b>No One Style Enforced</b><br />

What if object orientation isn&#8217;t really your thing? Maybe you only write 50-line text processing scripts and have no need to write complex objects. Well, you will find Python perfectly suited for your needs. While Python has advanced object oriented design elements, it doesn&#8217;t force you to use them. You can write large programs in the procedural style in Python and never be bothered to learn the object oriented way of doing things. Python also supports some functional programming constructs like anonymous one-line functions (using the Lambda keyword) and cool features like list comprehension.

</p><p><b>Standard Library</b><br />

Python&#8217;s biggest advantage is perhaps its large all inclusive standard library. Unlike many other open-source languages, Python has almost everything you need to write almost any type of application included. So whether you are writing a database-backed web application or a cross platform networked console application, be sure that the standard library has you covered. If for some reason you need more than is provided by the standard library, there are many, many third party libraries out there. They cover everything from industry standard encryption libraries to 3D graphics frameworks.

</p>

<a name="Uses"></a><h3> <span class="mw-headline">Uses</span></h3>

<p>Python is a compiled application that can be installed in a variety of environments &#8212; your desktop, a web server or embedded devices like your phone. Python can run on all the major platforms and comes pre-installed on Mac OS X and most Linux distros.

</p><p>There are two main ways to use Python &#8212; either by starting it directly from the command line or by calling an external script. Obviously, the latter method is much more flexible unless you&#8217;re just doing a quick one-time program.

</p><p>If you&#8217;re running Python on a web server, you can serve your scripts from a cgi-bin folder just as you would with a Perl script. There are also faster, more robust options like mod_python or mod_wsgi, two Apache modules that call on the Python interpreter to process your pages.



</p><p>Before we dig in, you should know about a site called <a href="http://www.python.org/" class="external text" title="http://www.python.org/" rel="nofollow">Python.org</a>. Python is an open-source language, and Python.org is its control center, with <a href="http://docs.python.org/ref/ref.html" class="external text" title="http://docs.python.org/ref/ref.html" rel="nofollow">extensive reference material</a>, additional tutorials and <a href="http://docs.python.org/lib/lib.html" class="external text" title="http://docs.python.org/lib/lib.html" rel="nofollow">a complete library</a> of all the elements available in Python.

</p>

<a name="Installing_Python"></a><h2> <span class="mw-headline">Installing Python</span></h2>

<p>Python code can be written as scripts and saved in text files with the .py extension. There&#8217;s also a shell interpreter that makes it very easy to get started just by typing <code>python</code> into your shell prompt. For now, that&#8217;s what we&#8217;ll be using to show some of the basic language principles.

</p><p>Go ahead and fire up a terminal window and type <code>python</code>. If you have Python installed, you&#8217;ll get a message like this:



</p>

<pre class="brush: js">Python 2.4.4 (#1, Oct 18 2006, 10:34:39)

[GCC 4.0.1 (Apple Computer, Inc. build 5341)] on darwin

Type "help", "copyright", "credits" or "license" for more information.

&gt;&gt;&gt;

</pre>

<p><b>Tip:</b> The three angle brackets are the standard Python command prompt which lets you know you&#8217;re now using the Python interpreter. Any time you see code snippets written with the &gt;&gt;&gt; you know the author is referring to the Python shell.

</p><p>If typing <code>python</code> in your shell didn&#8217;t load the interpreter, you&#8217;ll need to install Python. You can <a href="http://www.python.org/download/" class="external text" title="http://www.python.org/download/" rel="nofollow">download the source</a> from the Python website or use one of the many package installers available for most platforms.

</p><p>As of this writing, the latest version of Python is 2.5.2. Mac OS X and most Linux distros ship with Python 2.5. Windows users may need to install the latest version.



</p><p>Although Python 2.5 offers some nice new features over previous versions, for backwards compatibility reasons we&#8217;ll stick to concepts and tools that will work with Python 2.3 and greater.

</p><p><br />

</p>

<a name="Python_Differences"></a><h2> <span class="mw-headline">Python Differences</span></h2>

<p>For the most part, Python behaves much like PHP, Perl, Ruby and other languages you may be familiar with. However, there are some important and noteworthy differences.

</p><p>Perhaps the most obvious (and Python aficionados would argue, important) is that line breaks and indentions in your code have meaning in Python. Whereas PHP and others use a semicolon or other mark to designate the end of a line, Python sees all new lines as, well, new lines.

</p><p>Also where PHP and others use curly brackets to enclose code blocks, Python merely wants the code indented.

</p><p>Python forces you to properly indent code blocks and eschews end-of-line punctuation like PHP&#8217;s semicolons in favor of simple line breaks.

</p><p>This has some import consequences. First and foremost, it makes Python code much easier to read. The structure of a Python script is a snap to figure out at first glance. Even if you have no idea what the code is doing, you can tell how it does it just by glancing at it.

</p><p>Python forces neat, well structured code, but it also forces you pay more attention to how you write your code. Consider the following two code snippets, which do very different things:

</p>

<pre class="brush: js">def myfunction():

    if x == y:

        return True

</pre>

<pre class="brush: js">def myfunction():

    if x == y:

    return True

</pre>



<p>In the first code block our return statement is indented, and therefore within the if statement. In the second code block we didn&#8217;t indent the return statement so that function always returns true, regardless of our if test. Technically, that second function would generate an error because Python expects an indented block after the colon.

</p><p><br />

</p>

<a name="Spaces_versus_Tabs"></a><h3> <span class="mw-headline">Spaces versus Tabs</span></h3>

<p>As the joke goes, the most popular way to write Python code is to indent with spaces. The second most popular way to write Python is with tabs. Most good text editors have an &#8220;entab/detab&#8221; function which can convert tabs to spaces and vice versa.

</p><p>The important thing is to be consistent. <b>Don&#8217;t mix tab and space indenting in the same script!</b> Doing so will cause Python to throw an error and your code won&#8217;t execute.

</p>

<a name="Getting_Started"></a><h2> <span class="mw-headline">Getting Started</span></h2>

<p>Assuming you&#8217;ve got Python installed, fire up a shell window and type <code>python</code> to start the interpreter. Here&#8217;s a simple script. Just type <code>print 'hello world'</code> and hit return.



</p>

<pre class="brush: js">&gt;&gt;&gt; print 'hello world'

hello world

&gt;&gt;&gt;

</pre>

<p>Any time you want feedback from Python, use the <code>print</code> statement. As with any language, Python has built-in tools for doing common things, like in this case, printing something out.

</p><p>Let&#8217;s create some variable assignments and play around with some of Python&#8217;s built-in types. We&#8217;ll start by creating a string and playing around with it:

</p>

<pre class="brush: js">&gt;&gt;&gt; x = 'spam'

&gt;&gt;&gt; x[0]

's'

&gt;&gt;&gt; x[:1]

's'



&gt;&gt;&gt; x[1:]

'pam'

</pre>

<p>The first line just assigns x the value of &#8220;spam.&#8221; Python is dynamically typed language, that is, there&#8217;s no need to tell Python that x is going to be a string, it will figure that out at run time.

</p><p>It&#8217;s also worth noting that Python is a strongly typed language, which means that &#8220;types&#8221; are always enforced. If you try to treat x as a number after you&#8217;ve already assigned it a string value, Python will throw an error. In order to use x as a number, you&#8217;d have the explicitly recast x as a number first.

</p><p>The next line <code>x[0]</code> shows how Python&#8217;s treats strings &#8212; much like a list (array) with each letter being like an element of the list. The <code>x[:1]</code> is an example of Python&#8217;s slicing methods. The basic syntax is <code>variable[start:end]</code>. Slice indices always start with 0 and by default, omitting first index defaults that value to zero, while omitting second index defaults to the size of the string/list.

</p><p>Here are few more operators:

</p>

<pre class="brush: js">&gt;&gt;&gt; x = 'spam'



&gt;&gt;&gt; len(x)

4

&gt;&gt;&gt; y = x

&gt;&gt;&gt; x = 'knights'

&gt;&gt;&gt; y

'spam'

&gt;&gt;&gt;

</pre>

<p>Note that last sequence, we set a new variable y to the value of x and then change the value of x, but y stays the same. In other words, y doesn&#8217;t become a reference to x, it&#8217;s a new variable with the value of x. Just because x changes doesn&#8217;t mean y will as well.

</p><p><br />

</p>

<a name="More_Strings.2C_Formatting_and_Comments"></a><h2> <span class="mw-headline">More Strings, Formatting and Comments</span></h2>

<p>We already know that line endings and indentions matter in Python, but what about within Python strings? For instance:



</p>

<pre class="brush: js">&gt;&gt;&gt; long_string = "Python is the best language ever, but I willn

... keep that to myself and not start flame wars on Slashdot.n

... Just becausen

...     I think it's the best doesn't mean everyone needs to"

&gt;&gt;&gt; long_string

"Python is the best language ever, but I willnkeep that to myself and not start flame wars on Slashdot.nJust becausentI think it's the best doesn't mean everyone needs to"

&gt;&gt;&gt; print long_string

Python is the best language ever, but I will

keep that to myself and not start flame wars on Slashdot.

Just because

        I think it's the best doesn't mean everyone needs to

&gt;&gt;&gt;

</pre>

<p>So what&#8217;s going on here? How did we write multiple lines if line breaks mean the end of a line? The trick is the <code></code> which tells Python to ignore the end of the line. Also note the difference between calling our variable directly and printing it using the <code>print</code> statement.

</p><p>Escaping line breaks with a backslash also works within normal Python code blocks as well, not just within strings. In some cases it can help make your code more readable.



</p><p>The other Python concept that might look a bit funny to those coming from other languages is the string formatting tools. In other languages the common way to add data to a string is to just concatenate the string like this:

</p>

<pre class="brush: js">"the beginning of a sentence" + variable_data + "the end of a sentence"

</pre>

<p><br />

While this will work in Python as well, there is a far more elegant way to write it using the <code>%s</code> operator.

</p>

<pre class="brush: js">&gt;&gt;&gt; b = 'beginning of a sentence'

&gt;&gt;&gt; e = 'end of a sentence'

&gt;&gt;&gt; v = 'variable data'

&gt;&gt;&gt; '%s,&nbsp;%s,&nbsp;%s'&nbsp;%(b, v, e)

'beginning of a sentence, variable data, end of a sentence'



</pre>

<p><br />

The other nice thing about using <code>%s</code> is that it will force the value to a string, whereas straight concatenation won&#8217;t.

</p><p><b>Note:</b> There is a similar <code>%f</code> for inserting numbers into a string.

</p><p>One last thing about strings (aside from them being super-absorbant and perfect for doing away with floods and tidal waves).

</p><p>To create comments in Python you have several options. Like Perl, the hash mark can be used for inline comments, like so:

</p>

<pre class="brush: js">x = 'spam' #initial value

</pre>



<p>The other way to comment your code is with doc-strings:

</p>

<pre class="brush: js">def superfunction(params):

   """ The super function can do things

       you've only dreamed of"""

   print 'Spam!'

</pre>

<p>A doc-string is an unassigned string at the beginning of a function definition. In this example, we&#8217;ve used a tripple-quoted string which can span several lines but a normal, single-quoted string is also OK.

</p><p>A doc-string isn&#8217;t executed but is stored with the function to describe its purpose. Doc-strings can be accessed in your code &#8211; a feature which has been used to produce self-documenting and self-testing programs.

</p>

<a name="Lists.2C_Dictionaries_and_Tuples"></a><h2> <span class="mw-headline">Lists, Dictionaries and Tuples</span></h2>

<p>Arrays are one of the most useful constructs in a language. They allow you to store and manipulate compound data. Python has three distinct objects for handling compound data types: lists, dictionaries and tuples.

</p>

<a name="Lists"></a><h3> <span class="mw-headline">Lists</span></h3>

<p>Perhaps the most useful is the list, which is pretty straightforward; it&#8217;s a list of data:

</p>



<pre class="brush: js">&gt;&gt; l = ['spam', 'ham', 314, 23]

&gt;&gt;&gt; l

['spam', 'ham', 314, 23]

&gt;&gt;&gt; l[0]

'spam'

</pre>

<p>As you can see, we construct a list using square brackets and assign it to the variable <code>l</code>. From there, we can get the whole list by calling it directly or access individual list members using a zero-based index, just like we did earlier with the strings.

</p><p>Also note that lists can mix together any data-type you want. Here, we used both numbers and strings, but you could add anything you want &#8212; even other lists.

</p><p>Lists can do some other neat tricks. For instance, let&#8217;s try replacing some items:

</p>

<pre class="brush: js">&gt;&gt;&gt; l[0] = 'monkey'

&gt;&gt;&gt; l

['monkey', 'ham', 314, 23]



&gt;&gt;&gt; # slightly more complex replace method:

&gt;&gt;&gt; l[0:2] = ['banana', 18]

&gt;&gt;&gt; l

['banana', 18, 314, 23]

&gt;&gt;&gt; # we can even insert the list itself:

&gt;&gt;&gt; l[:0] = l

&gt;&gt;&gt; l

['banana', 18, 314, 23, 'banana', 18, 314, 23]

</pre>

<p><br />

As you can see, lists are mutable. You can do pretty much anything you want with them. As you start getting more comfortable with Python, you&#8217;ll find yourself using lists all the time. Be sure to check out the Python docs for <a href="http://www.python.org/doc/current/lib/typesseq-mutable.html" class="external text" title="http://www.python.org/doc/current/lib/typesseq-mutable.html" rel="nofollow">a complete list of list methods</a>.



</p>

<a name="Dictionaries"></a><h3> <span class="mw-headline">Dictionaries</span></h3>

<p>Another useful compound data-type is the dictionary. A Python dictionary is created using curly brackets, like so:

</p>

<pre class="brush: js">&gt;&gt;&gt; d = {"monkey":"banana", "spam":"eggs"}

&gt;&gt;&gt; d

{'monkey': 'banana', 'spam': 'eggs'}

</pre>

<p><br />

The name:value pairs are the dictionaries keys and values. To access dictionary data you just call the key using the square bracket syntax like lists, but instead of a number you&#8217;ll use a key:

</p>

<pre class="brush: js">&gt;&gt;&gt; d['monkey']

'banana'

&gt;&gt;&gt; #try to call something that doesn't exist and you'll get a KeyError.



&gt;&gt;&gt; #this means that you can't get keys from values:

&gt;&gt;&gt; d['banana']

Traceback (most recent call last):

  File "&lt;stdin&gt;", line 1, in&nbsp;?

KeyError: 'monkey'

</pre>

<p>Like lists, dictionaries are mutable, which means you can add key:value pairs whenever you want. Just keep in mind two things: you can&#8217;t have duplicate keys, as the second will overwrite the first, and key names are case sensitive.

</p>

<pre class="brush: js">&gt;&gt;&gt; #Start with an empty dictionary

&gt;&gt;&gt; d = {}

&gt;&gt;&gt; # add two key:value pairs

&gt;&gt;&gt; d['monkey'] = 'banana'



&gt;&gt;&gt; d['spam'] = 'eggs'

&gt;&gt;&gt; d

{'monkey': 'banana', 'spam': 'eggs'}

&gt;&gt;&gt; #try to add another monkey key

&gt;&gt;&gt; d['monkey'] = 'wrench'

&gt;&gt;&gt; # oops, we overwrote the original value:

&gt;&gt;&gt; d

{'monkey': 'wrench', 'spam': 'eggs'}

</pre>

<p><br />

As with lists, dictionaries can store any type of data you want. Even dictionary keys can be a variety of data-types, so long as the data-type is immutable (i.e. strings, integers, tuples, et cetera). And you can mix and match data-types within the same dictionary.

</p><p>For more details on what sort of manipulations you can perform with dictionaries, check out <a href="http://www.python.org/doc/current/lib/typesmapping.html" class="external text" title="http://www.python.org/doc/current/lib/typesmapping.html" rel="nofollow">the Python documentation page</a>.



</p>

<a name="Tuples"></a><h3> <span class="mw-headline">Tuples</span></h3>

<p>What the heck is a tuple? It&#8217;s got a funny name, but it&#8217;s just an immutable list. Once you stick data in a tuple you can&#8217;t change it. Unlike lists, tuples have no methods.

</p><p>Tuples are created using parentheses, and data in a tuple can be accessed just as we did with a list. Often functions that operate on lists work on tuples, too.

</p>

<pre class="brush: js">&gt;&gt;&gt; t = ('spam', 'ham', 314, 23)

&gt;&gt;&gt; t

('spam', 'ham', 314, 23)

&gt;&gt;&gt; t[0]

'spam'

&gt;&gt;&gt; t[0] = 'eggs'

Traceback (most recent call last):

  File "&lt;stdin&gt;", line 1, in&nbsp;?

TypeError: object does not support item assignment



&gt;&gt;&gt; len(t)

4

&gt;&gt;&gt; max(t)

'spam'

</pre>

<p>In many contexts, you don&#8217;t need the brackets to define a list. The comma alone is sufficient.

</p>

<pre class="brush: js">&gt;&gt;&gt; t = 'spam', 'ham', 314, 23

&gt;&gt;&gt; t

('spam', 'ham', 314, 23)

</pre>

<p>So you might be wondering, what&#8217;s the point of a tuple if it behaves like a crippled list? The answer is that tuples are faster than lists and Python uses them for holding some static sequences as we&#8217;ll see later. If you have a sequence of data that you know isn&#8217;t going to change, put it in a tuple.

</p><p>Tuples are also handy for data that should not need to be changed, like in a private class method. Using a tuple instead of a list prevents outside tampering. Tuples can be keys in a dictionary but lists cannot.

</p>

<a name="Assigning_Multiple_Values_at_Once"></a><h2> <span class="mw-headline">Assigning Multiple Values at Once</span></h2>



<p>One of the cool tricks in Python is ability to assign multiple variables values at the same time. For instance:

</p>

<pre class="brush: js">&gt;&gt;&gt; m,s = 'monkey','spam'

&gt;&gt;&gt; m

'monkey'

&gt;&gt;&gt; s

'spam'

</pre>

<p><br />

But this gets much more powerful with more complex data. For instance we can also do this:

</p>

<pre class="brush: js">&gt;&gt;&gt; a = 'b','c','d'

&gt;&gt;&gt; x, y, z = a

&gt;&gt;&gt; x

'b'



</pre>

<p>This is called &#8216;list unpacking&#8217;. Both sides of the assignment must have the same number of elements.

</p><p>Another variation on this theme is the built-in range function. Consider this:

</p>

<pre class="brush: js">&gt;&gt;&gt; range(7)

[0, 1, 2, 3, 4, 5, 6]

&gt;&gt;&gt; Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday = range(7)

&gt;&gt;&gt; Sunday

0

</pre>

<a name="The_Python_for_Loop"></a><h2> <span class="mw-headline">The Python <tt>for</tt> Loop</span></h2>



<p>Of all the things that will have you scratching your head while learning Python, the <tt>for</tt> loop is probably the most obvious difference from other languages. Rather than iterating over a progression of numbers, or allowing you to define both the iteration step and halting condition (as in C), Python&#8217;s <tt>for</tt> statement iterates over the items of any sequence (a list or a string), in the order that they appear in the sequence.

</p><p>The best way to understand how it works is to look at an example. In this case, we&#8217;ll create a list and then loop through the values.

</p>

<pre class="brush: js">&gt;&gt;&gt; a = 'spam', 'ham', 314, 23

&gt;&gt;&gt; for b in a:

...     print b

...

spam

ham

314

23

</pre>

<p>Note that the variable <tt>b</tt> is totally arbitrary. You can name the iterator whatever you would like, preferably picking whatever makes the most sense. For instance, if your list holds a bunch of URLs, you might write <tt>for url in urls:</tt>.



</p><p>We&#8217;d use the same technique to loop through a tuple, a string and other data-types. But what about a dictionary? That&#8217;s a little bit different, but we can borrow some of the multiple values techniques we mentioned above to help out.

</p>

<pre class="brush: js">&gt;&gt;&gt; mydict = {'guido':'python','larry':'perl','rasmus':'php'}

&gt;&gt;&gt; for key in mydict:

...     print key, 'created', mydict[key]

...

larry created perl

rasmus created php

guido created python

</pre>

<p>It&#8217;s worth noting that while Python&#8217;s for loops are just as capable as those in other language, the chances are that you won&#8217;t use them as much. One reason is that Python offers something called a list comprehension which does something similar but usually more elegantly .

</p><p>For instance suppose you have sequence of numbers and you want to perform a multiplication function on them. You might be tempted to do something like this:

</p>

<pre class="brush: js">&gt;&gt;&gt; new_list = []

&gt;&gt;&gt; for num in 0, 1, 1, 2, 3, 5:

...     new_list += [num * 2]

&gt;&gt;&gt; new_list

[0, 2, 2, 4, 6, 10]

</pre>



<p>But in Python, it&#8217;s much easier to just use a list comprehension. Here&#8217;s the same function in one line:

</p>

<pre class="brush: js">&gt;&gt;&gt; [num * 2 for num in 0, 1, 1, 2, 3, 5]

[0, 2, 2, 4, 6, 10]

&gt;&gt;&gt; # or if you want to store the results:

&gt;&gt;&gt; new_li = [num * 2 for num in 0, 1, 1, 2, 3, 5]

&gt;&gt;&gt; new_li

[0, 2, 2, 4, 6, 10]

</pre>

<p>It may take a while to wrap your head around, but list comprehensions are very very powerful and well worth spending some time with so you understand not just how they work, but when and where to use them.

</p><p>Have a look at the <a href="http://www.python.org/doc/current/tut/node7.html#SECTION007140000000000000000" class="external text" title="http://www.python.org/doc/current/tut/node7.html#SECTION007140000000000000000" rel="nofollow">official Python tutorial</a> for more information.

</p>



<a name="Suggested_readings"></a><h2> <span class="mw-headline"> Suggested readings </span></h2>

<ul><li> Learning Python, 3rd Edition, by Mark Lutz (O&#8217;Reilly)

</li></ul>

<ul><li> Also worth reading through is Mark Pilgrim&#8217;s seminal <a href="http://diveintopython.org/toc/index.html" class="external text" title="http://diveintopython.org/toc/index.html" rel="nofollow">Dive into Python</a> which covers some of the same ground we went over here, but also hits on some other areas of interest like parsing XML with Python&#8217;s powerful DOM tools and attempting to demystify Unicode text handling in Python.

</li></ul>

<a name="Conclusion"></a><h2> <span class="mw-headline">Conclusion</span></h2>

<p>So now you know how to say &#8220;nee!&#8221; and perform some basic operations using Python. If you&#8217;d like some more practice head over to the <a href="http://pypi.python.org/pypi/" class="external text" title="http://pypi.python.org/pypi/" rel="nofollow">Cheese Shop</a> (we did warn you that the Monty Python puns were thick in the Python community), a site dedicated to Python scripts, and try downloading some things that look useful.



</p><p>Next up we&#8217;ll take a look at how to write a script you can run from the command line and how to open and read data from a web service. In the mean time we&#8217;re off to return this parrot which seems almost like it&#8217;s, um, dead.

</p><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/get_started_with_python/feed/</wfw:commentRss>
        <slash:comments>7</slash:comments>

        
    </item>
    
    <item>
        <title>Using the Twitter API</title>
        <link>http://www.webmonkey.com/2010/02/get_started_with_the_twitter_api/</link>
        <comments>http://www.webmonkey.com/2010/02/get_started_with_the_twitter_api/#comments</comments>
        <pubDate>Tue, 16 Feb 2010 01:45:47 +0000</pubDate>

                <dc:creator>Webmonkey Staff</dc:creator>

        <guid isPermaLink="false">http://stag.wired.com/primate/?p=848</guid>
        		<category><![CDATA[APIs]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[Twitter]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[The microblogging site with the funny name is one of the hottest web services around. Twitter is one of those websites with very little room for functional nuance. Its limit of 140 characters per post forces users to be succinct, something that makes many people feel over-constrained and leads them to view the service as [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p>The microblogging site with the funny name is one of the hottest web services around.

</p><p><a href="http://www.twitter.com" class="external text" title="http://www.twitter.com" rel="nofollow">Twitter</a> is one of those websites with very little room for functional nuance. Its limit of 140 characters per post forces users to be succinct, something that makes many people feel over-constrained and leads them to view the service as too simple to actually be useful. Others see unbridled freedom inside such a unique limitation and embrace it like a poetic device. The lesson: You either get Twitter or you don&#8217;t.

</p><p>Regardless of how you feel about it, if you&#8217;re looking to try out an API for the first time, Twitter is a great place to start.</p>
<br />
<span id="more-848"></span>

<table id="toc" class="toc" summary="Contents"><tbody><tr><td><div id="toctitle"><h2>Contents</h2> </div>

<ol>
<li><a href="#Introduction">Introduction</a></li>
<li><a href="#Getting_Started">Getting Started</a></li>
<li><a href="#Authenticating_with_Twitter">Authenticating with Twitter</a></li>
<li><a href="#Client_Libraries">Client Libraries</a></li>
<li><a href="#Using_Python_with_Twitter">Using Python with Twitter</a></li>
<li><a href="#Mashups.2C_Apps_and_More">Mashups, Apps and More</a></li>
<li><a href="#Hashtags">Hashtags</a></li>
<li><a href="#Full_API_documentation">Full API documentation</a></li>
</ol>


</td></tr></tbody></table>

<a name="Introduction"></a><h2> <span class="mw-headline"> Introduction </span></h2>

</p><p>Like the service itself, the Twitter API is simple and easy to use. The only thing to keep in mind is that Twitter limits you to 70 requests per 60 sixty minute interval, so remember to cache or otherwise store your results. Otherwise, you may find yourself banned.

</p><p>If you end up building something that needs to make requests more frequently, you can always e-mail Twitter and ask for permission.

</p>

<a name="Getting_Started"></a><h3> <span class="mw-headline">Getting Started</span></h3>

<p>Twitter&#8217;s API is REST-based and will return results as either XML or JSON, as well as both RSS and ATOM feed formats.

</p><p>For a very simple look at a typical data response fire up a terminal window and type:

</p>

<pre class="brush: js">curl http://twitter.com/statuses/public_timeline.rss

</pre>

<p>That line will give you the latest 20 tweets from the public timeline in the form of an RSS feed. To get the same results in JSON just change the extension to &#8220;.json&#8221;.

</p><p>Public timelines can be accessed by any client, but all other Twitter methods require authentication.



</p>

<a name="Authenticating_with_Twitter"></a><h3> <span class="mw-headline">Authenticating with Twitter</span></h3>

<p>To authenticate yourself to Twitter you need to send a username and password. The basic format is:

</p>

<pre class="brush: js">curl -u email:password http://twitter.com/statuses/friends_timeline.xml

</pre>

<p>Most client libraries offer easy ways to pass in a username/password pair, making it very simple to authenticate with Twitter.

</p><p><br />

</p>

<a name="Client_Libraries"></a><h3> <span class="mw-headline">Client Libraries</span></h3>

<p>There are already some pretty good libraries out there for accessing Twitter, and there&#8217;s no need to re-invent the wheel. Whatever you&#8217;re looking for, Twitter&#8217;s got it: <a href="http://twitter.com/help/api" class="external text" title="http://twitter.com/help/api" rel="nofollow">ActionScript</a>, <a href="http://code.google.com/p/python-twitter/" class="external text" title="http://code.google.com/p/python-twitter/" rel="nofollow">Python</a>, <a href="http://groups.google.com/group/twitter-development-talk/web/twitter4r-open-source-ruby-library-for-twitter-rest-api" class="external text" title="http://groups.google.com/group/twitter-development-talk/web/twitter4r-open-source-ruby-library-for-twitter-rest-api" rel="nofollow">Ruby</a>, <a href="http://twitter.pbwiki.com/Scripts#PHP" class="external text" title="http://twitter.pbwiki.com/Scripts#PHP" rel="nofollow">PHP</a> and <a href="http://twitter.pbwiki.com/Scripts" class="external text" title="http://twitter.pbwiki.com/Scripts" rel="nofollow">many more</a>.



</p><p><br />

</p>

<a name="Using_Python_with_Twitter"></a><h3> <span class="mw-headline">Using Python with Twitter</span></h3>

<p>For the sake of example, we&#8217;ll use the Python library. Download and install the library and fire up a terminal window.

</p><p>Let&#8217;s grab your last twenty tweets. Fire up Python and type the following line, replacing &#8220;youusername&#8221; with your username:

</p>

<pre class="brush: js">&gt;&gt;&gt; import twitter

&gt;&gt;&gt; client = twitter.Api()

&gt;&gt;&gt; latest_posts = client.GetUserTimeline("yourusername")

&gt;&gt;&gt; print [s.text for s in latest_posts]

</pre>



<p>The last line prints out just the text of your posts. To get at things like date pasted and other useful methods, have a read through the <a href="http://static.unto.net/python-twitter/0.5/doc/twitter.html" class="external text" title="http://static.unto.net/python-twitter/0.5/doc/twitter.html" rel="nofollow">Python library documentation</a>.

</p><p>To go the other direction (posting something to Twitter) we&#8217;ll need to authenticate. Recreate our Twitter client, but this time pass in your username and password:

</p>

<pre class="brush: js">&gt;&gt;&gt; client = twitter.Api(username='yourusername', password='yourpassword')

&gt;&gt;&gt; update = client.PostUpdate('The Twitter API is easy')

</pre>

<p>Head over to your Twitter page and you should see the update.

</p>

<a name="Mashups.2C_Apps_and_More"></a><h3> <span class="mw-headline">Mashups, Apps and More</span></h3>

<p>To get some idea of what you can do with the Twitter API, visit the fan wiki and check out some of the <a href="http://twitter.pbwiki.com/Apps" class="external text" title="http://twitter.pbwiki.com/Apps" rel="nofollow">applications</a> and <a href="http://twitter.pbwiki.com/Mashups" class="external text" title="http://twitter.pbwiki.com/Mashups" rel="nofollow">mashups</a> created by Twitterheads.

</p>

<a name="Hashtags"></a><h3> <span class="mw-headline">Hashtags</span></h3>

<p>One area of particular usefulness is the hashtags concept. Hashtags involve inserting a # sign to denote keywords or other data like location. Although not everyone is a fan of hashtags (they tend to make your tweets less readable) parsing Twitter streams for hashtags can yield a wealth of useful data.

</p><p>Some of the client libraries include functions to parse hashtags, but in many case you may have to write your own functions.

</p>

<a name="Full_API_documentation"></a><h3> <span class="mw-headline">Full API documentation</span></h3>



<p>You can check out the development talk for the <a href="http://groups.google.com/group/twitter-development-talk/web/api-documentation" class="external text" title="http://groups.google.com/group/twitter-development-talk/web/api-documentation" rel="nofollow">full api documentation</a>.

</p><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/get_started_with_the_twitter_api/feed/</wfw:commentRss>
        <slash:comments>9</slash:comments>

        
    </item>
    
    <item>
        <title>Get Started With Django</title>
        <link>http://www.webmonkey.com/2010/02/get_started_with_django/</link>
        <comments>http://www.webmonkey.com/2010/02/get_started_with_django/#comments</comments>
        <pubDate>Tue, 16 Feb 2010 01:45:47 +0000</pubDate>

                <dc:creator>Webmonkey Staff</dc:creator>

        <guid isPermaLink="false">http://stag.wired.com/primate/?p=919</guid>
        		<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[Django is a web framework designed to help you build complex web applications simply and quickly. It&#8217;s written in the Python programming language. Django takes it name from the early jazz guitarist Django Reinhardt, a gypsy savant who managed to play dazzling and electrifying runs on his instrument even though two of the fingers on [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p>Django is a web framework designed to help you build complex web applications simply and quickly. It&#8217;s written in the Python programming language.

</p><p>Django takes it name from the early jazz guitarist Django Reinhardt, a gypsy savant who managed to play dazzling and electrifying runs on his instrument even though two of the fingers on his left hand were paralyzed in an accident when he was young.

</p><p>Thus, it&#8217;s a fitting name for the framework: Django can do some very complex things with less code and a simpler execution than you&#8217;d expect. It doesn&#8217;t take a heavy hand to build with Django. The framework does the repetitive work for you, allowing you to get a working website up quickly and easily.

</p><p><br />

</p><span id="more-919"></span>

<table id="toc" class="toc" summary="Contents"><tbody><tr><td><div id="toctitle"><h2>Contents</h2> </div>



<ol>

<li><a href="#Django.27s_DRY_pledge">Django&#8217;s DRY pledge</a></li>

<li><a href="#Background">Background</a></li>

<li><a href="#Why_isn.27t_Django_a_1.0_release.3F">Why isn&#8217;t Django a 1.0 release?</a></li>

<li><a href="#Structural_overview">Structural overview</a></li>



<li><a href="#So_how_does_Django_work.3F">So how does Django work?</a></li>

<li><a href="#Dive_in">Dive in</a></li>

</ol>

</td></tr></tbody></table>



<a name="Django.27s_DRY_pledge"></a><h2> <span class="mw-headline">Django&#8217;s DRY pledge</span></h2>

<p>Django was designed from the ground up to handle two common web developer challenges: intensive deadlines and strict adherence to the <a href="http://c2.com/cgi/wiki?DontRepeatYourself" class="external text" title="http://c2.com/cgi/wiki?DontRepeatYourself" rel="nofollow">Don&#8217;t Repeat Yourself (DRY) principle</a>. DRY sounds exactly like what it is: Why write the same code over and over again?



</p><p>The result is a fast framework, nimble and capable of generating full site mockups in a very short time. Django&#8217;s slogan captures its essence quite nicely: &#8220;The web framework for perfectionists with deadlines.&#8221;

</p><p>But quick doesn&#8217;t mean sloppy. Django comes with a slick built-in section for administering sites. The admin section supports <a href="http://www.djangoproject.com/documentation/cache/" class="external text" title="http://www.djangoproject.com/documentation/cache/" rel="nofollow">a variety of caching options</a> (including Memcached) and a host of other stable, scalable tools.

</p><p>Perhaps the best part about Django is its outstanding documentation. Unlike many open source projects, Django has <a href="http://www.djangoproject.com/documentation/" class="external text" title="http://www.djangoproject.com/documentation/" rel="nofollow">very thorough and readable docs available online</a>. If you have any problems with our tutorials, head over to the Django site for additional reading. Also consider joining the <a href="http://groups.google.com/group/django-users" class="external text" title="http://groups.google.com/group/django-users" rel="nofollow">django-users Google Group</a> which is full of helpful folks who can point you in the right direction if you run into trouble.

</p>

<a name="Background"></a><h2> <span class="mw-headline">Background</span></h2>

<p>Before we dive in, it&#8217;s worth pausing for a moment to understand where Django comes from, which has influenced both what it is and what it is not.

</p><p>Django was developed over a two year period by programmers working for an online news operation, the <a href="http://www2.ljworld.com/" class="external text" title="http://www2.ljworld.com/" rel="nofollow">Lawrence Journal-World Online</a> in Lawrence, Kansas. Eventually, the team realized it had a real framework on its hands and released the code to the public under an open-source BSD license.



</p><p>Once it became a community project, the development took off and Django began to pop up all over the web. For a complete list of Django sites, check out <a href="http://www.djangosites.org/" class="external text" title="http://www.djangosites.org/" rel="nofollow">Django Sites</a>. Notable examples include <a href="http://pownce.com/" class="external text" title="http://pownce.com/" rel="nofollow">Pownce</a>, <a href="http://projects.washingtonpost.com/congress/" class="external text" title="http://projects.washingtonpost.com/congress/" rel="nofollow">The Washington Post</a> and <a href="http://everyblock.net/" class="external text" title="http://everyblock.net/" rel="nofollow">Everyblock</a>.

</p><p>Perhaps the most common misconception about Django is that it&#8217;s a content management system. It&#8217;s not. It&#8217;s a <a href="/2010/02/Get_Started_with_Web_Frameworks" class="external text" title="/2010/02/Get_Started_with_Web_Frameworks" rel="nofollow">web framework</a>. It is a tool in which to build a CMS, like <a href="http://drupal.org/" class="external text" title="http://drupal.org/" rel="nofollow">Drupal</a> or other systems, but not one in itself.

</p><p>Django is designed to work in a slightly modified Model-View-Controller (MVC) pattern. MVC is a software engineering architecture concept describing how a program can change the visual aspect and the business aspect without affecting one another. The original Django developers refer to it as a model, template and view (MTV) framework.



</p><p>However, in Django&#8217;s vision of MVC development, the &#8220;view&#8221; refers to the data presented to user. Mind you, not <i>how</i> data looks, but <i>which data</i>. In other words, <a href="http://www.djangoproject.com/documentation/faq/" class="external text" title="http://www.djangoproject.com/documentation/faq/" rel="nofollow">to quote the Django documentation</a>, &#8220;the view describes which data you see, not how you see it.&#8221;

</p><p>It leaves the &#8220;how&#8221; to an additional element found in Django: the template.

</p>

<a name="Why_isn.27t_Django_a_1.0_release.3F"></a><h2> <span class="mw-headline"> Why isn&#8217;t Django a 1.0 release? </span></h2>

<p><a href="http://www.webmonkey.com/blog/Django_Deemed_Perfect__Goes_1DOT0" class="external text" title="http://www.webmonkey.com/blog/Django_Deemed_Perfect__Goes_1DOT0" rel="nofollow">It is</a>! Django was released as 1.0 on September 3rd, 2008. <a href="http://www.djangoproject.com/weblog/2009/jul/29/1-point-1/" class="external text" title="http://www.djangoproject.com/weblog/2009/jul/29/1-point-1/" rel="nofollow">Django 1.1 was released on July 29, 2009</a>.



</p>

<a name="Structural_overview"></a><h2> <span class="mw-headline">Structural overview</span></h2>

<p>Django was designed to make web development fast and easy &#8212; dare we say, even fun. And by fast, they mean fast. Once you&#8217;re comfortable with Django, it&#8217;s not hard to go from a simple wireframe to a working demo site in an hour or so.

</p><p>For development purposes, Django is entirely self-contained. It includes a command line interface, a web server and everything you need to get up and running without installing anything other than Django.

</p><p>That said, the web server included with Django is not intended to be used in a production environment. The preferred method is to run Django through <code>mod_python</code> or <code>mod_wsgi</code>. Don&#8217;t worry, we&#8217;ll get to <code>mod_python</code> and <code>mod_wsgi</code> in our more advanced tutorial. First, let&#8217;s look at how you might go about building a Django application.



</p><p>As it turns out, building a Django app actually takes much less time than explaining how to build it.

</p><p>Before we start building sites, it&#8217;s worth asking: What do you mean by building a Django app? Django&#8217;s official documentation and many of its built-in tools are set up to create projects, or containers for your whole site. Within projects you have many apps, or sections of your site.

</p><p>Apps don&#8217;t need to be in projects, and in many cases it&#8217;s better not to put them there.

</p><p>For the sake of example, here&#8217;s a very high-level overview of how a Django app is built:

</p><p>First, create a project using the built in command line tool (<code>python django-admin.py startproject projectname</code>). This will generate a new folder containing the project&#8217;s base settings file which you can use to specify database connections, template locations and more. Also in the folder is urls.py, which defines your base URLs and manage.py, which contains a standard set of command line tools.

</p><p>Next, create an app using the built in command line tool <code>python manage.py startapp appname</code>.

</p><p>Once the app folder is in place, look inside. You&#8217;ll see three files: <code>models.py</code>, <code>urls.py</code> and <code>views.py</code>. These are the files you&#8217;ll use to actually build the app:



</p>

<ul><li> <code>models.py</code> to design your model

</li><li> <code>urls.py</code> to write your URLs

</li><li> <code>views.py</code> to create your views

</li></ul>

<p>Django includes its own template language, but as with many elements of Django, using it entirely optional. You can drop in another template language if you like, but you might want to give Django&#8217;s a try first. It&#8217;s simple and fast, and it&#8217;s already there.

</p><p>The other thing to keep in mind is that Django is written in Python and requires Python 2.3 or higher. Mac OS X and most Linux distros ship with Python 2.5, so you shouldn&#8217;t have any problems. Windows users, however, may need to <a href="http://www.lehuen.com/nicolas/index.php/2005/02/21/39-win32-build-of-mod_python-314-for-python-24" class="external text" title="http://www.lehuen.com/nicolas/index.php/2005/02/21/39-win32-build-of-mod_python-314-for-python-24" rel="nofollow">install Python</a> separately.



</p>

<a name="So_how_does_Django_work.3F"></a><h2> <span class="mw-headline">So how does Django work?</span></h2>

<p>The simplest way to look at Django is to break it down into its component parts. First off, there&#8217;s a <code>models.py</code> file which defines your data model by extrapolating your single lines of code into full database tables and adding a pre-built (totally optional) administration section to manage content.

</p><p>The next element is the <code>urls.py</code> file which uses regular expressions to capture URL patterns for processing.

</p><p>The actual processing happens in your views which, if you haven&#8217;t seen the pattern yet, live in <code>views.py</code>. This is really the meat of Django, since views are where you grab the data you&#8217;re presenting to the visitor.

</p><p>Here&#8217;s what happens when a visitor lands on your Django page:

</p><p><b>1.</b> First, Django consults the various URL patterns you&#8217;ve created and uses the information to retrieve a view.



</p><p><b>2.</b> The view then processes the request, querying your database if necessary.

</p><p><b>3.</b> The view passes the requested information on to your template.

</p><p><b>4.</b> The template then renders the data in a layout you&#8217;ve created and displays the page.

</p><p><br />

</p>

<a name="Dive_in"></a><h2> <span class="mw-headline">Dive in</span></h2>

<p>Now you have at least some idea of how Django works, you&#8217;re ready to dive in and get your hands dirty. It&#8217;s really the best way to learn. For the sake of example, we&#8217;ll be building a blog-type site. It makes a nice intro to Django and takes advantage of some of Django&#8217;s handy shortcuts and other features.

</p><p>We aren&#8217;t going to just build a blog, we&#8217;ll also walk through adding a contact form, static pages (like an &#8220;about&#8221; page) and even integrate it with <a href="http://del.icio.us" class="external text" title="http://del.icio.us" rel="nofollow">del.icio.us</a> web services to display all your del.icio.us bookmarks on your new Django blog.



</p><p>So head on over to part two of our Django series, <a href="/2010/02/Install_Django_and_Build_Your_First_App" title="Tutorial:Install Django and Build Your First App">Install Django and Build Your First App</a>

</p>

<div id="series">

<div class="series_hdr">From the Django Tutorial series</div>

<table style="background: rgb(229, 249, 255) none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" width="620">

<tbody><tr>

<td>

<p><strong class="selflink"> Lesson 1: Get Started With Django</strong><br />

<a href="/2010/02/Install_Django_and_Build_Your_First_App" title="Tutorial:Install Django and Build Your First App"> Lesson 2: Install Django and Build Your First App</a><br />

<a href="/2010/02/Use_URL_Patterns_and_Views_in_Django" title="Tutorial:Use URL Patterns and Views in Django"> Lesson 3: Use URL Patterns and Views in Django</a><br />



<a href="/2010/02/Use_Templates_in_Django" title="Tutorial:Use Templates in Django"> Lesson 4: User Templates in Django</a><br />

<a href="/2010/02/Integrate_Web_APIs_into_Your_Django_Site" title="Tutorial:Integrate Web APIs into Your Django Site"> Lesson 5: Use Web API Data in Django</a><br />

<a href="/2010/02/Build_a_Microblog_with_Django" title="Tutorial:Build a Microblog with Django"> Lesson 6: Build a Microblog with Django</a>

</p>

</td></tr></tbody></table>

</div><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/get_started_with_django/feed/</wfw:commentRss>
        <slash:comments>8</slash:comments>

        
    </item>
    
    <item>
        <title>Use URL Patterns and Views in Django</title>
        <link>http://www.webmonkey.com/2010/02/use_url_patterns_and_views_in_django/</link>
        <comments>http://www.webmonkey.com/2010/02/use_url_patterns_and_views_in_django/#comments</comments>
        <pubDate>Tue, 16 Feb 2010 01:45:47 +0000</pubDate>

                <dc:creator>Webmonkey Staff</dc:creator>

        <guid isPermaLink="false">http://stag.wired.com/primate/?p=925</guid>
        		<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[Last time around, we installed Django and started building a blog application. We got Django&#8217;s built-in admin system up and running and explored some third-party libraries like the django-tagging project. So far we have some cool administrative tools, but no website for the rest of the world to see. This time around, we&#8217;ll work on [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p>Last time around, we <a href="/2010/02/Install_Django_and_Build_Your_First_App" title="Tutorial:Install Django and Build Your First App"> installed Django</a> and started building a blog application. We got Django&#8217;s built-in admin system up and running and explored some third-party libraries like the <a href="http://code.google.com/p/django-tagging/" class="external text" title="http://code.google.com/p/django-tagging/" rel="nofollow">django-tagging</a> project.

</p><p>So far we have some cool administrative tools, but no website for the rest of the world to see. This time around, we&#8217;ll work on displaying our content to the world by building the URL patterns and constructing some &#8220;views&#8221; &#8212; a term with a very specific meaning within the Django framework.

</p><p>Everything we&#8217;re going to do will make more sense if you understand how Django processes your visitor&#8217;s request. We went over some of this in our introduction, but here&#8217;s a quick refresher course.

</p><span id="more-925"></span>

<table id="toc" class="toc" summary="Contents"><tbody><tr><td><div id="toctitle"><h2>Contents</h2> </div>



<ol>

<li><a href="#How_content_is_presented">How content is presented</a></li>

<li><a href="#Working_with_urls.py">Working with urls.py</a></li>

<li><a href="#Thoughts_on_URLs">Thoughts on URLs</a></li>

<li><a href="#Being_Generic_is_Good">Being Generic is Good</a></li>



<li><a href="#Go_your_own_way">Go your own way</a></li>

<li><a href="#Conclusion">Conclusion</a></li>

</ol>

</td></tr></tbody></table>



<a name="How_content_is_presented"></a><h2> <span class="mw-headline">How content is presented</span></h2>

<p>The Django flow goes something like this:

</p><p>1) Visitor&#8217;s browser asks for a URL.<br />



2) Django matches the request against its urls.py files.<br />

3) If a match is found, Django moves on to the view that&#8217;s associated with the URL. Views are generally found inside each app in the views.py file.<br />

4) The view generally handles all the database manipulation. It grabs data and passes it on.<br />

5) A template (specified in the view) then displays that data.<br />

</p><p>Designer and coder Jeff Croft has put together a visual representation of this flow that makes it even easier to understand:

</p>

<div class="center"><div class="floatnone"><span><a href="/special/image/Django_flowchart.png" class="image" title="Django flowchart.png"><img alt="" src="/mediawiki/images/Django_flowchart.png" border="0" height="361" width="277"></a></span></div></div>

<p>See the full size original (along with explanatory text) at <a href="http://www.flickr.com/photos/jcroft/432038560/sizes/o/" class="external text" title="http://www.flickr.com/photos/jcroft/432038560/sizes/o/" rel="nofollow">Flickr</a>.

</p><p>With that in mind, let&#8217;s start building our public site by creating some URL patterns.

</p>

<a name="Working_with_urls.py"></a><h2> <span class="mw-headline">Working with urls.py</span></h2>



<p>Remember the <code>urls.py</code> file where we set up our admin URLs in the <a href="/2010/02/Install_Django_and_Build_Your_First_App" title="Tutorial:Install Django and Build Your First App"> last lesson</a>? Open that file in your favorite text editor.

</p><p>Now, we could define all our URLs in this file. But then what happens if we want to reuse this blog in an entirely separate project? We&#8217;d get a mess.

</p><p>A far better approach is to define all your app-specific URLs in a file that lives inside the app itself. In this case, we&#8217;re going to use a file inside the blog app, which will also be named <code>urls.py</code>.

</p><p>However, before we start with that file, we need to tell Django about it. So add this line to the project-wide <code>urls.py</code> file, just below the line that defines the admin URLs, like so:

</p>

<pre class="brush: js">from django.conf.urls.defaults import *

from django.contrib import admin



urlpatterns = patterns('',

    (r'^admin/(.*)', admin.site.root),

	(r'^blog/', include('djangoblog.blog.urls')),

)



</pre>

<p>OK, now head into the blog app folder and create a new <code>urls.py</code> file, which we&#8217;ll use to hold all the URLs related to our blog application.

</p>

<a name="Thoughts_on_URLs"></a><h2> <span class="mw-headline">Thoughts on URLs</span></h2>

<p>One of the nice things about Django is that it forces you to think about your URL designs, something many people don&#8217;t spend much time considering. If, perchance, you&#8217;ve never spent too much time thinking about URLs, now is good time to <a href="http://www.w3.org/Provider/Style/URI" class="external text" title="http://www.w3.org/Provider/Style/URI" rel="nofollow">read the W3C guide on the subject</a>.

</p><p>As the W3C points out, good URLs never change. In fact, even bad URLs never change &#8212; people change them. But when you change your URLs, you break everyone&#8217;s bookmarks and inbound links. So, spend a bit of time designing a good URL scheme from the beginning and you shouldn&#8217;t need to change things down the road.

</p><p>I would actually add one item to the W3Cs guidelines: good URLs are hackable. What do I mean by hackable? Let&#8217;s say our blog has URLs like:

</p>

<pre class="brush: js">http://mysite.com/blog/2008/jul/08/post-slug/

</pre>



<p>That URL would display the blog post with the slug named &#8220;post-slug&#8221; which was published on July 8, 2008.

</p><p><b>Note:</b> &#8220;Slug&#8221; is an old newspaper term. An article about fires in Nevada would probably be slugged &#8220;nv-fires&#8221; for easy identification. In this context, the slug refers to the last bit of the URL and can contain letters and dashes rather than spaces.

</p><p>Ideally, if the user heads up to their browser&#8217;s location bar and chops off the <code>post-slug/</code> bit, they would see all the blog entries from July 8, 2008. If they were to chop off <code>08/</code>, they would see all the posts from July 2008, and so on.

</p><p>In other words, the URL is hackable. Now, most people probably won&#8217;t do that. But in addition to making your site easier to navigate for the hands-on types, this rule also enforces an easy-to-use structure around which to build your site. In this case, the date-based structure was probably already obvious. But what about tags?

</p>

<pre class="brush: js">http://mysite.com/blog/tags/tag-slug/

</pre>

<p>This URL structure uses the same idea, but one-ups it. Not only can you hack the URL to get to a list of all tags (provided you create such a page), it should be obvious that you could plug just about any word into the &#8220;tag-slug&#8221; part of the URL and it effectively functions like a tag-based search engine.

</p><p>So, how do we actually build the URLs?

</p>



<a name="Being_Generic_is_Good"></a><h2> <span class="mw-headline">Being Generic is Good</span></h2>

<p>Let&#8217;s get started. Paste this code into your <code>blog/urls.py</code> file:

</p>

<pre class="brush: js">from django.conf.urls.defaults import *

from djangoblog.blog.models import Entry

from tagging.views import tagged_object_list



info_dict = {

	'queryset': Entry.objects.filter(status=1),

	'date_field': 'pub_date',

}



urlpatterns = patterns('django.views.generic.date_based',

	(r'(?P&lt;year&gt;d{4})/(?P&lt;month&gt;[a-z]{3})/(?P&lt;day&gt;w{1,2})/(?P&lt;slug&gt;[-w]+)/$', 'object_detail', dict(info_dict, slug_field='slug',template_name='blog/detail.html')),

	(r'^(?P&lt;year&gt;d{4})/(?P&lt;month&gt;[a-z]{3})/(?P&lt;day&gt;w{1,2})/(?P&lt;slug&gt;[-w]+)/$', 'object_detail', dict(info_dict, template_name='blog/list.html')),

	(r'^(?P&lt;year&gt;d{4})/(?P&lt;month&gt;[a-z]{3})/(?P&lt;day&gt;w{1,2})/$','archive_day',dict(info_dict,template_name='blog/list.html')),

	(r'^(?P&lt;year&gt;d{4})/(?P&lt;month&gt;[a-z]{3})/$','archive_month', dict(info_dict, template_name='blog/list.html')),

	(r'^(?P&lt;year&gt;d{4})/$','archive_year', dict(info_dict, template_name='blog/list.html')),

	(r'^$','archive_index', dict(info_dict, template_name='blog/list.html')),

)





</pre>

<p>Now, remember when I said that the URL patterns determine which view Django will use to grab data from our database? In that scheme, we would write our regular expressions and then point each pattern to a function in <code>views.py</code>.

</p><p>But we&#8217;re cheating a little bit here by taking advantage of some built in views that Django provides. These are known as &#8220;generic views.&#8221;

</p><p>Django&#8217;s developers wisely figured that date-based archives were likely to be a common problem that just about every site has at least some use for, so they baked in some generic data-based views.

</p><p>What we&#8217;ve done here is take advantage of the built in views to construct our URLs.

</p><p>Let&#8217;s start with <code>info_dict</code>, which is just a Python dictionary that holds two things: a queryset containing all of our public blog entries and the name of our date field in the database.

</p><p>It&#8217;s important to realize that Django querysets are lazy &#8212; Django only hits the database when the queryset is evaluated, so there&#8217;s no performance penalty for defining a queryset that looks for everything, then filtering it on a case-by-case basis. This happens to be essentially what we&#8217;ve just done.

</p><p>Passing the queryset to the generic view enables Django to automatically do whatever date sorting we need, for instance, to show all the entries from a single month or year. For more info on querysets, check out the <a href="http://www.djangoproject.com/documentation/db-api/" class="external text" title="http://www.djangoproject.com/documentation/db-api/" rel="nofollow">database API docs</a> on the Django site.

</p><p>That&#8217;s all the URL patterns list is: a regular expression that looks at the URL and figures out what view to use. The view then determines which entry or list of entries to show.

</p><p>Let&#8217;s break it down and go through each part of the URL pattern. We&#8217;ll use the first line as an example:



</p>

<pre class="brush: js">(r'(?P&lt;year&gt;d{4})/(?P&lt;month&gt;[a-z]{3})/(?P&lt;day&gt;w{1,2})/(?P&lt;slug&gt;[-w]+)/$', 'object_detail', dict(info_dict, slug_field='slug',template_name='blog/detail.html')),

</pre>

<p>The first bit:

</p>

<pre class="brush: js">(?P&lt;year&gt;d{4})/(?P&lt;month&gt;[a-z]{3})/(?P&lt;day&gt;w{1,2})/(?P&lt;slug&gt;[-w]+)/$



</pre>

<p>is the regular expression. In this case, the expression will match our permalink URLs and capture the year, month, day and slug of a particular entry. That information will then be passed to the next bit, <code>object_detail</code>, which is the name of the generic view that will pull out a single entry.

</p><p>The full path to object_detail is actually <code>django.views.generic.date_based.object_detail</code>, but since we started our urlpattern definition by including the <code>django.views.generic.date_based</code> bit, there&#8217;s no need to retype it every time, we just need to call the individual function, in this case object_detail.

</p><p>After we grab the URL info and pass it to the <code>object_detail</code> function, we also pass along a dictionary of data. Most of the time you can just pass <code>info_dict</code> here. The <code>object_detail</code> generic view is something of an exception because it needs to pass along the slug_field variable as well.



</p><p>I wanted to show some of the other data you can include as well, so I wrapped it in the <code>dict</code> your see above. In this case, we&#8217;ve passed <code>info_dict</code>, the slug_field and the name of the template Django should use to display the data.

</p><p>The rest of the patterns just work their way back up the URL using ever-shortening regular expressions until we get to nothing, which would be the URL: http:/mysite.com/blog/.

</p><p>We&#8217;ll be using that URL as the location of our archive page. So, I guess you can think of this as a tumblelog rather than a traditional blog, which would probably have separate archive and home pages. Naturally, you can tweak the URL patterns to fit whatever design you&#8217;d like.

</p><p>Django&#8217;s generic views are incredibly powerful, and there are quite a few other options beyond just the date-based ones we&#8217;ve used here. There&#8217;s also a super-handy built-in pagination system for some generic views. Be sure to read through the <a href="http://www.djangoproject.com/documentation/generic_views/" class="external text" title="http://www.djangoproject.com/documentation/generic_views/" rel="nofollow">documentation on the Django website</a> and also have a look at <a href="http://www.b-list.org/weblog/2006/nov/16/django-tips-get-most-out-generic-views/" class="external text" title="http://www.b-list.org/weblog/2006/nov/16/django-tips-get-most-out-generic-views/" rel="nofollow">James Bennett&#8217;s excellent guide</a> to the various ways you can wrap and extend generic views.

</p>

<a name="Go_your_own_way"></a><h2> <span class="mw-headline">Go your own way </span></h2>



<p>Django&#8217;s generic views can save you quite a bit of time, but you will probably encounter some situations where they don&#8217;t quite do exactly what you want. When that happens, it&#8217;s time to write your own views.

</p><p>Fear not, writing a custom view isn&#8217;t hard.

</p><p>We&#8217;ve pretty much covered our blogs URLs, from date-based archives to the detail pages, but what about the pages that display our entries by tag?

</p><p>The tagging application actually includes some views that we could use. But for the sake of example, we&#8217;ll write some custom views. Rather than overwriting what&#8217;s already in the tagging application, we&#8217;re just going to create a views file that lives on its own in our main project folder.

</p><p>So, inside the &#8220;djangoblog&#8221; folder create a new file named <code>tag_views.py</code>. Remember, before we get started there, we need to tell Django about the <code>tag_views</code> file, so open up <code>djangoblog/urls.py</code> and add the last line below what&#8217;s already there:

</p>

<pre class="brush: js">urlpatterns = patterns('',

	(r'^admin/(.*)', admin.site.root),

	(r'^blog/', include('djangoblog.blog.urls')),

	(r'^tags/(?P&lt;slug&gt;[a-zA-Z0-9_.-]+)/$', 'djangoblog.tag_views.tag_detail'),

)



</pre>

<p>Here, we haven&#8217;t included another <code>url.py</code> file like we did with the lines above. You could argue that we should, but just to show that you don&#8217;t <i>have</i> to, we&#8217;ll just point directly to our <code>tag_views.py</code> file which will soon have a function named <code>tag_detail</code>. Note that in the tag URL, we&#8217;re capturing the slug paramater. We&#8217;ll use that in just a minute to filter our blog entries by tag.

</p><p>Now it&#8217;s time to create the tag_detail function in the <code>tag_views.py</code> file. Open up that file in your text editor and paste in this code:



</p><p><br />

</p>

<pre class="brush: js">from django.views.generic.list_detail import object_detail



from tagging.models import Tag,TaggedItem

from blog.models import Entry



def tag_detail(request, slug):

	unslug = slug.replace('-', ' ')

	tag = Tag.objects.get(name=unslug)

	qs = TaggedItem.objects.get_by_model(Entry, tag)

	return object_list(request, queryset=qs, extra_context={'tag':slug}, template_name='tags/detail.html')

</pre>

<p>What&#8217;s going on here? Well, ignore the first line for now, we&#8217;ll get to that in a minute. We import all the things we need &#8212; in this case, the Tag and TaggedItem classes from django tagging and then our own Entry class. Then we define the <code>tag_detail</code> function, which is just an ordinary Python function that takes two parameters. The first is <code>request</code> which Django passes to all view functions, and the second is the slug paramater we defined in our URL pattern above.

</p><p>Now because we&#8217;re using a slug for our tag URLs, but strings of words with spaces for our tags, we need to get rid of the dashes and replace them with spaces (Remember, a slug can contain letters and dashes, but not spaces).

</p><p>Because our slug parameter is just a string, we can use the normal Python string function to make that replacement.

</p><p>In the next line, we look up our tag name in the database using the <code>objects</code> manager. Then we take advantage of django-tagging&#8217;s built in function <code>get_by_model</code> to grab all the entries with the given tag.



</p><p>The last step is to return something so that Django can load our template and display the entries to our visitor. To do that we&#8217;re going to use another of Django&#8217;s generic view functions &#8212; <code>object_detail</code> from the generic list views.

</p><p><code>Object_detail</code> requires a few things. First is the request object, then the queryset of results. After that, I&#8217;ve added an extra context variable named tag, so our template will be aware not just what entries to display, but also the current tag. Finally, the last item simply tells Django which template to use.

</p><p>We haven&#8217;t yet created a URL for <code><a href="http://mysite.com/blog/tags/" class="external free" title="http://mysite.com/blog/tags/" rel="nofollow">http://mysite.com/blog/tags/</a></code> to list all our tags, but that&#8217;s a good stepping stone to practice writing a view function on your own. Here&#8217;s a hint: you can use pretty much the same code we used for the <code>tag_detail</code> function, but you don&#8217;t need to worry about the <code>slug</code> param. And instead of looking up TaggedItems, just grab all the tags (i.e. <code>qs = Tag.objects.all()</code>)



</p>

<a name="Conclusion"></a><h2> <span class="mw-headline"> Conclusion </span></h2>

<p>And there you have it, a quick and dirty overview of how URL patterns and view work in Django.

</p><p>If you point your browser to our development URL (<a href="http://127.0.0.1:8000/blog/" class="external free" title="http://127.0.0.1:8000/blog/" rel="nofollow">http://127.0.0.1:8000/blog/</a>) you should see a Django error page complaining that the template blog/list.html does not exist. This is true, since we haven&#8217;t created it yet (visiting the tag pages will give you &#8220;list index out of range&#8221; error, also due to the missing templates).

</p><p>But don&#8217;t worry &#8212; in the next lesson, we&#8217;ll dive into Django&#8217;s template system and explore all the cool things we can do, including how to write custom template filters and more.

</p><p>See you then!

</p><p><br />

</p>

<div id="series">

<div class="series_hdr">From the Django Tutorial series</div>

<table style="background: rgb(229, 249, 255) none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" width="620">



<tbody><tr>

<td>

<p><a href="/2010/02/Get_Started_With_Django" title="Tutorial:Get Started With Django"> Lesson 1: Get Started With Django</a><br />

<a href="/2010/02/Install_Django_and_Build_Your_First_App" title="Tutorial:Install Django and Build Your First App"> Lesson 2: Install Django and Build Your First App</a><br />

<strong class="selflink"> Lesson 3: Use URL Patterns and Views in Django</strong><br />

<a href="/2010/02/Use_Templates_in_Django" title="Tutorial:Use Templates in Django"> Lesson 4: User Templates in Django</a><br />

<a href="/2010/02/Integrate_Web_APIs_into_Your_Django_Site" title="Tutorial:Integrate Web APIs into Your Django Site"> Lesson 5: Use Web API Data in Django</a><br />



<a href="/2010/02/Build_a_Microblog_with_Django" title="Tutorial:Build a Microblog with Django"> Lesson 6: Build a Microblog with Django</a>

</p>

</td></tr></tbody></table>

</div><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/use_url_patterns_and_views_in_django/feed/</wfw:commentRss>
        <slash:comments>2</slash:comments>

        
    </item>
    
    <item>
        <title>Use Templates in Django</title>
        <link>http://www.webmonkey.com/2010/02/use_templates_in_django/</link>
        <comments>http://www.webmonkey.com/2010/02/use_templates_in_django/#comments</comments>
        <pubDate>Tue, 16 Feb 2010 01:45:47 +0000</pubDate>

                <dc:creator>Webmonkey Staff</dc:creator>

        <guid isPermaLink="false">http://stag.wired.com/primate/?p=927</guid>
        		<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[This is part 4 of Webmonkey&#8217;s introductory Django tutorial. If you&#8217;re arriving here to learn about getting started with Django, start back at the beginning with Lesson 1. When we left off last time, we had defined some URLs for our blog and constructed a custom view to handle displaying posts by tag. If you [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p>This is part 4 of Webmonkey&#8217;s introductory Django tutorial. If you&#8217;re arriving here to learn about getting started with Django, start back at the beginning with <a href="/2010/02/Get_Started_With_Django" title="Tutorial:Get Started With Django"> Lesson 1</a>.

</p><p>When we left off last time, we had defined some URLs for our blog and constructed a custom view to handle displaying posts by tag. If you point your browser to our development URL at this point, (<a href="http://127.0.0.1:8000/blog/" class="external free" title="http://127.0.0.1:8000/blog/" rel="nofollow">http://127.0.0.1:8000/blog/</a>) you&#8217;ll still see a Django error page complaining that the template blog/list.html does not exist. Don&#8217;t panic, it&#8217;s true &#8212; we haven&#8217;t created it yet.

</p><p>It&#8217;s time to tackle the last aspect of Django, the template syntax.

</p><p><br />

</p><span id="more-927"></span>

<table id="toc" class="toc" summary="Contents"><tbody><tr><td><div id="toctitle"><h2>Contents</h2> </div>



<ol>

<li><a href="#Create_some_templates">Create some templates</a></li>

<li><a href="#Inheritance">Inheritance</a></li>

<li><a href="#A_simple_template">A simple template</a>

<ol>

<li><a href="#Using_built-in_filters">Using built-in filters</a></li>



<li><a href="#Displaying_tags">Displaying tags</a></li>

</ol>

</li>

<li><a href="#Finishing_up_the_template">Finishing up the template</a></li>

<li><a href="#More_about_built-in_template_filters">More about built-in template filters</a></li>

<li><a href="#Roll_your_own_template_tags">Roll your own template tags</a></li>



<li><a href="#Links_and_other_resources">Links and other resources</a></li>

</ol>

</td></tr></tbody></table>



<a name="Create_some_templates"></a><h2> <span class="mw-headline">Create some templates</span></h2>

<p>If you look back through the code we&#8217;ve written so far, you&#8217;ll find that we&#8217;ve point Django to a number of templates (check out the [Tutorial:Use URL Patterns and Views in Django | urlpatterns code] and the custom view we wrote).

</p><p>The templates we&#8217;ve defined need to be created. We&#8217;re going to use the following names within this directory structure:

</p>

<pre class="brush: js">djangoblog

	- templates

		-blog

			list.html

			detail.html

		-tags

			list.html

</pre>

<p>You can go ahead and create that directory structure &#8212; just create a folder in your main &#8220;djangoblog&#8221; folder and name it &#8220;templates.&#8221; Inside that, create two folders named &#8220;blog&#8221; and &#8220;tags.&#8221;

</p><p>Then create your <code>list.html</code> and <code>detail.html</code> files.



</p><p>Note: The .html extension is totally optional &#8212; I prefer it because it turns on the syntax highlighting feature in my text editor, but you can use any extension you like.

</p>

<a name="Inheritance"></a><h2> <span class="mw-headline">Inheritance</span></h2>

<p>If we step back for a minute and think about our blog and what our templates need to display, the first thing that jumps out at you is that there&#8217;s a whole bunch of stuff that&#8217;s common to every page &#8212; a header, site navigation, sidebar, footer, and so on.

</p><p>It would be silly (and a egregious violation of the DRY principle) if we wrote that code more than once. Luckily, like most good template languages, Django provides a way to extend a single template file. We can define our site-wide components once and then simply inherit from that file, adding in the aspects of the site that do change.

</p><p>So before we dive into the detail pages, let&#8217;s first create a base file. Being the creative type, I generally call the file <code>base.html</code>. So inside the templates folder you created above, add a new file called <code>base.html</code>.

</p>

<a name="A_simple_template"></a><h2> <span class="mw-headline">A simple template</span></h2>

<p>Open that file in your text editor. Let&#8217;s sketch out some of the site-wide HTML we might need. For the sake of this tutorial, I&#8217;ve kept things pretty simple, but feel free to get as fancy as you want with your HTML. Here&#8217;s a basic starting point:



</p>

<pre class="brush: js">&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"&gt;

&lt;html lang="en"&gt;

	&lt;head&gt;

		&lt;title&gt;My Site - {%block pagetitle&nbsp;%}{% endblock&nbsp;%}&lt;/title&gt;

	&lt;/head&gt;



	&lt;body&gt;

		&lt;div id="header"&gt;My Site&lt;/div&gt;

		&lt;div id="nav"&gt;

			&lt;ul&gt;

				&lt;li&gt;&lt;a href="/"&gt;home&lt;/a&gt;&lt;/li&gt;



				&lt;li&gt;&lt;a href="/blog/"&gt;Blog&lt;/a&gt;&lt;/li&gt;

				&lt;li&gt;&lt;a href="/links/"&gt;Links&lt;/a&gt;&lt;/li&gt;

				&lt;li&gt;&lt;a href="/about/"&gt;About&lt;/a&gt;&lt;/li&gt;



			&lt;/ul&gt;

		&lt;/div&gt;

		&lt;div id="content"&gt;

			&lt;div id="primary"&gt;

				&lt;h1&gt;{% block title&nbsp;%}{% endblock&nbsp;%}&lt;/h1&gt;



				{% block primary&nbsp;%}{% endblock&nbsp;%}

			&lt;/div&gt;

			&lt;div id="secondary"&gt;

				&lt;h3&gt;Recent Entries:&lt;/h3&gt;

			&lt;div&gt;



		&lt;/div&gt;

	&lt;/body&gt;

&lt;/html&gt;

</pre>

<p>That should be pretty self explanatory, save perhaps the curious things enclosed in curly brackets, the <code>{%&nbsp;%}</code> bits. What up with that stuff?

</p><p>That is Django&#8217;s template syntax for creating blocks which other templates can plug data into. In this case we&#8217;re creating a base template with a few blocks (think of them as holes) and our other templates will extend this and fill in the holes.

</p><p>To see what I mean let&#8217;s create the blog/list.html template. Add a new blog folder in the templates folder (if you haven&#8217;t already) and create a file list.html. Now open that up and past in the line:

</p>



<pre class="brush: js">{% extends 'base.html'&nbsp;%}</pre>.

<p>Now, if you revisit <a href="http://127.0.0.1:8000/blog/" class="external free" title="http://127.0.0.1:8000/blog/" rel="nofollow">http://127.0.0.1:8000/blog/</a> the template not found error should be gone. In its place, you should see everything we just put in <code>base.html</code>.

</p><p>Not much, I&#8217;m afraid. But fear not &#8212; now that we&#8217;re extending <code>base.html</code>, we can start plugging in some values for those blocks we created earlier.

</p><p>Add this below the extends statement:

</p>

<pre class="brush: js">{% block pagetitle&nbsp;%}Tumblelog{% endblock&nbsp;%}

{% block title&nbsp;%}My Page Headline{% endblock&nbsp;%}

{% block primary&nbsp;%}

{% for object in latest&nbsp;%}

	&lt;h2&gt;{{ object.title }}&lt;/h2&gt;



	&lt;p&gt;{{ object.pub_date }}&lt;/p&gt;

	 {{ object.body_html|truncatewords_html:"20"|safe }}

	&lt;p&gt;tags: {% for tag in object.get_tags%}&lt;a href="/blog/tags/{{tag.name|slugify}}/"&gt;{{tag}}&lt;/a&gt;{% endfor&nbsp;%}&lt;/p&gt;

	&lt;p&gt;&lt;a href="{{object.get_absolute_url}}"&gt;read more&lt;/a&gt;&lt;/p&gt;



{% endfor&nbsp;%}

{% endblock&nbsp;%}

</pre>

<p>The first thing we do is fill in our page title block in the head tags. Then we do the same for the displayed title. The next block we fill in is the primary content block. Here&#8217;s where we display the data that our generic view grabbed for us.

</p><p>The Django template syntax can be considered fairly &#8220;Pythonic,&#8221; in that your define loops using the same <code>for x in dataset</code> syntax as Python. In this case, the generic view function <code>object_detail</code> passes in a variable named latest. By default, this displays the fifteen latest entries, though you can go back to the <code>urls.py</code> file and increase that number using the <code>num_latest</code> param.



</p><p>All we do is construct a loop using the <code>latest</code> variable. Then within that loop we pull out some of our data &#8212; again, accessing an objects attributes uses the Python-like dot accessor methods.

</p>

<a name="Using_built-in_filters"></a><h3> <span class="mw-headline">Using built-in filters</span></h3>

<p>The only part that requires additional explaining is the <code>object.body_html</code> section where we&#8217;ve applied two built-in Django template filters, <code>truncatewords_html</code> and <code>safe</code>.



</p><p><code>Truncatewords_html</code> should be fairly obvious &#8212; this clips the body of our post after twenty words, but also preserves the structure of the HTML by appending any closing tags to make sure the HTML remains intact.

</p><p>The <code>safe</code> filter simply tells Django that it&#8217;s OK to display HTML. Without the safe filter, Django will automatically escape all HTML entities and tags. Autoescaping is a nice feature for avoiding nefarious XSS attacks and the like, but in this case, since we trust the source, we&#8217;ll let the HTML through.

</p>

<a name="Displaying_tags"></a><h3> <span class="mw-headline">Displaying tags</span></h3>

<p>All fine so far, but what about tags? We have tags on our entries, so we might as well display them. This is what we do in the next line.

</p><p>You&#8217;ll notice that in that line, we have a loop within a loop. Remember when we created our models and we added a <code>get_tags</code> method to return all the tags for each entry? Well, here it is in action.

</p><p>That will loop through all the tags for each entry and display them along with a link to that tag&#8217;s permalink page. And note that we&#8217;ve used the slugify filter to make sure than any multiword tags will be hyphenated in the URL



</p><p>Note: If you remember back when we wrote our custom tag view, we used a string replace function to &#8220;unslugify&#8221; the URL for lookup in the datebase.

</p><p><br />

</p>

<a name="Finishing_up_the_template"></a><h2> <span class="mw-headline">Finishing up the template</span></h2>

<p>The last line calls the <code>get_absolute_url</code> function that we defined when we built our model in the last lesson. This provides a link to the permalink page for each entry in the list.

</p>

So click that link and what happens? Error page. You need to define the detail.html template. That&#8217;s not to hard, just create the file, add the extends base.html instruction at the top and fill in the blank blocks like title and primary. This time there&#8217;s no need to loop through anything since there&#8217;s only one object. Just call it directly like we did inside the loop on the archive page: <pre class="brush: js">{{object.title}}</pre> etc.

<p>The code might look something like this:

</p>



<pre class="brush: js">{% block pagetitle&nbsp;%}{{object.title}}{% endblock&nbsp;%}

{% block title&nbsp;%}{{object.title}}{% endblock&nbsp;%}

{% block primary&nbsp;%}

	&lt;ul class="page-nav"&gt;

		{% if object.get_previous_published%}

		&lt;li&gt;

			&lt;a href="{{ object.get_previous_published.get_absolute_url }}" title=" {{object.get_previous_published.title}}"&gt;« previous&lt;/a&gt;



		&lt;/li&gt;

		{%endif%}

		{% if object.get_next_published%}

			&lt;li&gt;

				&lt;a href="{{ object.get_next_published.get_absolute_url }}" title=" {{object.get_next_published.title}}"&gt;next »&lt;/a&gt;

			&lt;/li&gt;

		{%endif%}

    &lt;/ul&gt;



	&lt;h2&gt;{{ object.title }}&lt;/h2&gt;

	&lt;p&gt;{{ object.pub_date }}&lt;/p&gt;

	 {{ object.body_html|safe }}

	&lt;p&gt;tags: {% for tag in object.get_tags%}&lt;a href="/blog/tags/{{tag.name|slugify}}/"&gt;{{tag}}&lt;/a&gt;{% endfor&nbsp;%}&lt;/p&gt;



	&lt;p&gt;&lt;a href="{{object.get_absolute_url}}"&gt;read more&lt;/a&gt;&lt;/p&gt;

{% endblock&nbsp;%}

</pre>

<p>Note that I&#8217;ve made use of those <code>get_next_published</code> and <code>get_previous_published</code> functions that we defined way back when wrote our models. That way, users have some handy next and previous links for navigating through your permalink pages.



</p><p>Naturally you can get much more sophisticated with your HTML than this simple example.

</p><p>To create the templates for the tag pages, you&#8217;ll essentially do the same thing. In our custom tag view we returned a list of all the entries in an object named <code>object_list</code>. So in order to display them, just loop through <code>object_list</code> like we did with the <code>latest</code> variable above.

</p>

<a name="More_about_built-in_template_filters"></a><h2> <span class="mw-headline">More about built-in template filters</span></h2>

<p>Before we move on, a slight digression.

</p><p>It&#8217;s worth paying a visit to the <a href="http://www.djangoproject.com/documentation/templates/" class="external text" title="http://www.djangoproject.com/documentation/templates/" rel="nofollow">Django documentation on template filters and tags</a>. There&#8217;s a whole bunch of useful stuff built in to Django. You can use <code>{% if&nbsp;%}</code> tags to narrow and filter results, and there&#8217;s also <code>{% else&nbsp;%}</code>, <code>{% ifequal var1 var2&nbsp;%}</code>, <code>{% ifnotequal var1 var2&nbsp;%}</code> and most other common programming structures.



</p><p>Then there&#8217;s a host of template filters, like the <code>truncatewords_html</code> and <code>safe</code> filters we used above. For instance, there&#8217;s a handy <code>date</code> filter if you&#8217;d like to display your post date in something a little sexier than a UNIX timestamp.

</p><p>Here&#8217;s what that would look like using the &#8220;date&#8221; filter:

</p>

<pre class="brush: js">{{object.pub_date|date:"D d M Y"}}</pre>

<p>Another great filter is the <code>timesince</code> filter which will automatically convert a date into syntax like &#8220;1 week, 2 days ago&#8221;.



</p><p>There are also filters for escaping ampersands, escaping JavaScript, adding line breaks, removing HTML, converting to upper/lowercase and dozens more. In fact in two and a half years of building sites with Django I&#8217;ve only needed to write a custom filter once. Naturally your mileage may vary somewhat.

</p>

<a name="Roll_your_own_template_tags"></a><h2> <span class="mw-headline">Roll your own template tags</span></h2>

<p>One thing I do frequently do is write custom template &#8220;tags.&#8221; Template tags are perhaps one of the more confusing aspects of Django, since they still have a little bit of &#8220;magic&#8221; in them. But luckily they aren&#8217;t too hard to work with.

</p><p>Template tags are a way of extending the Django template system to use it in project specific ways. For instance, custom template tags are a perfect way to handle things that don&#8217;t make sense in a view, but do require some database logic.

</p><p>Perhaps the best example is something like a sidebar. So far ours is empty, but we can easily add a list of our most recent blog posts.

</p><p>We could write a filter that specifically fetches blog entries, but then what happens when we add links in the next lesson and want to display the most recent links? Write another template filter? That&#8217;s not very DRY! Instead, let&#8217;s just write a filter that fetches the most recent entries from any model with a date field.

</p><p>In fact we don&#8217;t even need to really write it. James Bennett has already <a href="http://www.b-list.org/weblog/2006/jun/07/django-tips-write-better-template-tags/" class="external text" title="http://www.b-list.org/weblog/2006/jun/07/django-tips-write-better-template-tags/" rel="nofollow">written some great reusable code</a> so we&#8217;ll just use that. I strongly recommend that you have read through James&#8217; tutorial so you can see how and why this code works.

</p><p>Open a new file and paste in this code:

</p>

<pre class="brush: js">from django.template import Library, Node

from django.db.models import get_model



register = Library()



class LatestContentNode(Node):

    def __init__(self, model, num, varname):

        self.num, self.varname = num, varname

        self.model = get_model(*model.split('.'))



    def render(self, context):

        context[self.varname] = self.model._default_manager.all()[:self.num]

        return ''



def get_latest(parser, token):

    bits = token.contents.split()

    if len(bits)&nbsp;!= 5:

        raise TemplateSyntaxError, "get_latest tag takes exactly four arguments"

    if bits[3]&nbsp;!= 'as':

        raise TemplateSyntaxError, "third argument to get_latest tag must be 'as'"

    return LatestContentNode(bits[1], bits[2], bits[4])



get_latest = register.tag(get_latest)





</pre>

<p>Now save that file as &#8220;get_latest.py&#8221; in a new folder within the blog app named &#8220;templatetags&#8221;. The folder name and location are important since Django only looks up template tags in specific locations. You also need to create an empty file named &#8220;__init__.py&#8221; inside the &#8220;templatetags&#8221; folder.

</p><p>One thing to note about this code, if you look closely you&#8217;ll notice that our template tag is going to fetch all entries, not just the public ones. In other words, our model allows for draft posts, but our template tag doesn&#8217;t.

</p><p>This is the line in question:

</p>

<pre class="brush: js">self.model._default_manager.all()

</pre>

<p>There are two ways around this, one is quick and dirty &#8212; just change that line to filter only published entries. In other words:

</p>

<pre class="brush: js">self.model._default_manager.filter(status=1)

</pre>

<p>The better (and cleaner) way to do it would be overwrite the default manager for our Entry model. However, that&#8217;s a little beyond the scope of this article, so for now we&#8217;ll just use the quick and dirty method.

</p><p>Now open up <code>base.html</code> again and add this line at the top:

</p>



<pre class="brush: js">{% load get_latest&nbsp;%}

</pre>

<p>That tells Django to load the template tag, but then we need to grab the actual data. So, head down to the sidebar section and replace it with this code:

</p>

<pre class="brush: js">&lt;div id="secondary"&gt;

	&lt;h3&gt;Recent Entries:&lt;/h3&gt;

	{% get_latest blog.Entry 5 as recent_posts&nbsp;%}

    &lt;ul class="archive"&gt;



    	{% for obj in recent_posts&nbsp;%}

		&lt;li&gt;

			&lt;a href="{{ obj.get_absolute_url }}" title="Permanent Link to {{ obj.title}}"&gt;{{ obj.title}}&lt;/a&gt;

		&lt;/li&gt;

    	{% endfor&nbsp;%}

	&lt;/ul&gt;



&lt;div&gt;

</pre>

<p>If you want to override that in templates that are inheriting from <code>base.html</code>, just wrap that code in a {% block&nbsp;%} tag and then replace it with something else in the new template.

</p>

<a name="Links_and_other_resources"></a><h2> <span class="mw-headline">Links and other resources</span></h2>

<p>The Django template system is quite vast in terms of capabilities, and we&#8217;ve really just scratched the surface here.

</p><p>Make sure you <a href="http://www.djangoproject.com/documentation/templates_python/" class="external text" title="http://www.djangoproject.com/documentation/templates_python/" rel="nofollow">read through the documentation for Python programmers</a> as well as <a href="http://www.djangoproject.com/documentation/templates/" class="external text" title="http://www.djangoproject.com/documentation/templates/" rel="nofollow">the documentation for template authors</a> and familiarize yourself with all the various built in tags and filters. Another great article is Jeff Croft&#8217;s <a href="http://jeffcroft.com/blog/2006/feb/21/django-templates-an-introduction/" class="external text" title="http://jeffcroft.com/blog/2006/feb/21/django-templates-an-introduction/" rel="nofollow">Django Templates: An Introduction</a>.



</p><p>It&#8217;s worth noting that there&#8217;s an extensive collection of useful filters and template tags on the <a href="http://www.djangosnippets.org/" class="external text" title="http://www.djangosnippets.org/" rel="nofollow">Django Snippets site</a>. If you ever find yourself needing a custom tag or filter, have a look through there and see if anyone has already written something that works for your project.

</p><p>I should also point out that if you just don&#8217;t for whatever reason like Django&#8217;s template system, it&#8217;s possible drop in another template language, like <a href="http://cheetahtemplate.sourceforge.net/" class="external text" title="http://cheetahtemplate.sourceforge.net/" rel="nofollow">Cheetah</a> or others.

</p><p>Be sure to stop by for our next installment when we&#8217;ll tackle a plan to import, store and display our del.icio.us bookmarks. See you then!

</p>

<div id="series">

<div class="series_hdr">From the Django Tutorial series</div>

<table style="background: rgb(229, 249, 255) none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" width="620">

<tbody><tr>

<td>

<p><a href="/2010/02/Get_Started_With_Django" title="Tutorial:Get Started With Django"> Lesson 1: Get Started With Django</a><br />



<a href="/2010/02/Install_Django_and_Build_Your_First_App" title="Tutorial:Install Django and Build Your First App"> Lesson 2: Install Django and Build Your First App</a><br />

<a href="/2010/02/Use_URL_Patterns_and_Views_in_Django" title="Tutorial:Use URL Patterns and Views in Django"> Lesson 3: Use URL Patterns and Views in Django</a><br />

<strong class="selflink"> Lesson 4: User Templates in Django</strong><br />

<a href="/2010/02/Integrate_Web_APIs_into_Your_Django_Site" title="Tutorial:Integrate Web APIs into Your Django Site"> Lesson 5: Use Web API Data in Django</a><br />

<a href="/2010/02/Build_a_Microblog_with_Django" title="Tutorial:Build a Microblog with Django"> Lesson 6: Build a Microblog with Django</a>

</p>

</td></tr></tbody></table>



</div><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/use_templates_in_django/feed/</wfw:commentRss>
        <slash:comments>3</slash:comments>

        
    </item>
    
    <item>
        <title>Integrate Web APIs into Your Django Site</title>
        <link>http://www.webmonkey.com/2010/02/integrate_web_apis_into_your_django_site/</link>
        <comments>http://www.webmonkey.com/2010/02/integrate_web_apis_into_your_django_site/#comments</comments>
        <pubDate>Tue, 16 Feb 2010 01:45:47 +0000</pubDate>

                <dc:creator>Webmonkey Staff</dc:creator>

        <guid isPermaLink="false">http://stag.wired.com/primate/?p=929</guid>
        		<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[Welcome back! If you&#8217;ve been following along our entire series of tutorials on building sites with Django, you&#8217;ll (by now) have built a blog website with date-based archives and some nice extras such as tagging and Markdown support. Along the way, we also ported our app over to the new Newforms Admin version of Django [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p>Welcome back! If you&#8217;ve been following along our entire series of tutorials on building sites with Django, you&#8217;ll (by now) have built a blog website with date-based archives and some nice extras such as tagging and Markdown support.

</p><p>Along the way, we also ported our app over to the new Newforms Admin version of Django so that we&#8217;ll be all ready to go when Django hits version 1.0. If you haven&#8217;t done that yet, <a href="/2010/02/Django_Newforms_Admin_Migration" title="Tutorial:Django Newforms Admin Migration"> be sure to do it before we continue</a>.

</p><span id="more-929"></span>

<table id="toc" class="toc" summary="Contents"><tbody><tr><td><div id="toctitle"><h2>Contents</h2> </div>



<ol>

<li><a href="#Delicious_data">Delicious data</a></li>

<li><a href="#Building_the_model">Building the model</a></li>

<li><a href="#Building_a_Delicious_client">Building a Delicious client</a></li>

<li><a href="#Using_our_new_client">Using our new client</a></li>



<li><a href="#It.27s_all_in_the_timing">It&#8217;s all in the timing</a></li>

<li><a href="#Displaying_links">Displaying links</a></li>

<li><a href="#Conclusion">Conclusion</a></li>

</ol>

</td></tr></tbody></table>



<a name="Delicious_data"></a><h2> <span class="mw-headline">Delicious data</span></h2>



<p>Now let&#8217;s branch out a little bit. Blogs are fine and dandy, but what about some of the cool web services we all use &#8212; Flickr, Delicious, Upcoming and the like. Wouldn&#8217;t it be cool if you could pull custom data from those services and display it on our site?

</p><p>I&#8217;m going to walk you through integrating data from <a href="http://www.delicious.com" class="external text" title="http://www.delicious.com" rel="nofollow">Delicious</a>, the popular social bookmarking site, to power your own link blog. I&#8217;ve chosen Delicious because you&#8217;ll easily be able to take the basic outline we&#8217;ll use and apply it to any service with the decent API.

</p><p>The way our setup will work is whenever we want to post a link to our site, we&#8217;ll take advantage of the nice Delicious front-end tools like browser add-ons and bookmarklets. We&#8217;ll then use the Delicious API to pull that info into our own site.

</p><p>Before we get started, you might be wondering why? What&#8217;s the point when there are dead simple cut-and-paste JavaScript widgets that can already do that for us?

</p><p>Well it&#8217;s true, there are some easier ways to integrate Delicious data, but JavaScript widgets don&#8217;t allow us to store the data locally on our own server, and that&#8217;s the win. There are two reasons local data is better. First, if Delicious goes down or the server stops responding for some reason, our local app is unaffected and keeps humming along as usual. Second, if Delicious ever goes away permanently or if you simply find another service you like better, it isn&#8217;t hard to add in the new service without affecting the existing data.

</p><p>Convinced? OK let&#8217;s get started.

</p>

<a name="Building_the_model"></a><h2> <span class="mw-headline">Building the model</span></h2>

<p>The first thing we&#8217;ll do is create a new app. Why not just add a bookmark to our blog app? Well you could, but I&#8217;ve broken it out on its own for portability and for easy reusability. So, create a new folder in our djangoblog project and name it &#8220;links.&#8221;

</p><p>Now in the links folder, create a new file called &#8220;models.py&#8221; (and don&#8217;t forget to add an __init__.py file in the links folder as well, so Python can access it). Open models.py in your text editor and add these lines:

</p>

<pre class="brush: js">from django.db import models



from tagging.fields import TagField

from tagging.models import Tag



class Link(models.Model):

    title = models.CharField(max_length=200)

    description = models.TextField()

    url = models.CharField(max_length=400)

    date = models.DateTimeField('Date published')

    tags = TagField()

    status = models.IntegerField(default=1)



    class Meta:

        ordering = ('-date',)

        get_latest_by = 'date'



    def __unicode__(self):

        return u'%s'&nbsp;%(self.title)



    def get_absolute_url(self):

        return "/link/%s/"&nbsp;%(self.id)



    def get_tags(self):

        return Tag.objects.get_for_object(self)







</pre>

<p>Look familiar? It should. It&#8217;s basically a very simplified version of our blog model. Now let&#8217;s add our Link model to the admin page. Create a new file in the links folder called &#8220;admin.py&#8221; and paste in this code:

</p>

<pre class="brush: js">from django.contrib import admin



from djangoblog.links.models import Link



class LinkAdmin(admin.ModelAdmin):

    pass



admin.site.register(Link, LinkAdmin)

</pre>

<p>Note that I haven&#8217;t customized anything here, but feel free to add some list_display options or filters for easier sorting in the Admin interface.

</p><p>Now, open up the admin.py file in your djangoblog folder and change it so that it matches this code:

</p>

<pre class="brush: js">from django.contrib import admin

from djangoblog.blog.models import Entry

from djangoblog.blog.admin import EntryAdmin



from djangoblog.links.models import Link

from djangoblog.links.admin import LinkAdmin



class AdminSite(admin.AdminSite):

    pass



site = AdminSite()

site.register(Entry, EntryAdmin)

site.register(Link, LinkAdmin)

</pre>

<p><br />

The last step is to let Django know about our new Links app, so open up your settings.py file and add &#8220;links&#8221; to your list of installed apps.

</p><p>Now run syncdb in the shell:

</p>

<pre class="brush: js">python manage.py syncdb

</pre>

<p>And you&#8217;ll see that Django has created the required database tables. Fire up the development server and refresh the admin page to see your new links model.



</p><p><br />

</p>

<a name="Building_a_Delicious_client"></a><h2> <span class="mw-headline">Building a Delicious client</span></h2>

<p>Having Django set up the backend is pretty cool, but we don&#8217;t actually want to administer our links &#8212; we want them to be automatically created when we bookmark something on Delicious.com.

</p><p>To do that we&#8217;re going to need to send our user name and password over to Delicious which will the return a list of our most recent bookmarks. Then we need to parse through the XML, grab the data we need and store it in our new Link model.

</p><p>It might sound very complex, but it really isn&#8217;t, and once you have it set up you&#8217;ll never have to bother with it again, so let&#8217;s get started.

</p><p>What we need is a very simple client program to interact with Delicious.com. Luckily, there is a <a href="http://nixbit.com/cat/internet/nttp-%28www%29/delicious-python/" class="external text" title="http://nixbit.com/cat/internet/nttp-(www)/delicious-python/" rel="nofollow">Python library</a> that does just that. However, I find its dependancies make it more of a hassle than it needs to be. So I wrote my own client, which is dead simple, lacks many features of the other, but works for our purposes.

</p><p>Now you might be wondering, where should we store this? There isn&#8217;t a hard and fast rule that I know of, but I generally stick these sorts of things in the &#8220;utils.py&#8221; file within my app. So, create a new file in the links directory and name it utils.py.

</p><p>Here&#8217;s the code (which was sort of mashed up from several sources):

</p>

<pre class="brush: js">import urllib

import time

import dateutil.parser

import dateutil.tz

import xml.etree.cElementTree as xml_parser

from django.utils.encoding import smart_unicode



from djangoblog.links.models import Link



class DeliciousClient(object):

    interval = 0



    def __init__(self, username, password):

        self.username, self.password = username, password



    def fetch(self, **params):

        delta = time.time() - DeliciousClient.interval

        if delta &lt; 2:

            time.sleep(2 - delta)

        DeliciousClient.interval = time.time()

        url = 'https://%s:%s@api.del.icio.us/v1/posts/recent'&nbsp;% (self.username, self.password)

        return self.fetch_xml(url)



    def fetch_xml(self, url):

        u = urllib.FancyURLopener(None)

        usock = u.open(url)

        rawdata = usock.read()

        usock.close()

        return xml_parser.fromstring(rawdata)





    def __getattr__(self, method):

        return DeliciousClient(self.username, self.password, '%s/%s'&nbsp;% (self.method, method))



    def __repr__(self):

        return "&lt;DeliciousClient&gt;"





def create_link(data):

    for post in data.findall('post'):

        info = dict((k, smart_unicode(post.get(k))) for k in post.keys())

        b, created = Link.objects.get_or_create(

            url = info['href'],

            description = info['extended'],

            tags = info.get('tag', ''),

            date = parsedate(info['time']),

            title = info['description']

        )





def parsedate(s):

	dt = dateutil.parser.parse(s)

	if dt.tzinfo:

	    dt = dt.astimezone(dateutil.tz.tzlocal()).replace(tzinfo=None)

	return dt



</pre>

<p>There are many ways we could do this. Granted, my particular take is not the best, but I wanted to avoid dependancies, which this does. The only exception is that the ElementTree library is only present starting in Python 2.5. If you&#8217;re using an earlier version you&#8217;ll need to download and install ElementTree separately if you want to use this code.

</p><p>So what&#8217;s going on here? Well we have a class <code>DeliciousClient</code> which then has several methods. The main method of importance is &#8220;fetch,&#8221; which, when called, will return an ElementTree object with the 15 most recent links from our Delicious account.

</p><p>One thing to note: one of the rules of the Delicious API is that you can&#8217;t ping it more frequently than once per second. The code at the top of the <code>fetch</code> function ensures that we don&#8217;t exceed that limit.

</p><p>After the class, we have a small helper function that simply loops through the returned ElementTree object, pulls out the data nodes we need and then creates a new link in our database if one doesn&#8217;t already exist.

</p><p>The last function is just a generic date parser that converts a string into a date object, since that&#8217;s what our Django model is looking for.

</p>

<a name="Using_our_new_client"></a><h2> <span class="mw-headline">Using our new client</span></h2>

<p>So how does it work? Well, in order to demonstrate this app and run it on your own site, you&#8217;ll need to have a Delicious account with some links in it. So once you&#8217;re set up, follow along and get ready to import some links.



</p><p>Fire up your terminal and start the Django python client:

</p>

<pre class="brush: js">djangoblog sng$ python manage.py shell

</pre>

<p>Now let&#8217;s import our new tools and put them to use:

</p>

<pre class="brush: js">&gt;&gt;&gt; from djangoblog.links import utils

&gt;&gt;&gt; client = utils.DeliciousClient('username','passwd')

</pre>

<p>OK, now it&#8217;s time to fetch the data and save it to the database:

</p>

<pre class="brush: js">&gt;&gt;&gt; data = client.fetch()

&gt;&gt;&gt; utils.create_link(data)



</pre>

<p>With any luck, your fifteen most recent Delicious links should now be visible in the admin section. Start the dev server and refresh the page.

</p>

<a name="It.27s_all_in_the_timing"></a><h2> <span class="mw-headline">It&#8217;s all in the timing</span></h2>

<p>So far, we&#8217;re feeling pretty proud of ourselves. But we don&#8217;t want to have to log in to the shell every time we want to update our displayed list of bookmarks. In fact, we want our site to automatically update itself. To do that, we&#8217;re going to write a quick python script and then run it through a cron job.

</p><p>The only problem with that solution is that cron will run our script through the normal python interpreter which isn&#8217;t aware of our Django settings file and the like. Now worries though &#8212; we just need to tell it about it.

</p><p>Create a new file named sync_link.py and paste in this code:

</p>

<pre class="brush: js">import sys, os



sys.path.append('/path/to/django')

sys.path.append('/path/to/djangoblog')

os.environ['DJANGO_SETTINGS_MODULE'] = 'djangoblog.settings'



from djangoblog.links import utils

client = utils.DeliciousClient('username','passwd')

data = client.fetch()

utils.create_link(data)

</pre>

<p>Now open your crontab and create a new entry that reads:

</p>

<pre class="brush: js">0,15,30,45 * * * * /path/to/python2.5 /path/to/sync_links.py 2&gt;&amp;1

</pre>



<p>That script will update your site with a new list every fifteen minutes. Naturally, you can adjust that list to suit your needs. If you&#8217;re a less-active bookmarker, once or twice per day should be sufficient.

</p><p><br />

</p>

<a name="Displaying_links"></a><h2> <span class="mw-headline">Displaying links</span></h2>

<p>To keep things simple, we&#8217;re not going to create permalink pages for our Delicious posts. If you&#8217;d like to do that, refer back to lesson 3, <a href="/2010/02/Use_URL_Patterns_and_Views_in_Django" class="external text" title="/2010/02/Use_URL_Patterns_and_Views_in_Django" rel="nofollow">Use URL Patterns and Views in Django</a>.

</p><p>Instead, we&#8217;ll just put our links in the sidebar of our blog. Open up the base.html template and add this code in the sidebar section:

</p>

<pre class="brush: js">&lt;h3&gt;Recent Delicious Links&lt;/h3&gt;

{% get_latest links.Link 5 as recent_links&nbsp;%}



&lt;ul class="archive"&gt;

	{% for obj in recent_links&nbsp;%}

	&lt;li&gt;

		&lt;a href="{{ obj.url }}" title="{{ obj.title}}"&gt;{{ obj.title}}&lt;/a&gt;{{obj.description}} Posted on {{obj.pub_date|date:"D d M Y"}}

	&lt;/li&gt;

	{% endfor&nbsp;%}



&lt;/ul&gt;

</pre>

<p>See, I told you that template tag would come in handy! We&#8217;ve used the very same template tag we <a href="/2010/02/Use_Templates_in_Django#Roll_your_own_template_tags" class="external text" title="/2010/02/Use_Templates_in_Django#Roll_your_own_template_tags" rel="nofollow">created in the last lesson to show recent blog entries</a> to display the links. Very nice.

</p>

<a name="Conclusion"></a><h2> <span class="mw-headline">Conclusion</span></h2>

<p>And there you have it, we&#8217;ve successfully integrated delicious into our blog. Hopefully, we&#8217;ve also shown how you might do something similar with other web services as well &#8212; Flickr, Twitter, Yelp, or anything with an API, really.

</p><p>Keep in mind that our Delicious client is just a quick and dirty hack. There are a number of ways you could improve it, such as adding functionality to check for updates to links that already exist. Or perhaps even abstract it some more so that it interacts with any of the many other Delicious API methods. The limits are&#8230; limitless.

</p><p>In the final installment of our Django Tutorial, we&#8217;ll set up our blog with a &#8220;river&#8221; of links and posts &#8212; a riff on the model popularized by FriendFeed and Tumblr &#8212; and add some RSS so people can subscribe to the streams of awesome content sure to follow.

</p><p>See you then.

</p>

<div id="series">



<div class="series_hdr">From the Django Tutorial series</div>

<table style="background: rgb(229, 249, 255) none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" width="620">

<tbody><tr>

<td>

<p><a href="/2010/02/Get_Started_With_Django" title="Tutorial:Get Started With Django"> Lesson 1: Get Started With Django</a><br />

<a href="/2010/02/Install_Django_and_Build_Your_First_App" title="Tutorial:Install Django and Build Your First App"> Lesson 2: Install Django and Build Your First App</a><br />

<a href="/2010/02/Use_URL_Patterns_and_Views_in_Django" title="Tutorial:Use URL Patterns and Views in Django"> Lesson 3: Use URL Patterns and Views in Django</a><br />

<a href="/2010/02/Use_Templates_in_Django" title="Tutorial:Use Templates in Django"> Lesson 4: User Templates in Django</a><br />



<strong class="selflink"> Lesson 5: Use Web API Data in Django</strong><br />

<a href="/2010/02/Build_a_Microblog_with_Django" title="Tutorial:Build a Microblog with Django"> Lesson 6: Build a Microblog with Django</a>

</p>

</td></tr></tbody></table>

</div><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/integrate_web_apis_into_your_django_site/feed/</wfw:commentRss>
        <slash:comments>0</slash:comments>

        
    </item>
    
    <item>
        <title>Build a Microblog with Django</title>
        <link>http://www.webmonkey.com/2010/02/build_a_microblog_with_django/</link>
        <comments>http://www.webmonkey.com/2010/02/build_a_microblog_with_django/#comments</comments>
        <pubDate>Tue, 16 Feb 2010 01:45:47 +0000</pubDate>

                <dc:creator>Webmonkey Staff</dc:creator>

        <guid isPermaLink="false">http://stag.wired.com/primate/?p=931</guid>
        		<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[wiki]]></category>
        <description><![CDATA[Thus far in our introductory Django tutorial, we&#8217;ve installed the open-source Django framework, set up a blog and beefed it up by adding some extras like semantic content tags, some handy template tags and a list of our bookmarks from delicious.com. If you haven&#8217;t been following along, now would be a good time to go [...]]]></description>

            <content:encoded><![CDATA[<!-- wpautop disabled --><p>Thus far in our introductory Django tutorial, we&#8217;ve <a href="/2010/02/Install_Django_and_Build_Your_First_App" title="Tutorial:Install Django and Build Your First App"> installed the open-source Django framework</a>, set up a blog and beefed it up by adding some extras like <a href="/2010/02/Use_URL_Patterns_and_Views_in_Django" title="Tutorial:Use URL Patterns and Views in Django"> semantic content tags</a>, some handy <a href="/2010/02/Use_Templates_in_Django" title="Tutorial:Use Templates in Django"> template tags</a> and <a href="/2010/02/Integrate_Web_APIs_into_Your_Django_Site" title="Tutorial:Integrate Web APIs into Your Django Site"> a list of our bookmarks from delicious.com</a>. If you haven&#8217;t been following along, now would be a good time to go back to <a href="/2010/02/Get_Started_With_Django" title="Tutorial:Get Started With Django"> Lesson 1</a> and catch up.



</p><p>However, what we&#8217;ve created is not much different than what one could do with WordPress or another out-of-the-box blogging tool. That&#8217;s OK for a learning project. But now we&#8217;re getting close to being experts, we are going to explore some territory beyond what we can do with pre-built tools.

</p><p>Let&#8217;s build something a little more advanced. Let&#8217;s build a microblog.

</p><span id="more-931"></span>

<table id="toc" class="toc" summary="Contents"><tbody><tr><td><div id="toctitle"><h2>Contents</h2> </div>

<ol>

<li><a href="#Let.27s_get_ready_to_Tumble">Let&#8217;s get ready to Tumble</a></li>



<li><a href="#Laying_the_groundwork">Laying the groundwork</a></li>

<li><a href="#How_it_works">How it works</a></li>

<li><a href="#Listen_for_the_Signals">Listen for the Signals</a></li>

<li><a href="#Writing_the_URLs_and_views">Writing the URLs and views</a></li>

<li><a href="#Where_do_we_go_from_here.3F">Where do we go from here?</a></li>



<li><a href="#RSS_feeds">RSS feeds</a></li>

<li><a href="#Conclusion">Conclusion</a></li>

</ol>

</td></tr></tbody></table>



<a name="Let.27s_get_ready_to_Tumble"></a><h2> <span class="mw-headline">Let&#8217;s get ready to Tumble</span></h2>

<p>These days, many of us follow our friends on services like FriendFeed or Facebook, where the concept of a &#8220;blog post&#8221; is much looser, smaller and faster.

</p><p>Whether you want to call it a newsfeed, lifestream, microblog, tumblelog or a dozen other clever portmanteaus or neologisms, the concept is the same: a site to log snippets of your life and its discoveries in one place.

</p><p>FriendFeed is a favorite. The service combines tweets from Twitter, photos from Flickr, links from Delicious, updates from Facebook and other sundry data and displays them all on one page. The page itself also has an RSS feed, giving you (or any of your many fans) a way to follow your every move.



</p><p>Let&#8217;s build a version of Friendfeed using Django.  We&#8217;ll build a page displaying both our links and blog posts together in a single, time-based &#8220;river.&#8221; As a bonus we&#8217;ll add in some RSS sugar so our friends can follow along without having to visit the site.

</p>

<a name="Laying_the_groundwork"></a><h2> <span class="mw-headline"> Laying the groundwork </span></h2>

<p>Before we get started, let&#8217;s think for a bit about what needs to be done. We will post data two separate using two models: the blog Entry model and the Link model. We need to query them both at the same time and then sort the feed into reverse chronological order.

</p><p>The key to making it work is by creating a way to normalize our data. The database table for each of these models are significantly different. Instead of querying both models, wouldn&#8217;t it be better if we just query against one table?

</p><p>Let&#8217;s do it.

</p>

<a name="How_it_works"></a><h2> <span class="mw-headline"> How it works </span></h2>

<p>There&#8217;s one thing all models will have in common: a publication date. What we&#8217;re going to do is create a kind of meta model which stores the date as well as what kind of data it is (i.e. blog entry, link, etc).

</p><p>Django ships with two tools which actually make it very easy to build our meta model. The first is the <a href="http://www.djangoproject.com/documentation/contenttypes/" class="external text" title="http://www.djangoproject.com/documentation/contenttypes/" rel="nofollow">content types framework</a>. As the docs explain, &#8220;instances of ContentType represent and store information about the models installed in your project, and new instances of ContentType are automatically created whenever new models are installed.&#8221;



</p><p>Huh? Basically, what the Django Project is telling us is just by referencing the content type, we will always know what type of content we&#8217;re storing. Storing the content type is half the battle.

</p><p>The other half of the battle will be won by using a built-in field known as a <a href="http://www.djangoproject.com/documentation/contenttypes/#generic-relations" class="external text" title="http://www.djangoproject.com/documentation/contenttypes/#generic-relations" rel="nofollow">GenericForeignKey</a>. You may have noticed a ForeignKey field in the Django docs. ForeignKey is similar to what we&#8217;re going to use. Where ForeignKey refers to a single model, our GenericForeignKey can refer to any model by referencing the content_type instead.

</p><p>If that sounds confusing, don&#8217;t worry. It&#8217;ll make more sense when you see it in action.

</p><p>Let&#8217;s start writing some code. I&#8217;m going to store our meta app in a folder named &#8220;tumblelog&#8221; so create the folder and create a new <code>models.py</code> file inside it (don&#8217;t forget the <code>__init__.py</code> file as well, Python&#8217;s never-ending &#8220;gotcha&#8221;). Open up <code>models.py</code> in your text editor and paste in this code:

</p>

<pre class="brush: js">from django.db import models

from django.contrib.contenttypes import generic



class TumbleItem(models.Model):

    content_type = models.ForeignKey(ContentType)

    object_id = models.PositiveIntegerField()

    pub_date = models.DateTimeField()

    content_object = generic.GenericForeignKey('content_type', 'object_id')



    class Meta:

        ordering = ('-pub_date',)



    def __unicode__(self):

        return self.content_type.name





</pre>

<p>If you&#8217;re familiar with our previous tutorials (or Django in general), by now this should look somewhat familiar. We have a regular <code>ForeignKey</code> to the <code>ContentType</code> as we discussed above. Then we have an <code>id</code> field, which we need to pass to the <code>GenericForeignKey</code> field (along with <code>content_type</code>). Finally we add a <code>datetime</code> field for easy sorting. If you look at the <code>GenericForeignKey</code> documentation you&#8217;ll notice this is pretty much the same code used to demonstrate <code>GenericForeignKeys</code>. The only difference is we&#8217;ve added a <code>date</code> field.



</p><p>Now we have a basic script, but we certainly don&#8217;t want to update this by hand every time we post something. Especially since our delicious.com import script runs automatically.

</p><p>Well, it turns out there&#8217;s a very powerful feature baked into Django which can handle the task for us.

</p><p>Django includes an internal &#8220;dispatcher&#8221; which allows objects to listen for signals from other objects. In our case, our tumblelog app is going to &#8220;listen&#8221; to our Entry and Link models. Every time a new Entry or Link is saved, those models will send out a signal. When the tumblelog app gets the signal it will automatically update itself.

</p><p>Sweet. How do we do it?

</p>

<a name="Listen_for_the_Signals"></a><h2> <span class="mw-headline"> Listen for the Signals </span></h2>

<p>The first thing we need to do is import the signals framework. Add this to the top of your <code>model.py</code> file:

</p>

<pre class="brush: js">from django.db.models import signals

from django.contrib.contenttypes.models import ContentType

from django.dispatch import dispatcher

from blog.models import Entry

from links.models import Link

</pre>

<p>OK, now move to the bottom of the file and add these lines:



</p>

<pre class="brush: js">for modelname in [Entry, Link]:

	dispatcher.connect(create_tumble_item, signal=signals.post_save, sender=modelname)



</pre>

<p>In Django 1.1 (and 1.0 I think) the signal have changed.

Change the import to:

</p>

<pre class="brush: js">from django.db.models import signals

from django.contrib.contenttypes.models import ContentType

from django.db.models.signals import post_save

from blog.models import Entry

from links.models import Link

</pre>

<p>and change the dispatcher line to

</p>

<pre class="brush: js">post_save.connect(create_tweet_item, sender=Entry)

post_save.connect(create_tweet_item, sender=Link)

</pre>

<p><br />

</p><p><br />

So what&#8217;s it do? Well it tells the dispatcher to listen for the <code>post_save</code> signal from out Entry and Link models and whenever it gets the signal, it will fire off our <code>create_tumble_item</code> function.



</p><p>But wait, we don&#8217;t have a <code>create_tumble_item</code> function do we?

</p><p>No, so we better write one. Just above the <code>dispatcher</code> function add this code:

</p>

<pre class="brush: js">def create_tumble_item(sender, instance, signal, *args, **kwargs):

	if 'created' in kwargs:

		if kwargs['created']:

			create = True

			ctype = ContentType.objects.get_for_model(instance)

			if ctype.name == 'link':

				pub_date = instance.date

			else:

				pub_date = instance.pub_date

			if create:

				t = TumbleItem.objects.get_or_create(content_type=ctype, object_id=instance.id, pub_date=pub_date)

</pre>

<p>What&#8217;s this function doing? For the most part it&#8217;s just taking the data sent by the dispatcher and using it to create a new <code>TumbleItem</code>.

</p><p>The first line looks to see if a variable, <code>created</code>, has been passed by the dispatcher. The <code>post_save</code> signal is sent everytime an object is saved, so it&#8217;s possible we&#8217;ve just updated an existing item rather than creating a new one. In that case, we don&#8217;t want to create a new <code>TumbleItem</code>, so the function checks to make sure this is, in fact, a new object.



</p><p>If the dispatcher has passed the variable <code>created</code>, and its true, then we set our own <code>create</code> flag and get the <code>content_type</code> of the passed instance. This way, we know whether it&#8217;s a Link or an Entry.

</p><p>If it&#8217;s a Link we need to find the datetime info. When we built our Link model, we called the field <code>date</code>, so we set our normalizing <code>pub_date</code> field equal to the <code>instance.date</code> field.



</p><p>If the instance is a blog Entry we set <code>pub_date</code> to the value of the instance&#8217;s <code>pub_date</code> field since, it shares the name we used in our Entry model.

</p><p>Then we create a new TumbleItem using the built-in <code>get_or_create</code> method. We also pass in a <code>content_type</code>, <code>id</code> and <code>pub_date&lt;code&gt; to their respective fields.



</code></p><p>And there you have it. Any time you create a blog entry or the script adds a new link, our new TumbleItem model will automatically update.

</p><p>There&#8217;s a slight problem though. What about the data we&#8217;ve already got in there?

</p><p>Well to make sure it gets added, we&#8217;re going to have to comment out the following lines:

</p>

<pre class="brush: js">	if 'created' in kwargs:

		if kwargs['created']:

</pre>

<p>Comment it out and save the file. Then fire up the terminal and enter this code one line at a time:

</p>

<pre class="brush: js">&gt;&gt;&gt; from blog.models import Entry

&gt;&gt;&gt; from link.models import Link

&gt;&gt;&gt; entries = Entry.objects.all()

&gt;&gt;&gt; for entry in entries:

...     entry.save()

...



&gt;&gt;&gt; links = Link.objects.all()

&gt;&gt;&gt; for link in Link:

...     link.save()

...

&gt;&gt;&gt;

</pre>

<p>What did it do? We just called the &lt;code&gt;save method and dispatcher passed its signal along to the TumbleItem model which then updated itself. Because we commented out the lines that check to see if an item is new, the function ran regardless of the instance&#8217;s created variable.

</p><p>Now uncomment those lines and save the file.

</p><p>Before we move on I should point out <code>post_save</code> isn&#8217;t the only signal Django can send. There are in fact a whole bunch of useful signals like <code>request_started</code>, <code>pre_save</code> and many more. Check out the <a href="http://code.djangoproject.com/wiki/Signals" class="external text" title="http://code.djangoproject.com/wiki/Signals" rel="nofollow">Django wiki</a> for more details.



</p><p><br />

</p>

<a name="Writing_the_URLs_and_views"></a><h2> <span class="mw-headline"> Writing the URLs and views </span></h2>

<p>Now we need to add a tumblelog URL and pull out the data. Open up your project level <code>urls.py</code> file and add this line:

</p>

<pre class="brush: js">(r'^tumblelog/', 'tumblelog.views.tumbler'),

</pre>

<p>Now create a new <code>views.py</code> file inside your tumblelog folder and open it up to paste in this code:



</p>

<pre class="brush: js">from tumblelog.models import TumbleItem

from django.shortcuts import render_to_response



def tumbler(request):

	context = {

		'tumble_item_list': TumbleItem.objects.all().order_by('-pub_date')

	}



	return render_to_response('tumblelog/list.html', context)

</pre>

<p>What&#8217;s going on here? Well first we grab the tumblelog items and then we use a Django shortcut function to return to pass the list on to template named <code>list.html</code>.

</p><p>Let&#8217;s create the template. Add a new folder &#8220;tumblelog&#8221; inside your templates folder and create the <code>list.html</code> file. We&#8217;ll start by extending our base template and filling in the blocks we created in <a href="/2010/02/Use_Templates_in_Django" title="Tutorial:Use Templates in Django"> an earlier lesson</a>:

</p>

<pre class="brush: js">{% block title&nbsp;%}My Tumblelog{% endblock&nbsp;%}

{% block primary&nbsp;%}

{% for object in object_list&nbsp;%}

	{%if object 'link'%}

		&lt;a href="{{ obj.url }}" title="{{ obj.title}}"&gt;{{ obj.title}}&lt;/a&gt;{{object.description}} Posted on {{object.pub_date|date:"D d M Y"}}

	{% endif&nbsp;%}



	{%if object 'entry'%}

		&lt;h2&gt;{{ object.title }}&lt;/h2&gt;



		&lt;p&gt;{{ object.pub_date }}&lt;/p&gt;

		{{ object.body_html|truncatewords_html:"20"|safe }}

		&lt;p&gt;&lt;a href="{{object.get_absolute_url}}"&gt;more&lt;/a&gt;&lt;/p&gt;

	{% endif&nbsp;%}

{% endfor&nbsp;%}

{% endblock&nbsp;%}



</pre>

<p>If you start up the development server and head to <a href="http://127.0.0.1:8000/tumblelog/" class="external free" title="http://127.0.0.1:8000/tumblelog/" rel="nofollow">http://127.0.0.1:8000/tumblelog/</a> you should see your blog entries and links ordered by date.

</p>

<a name="Where_do_we_go_from_here.3F"></a><h2> <span class="mw-headline"> Where do we go from here? </span></h2>

<p>We&#8217;re looking pretty good up until we get to the template stage. The <code>if</code> statements aren&#8217;t so bad when we&#8217;re only sorting two content types, but if you start pulling in tons of different types of data you&#8217;ll quickly end up with spaghetti code.

</p><p>A far better idea would be to write a template tag which takes the <code>content type</code> as an argument, uses it to call a template file, renders it and passes back to the html as a string.



</p><p>We&#8217;ll leave it up to you as an exercise (hint: read up on Django&#8217;s <a href="http://www.djangoproject.com/documentation/templates_python/#the-render-to-string-shortcut" class="external text" title="http://www.djangoproject.com/documentation/templates_python/#the-render-to-string-shortcut" rel="nofollow">render_to_string method</a>).

</p><p>The other thing you might be wondering about is pagination. If you save dozens of links a day and blog like a madman, this page is going to get really large really fast. Django ships with some built-in pagination tools (see <a href="http://www.djangoproject.com/documentation/pagination/" class="external text" title="http://www.djangoproject.com/documentation/pagination/" rel="nofollow">the docs</a>) and there&#8217;s also a slick <a href="http://code.google.com/p/django-pagination/" class="external text" title="http://code.google.com/p/django-pagination/" rel="nofollow">django-pagination app</a> available from Eric Florenzano. Eric even has a <a href="http://eflorenzano.com/blog/post/first-two-django-screencasts/#using-django-pagination" class="external text" title="http://eflorenzano.com/blog/post/first-two-django-screencasts/#using-django-pagination" rel="nofollow">very nice screencast</a> on how to set things up.

</p><p><br />

</p>

<a name="RSS_feeds"></a><h2> <span class="mw-headline"> RSS feeds </span></h2>



<p>We&#8217;re almost done. Let&#8217;s hook up some RSS feeds for our new site.

</p><p>It turns out, Django ships with a very nice <a href="http://www.djangoproject.com/documentation/syndication_feeds/" class="external text" title="http://www.djangoproject.com/documentation/syndication_feeds/" rel="nofollow">syndication framework</a>. All we need to do is turn it on and hook it up.

</p><p>Let&#8217;s start by going into our TumbleItem <code>models.py</code> file and setting up the framework. Paste in this code at the bottom of the file:

</p>

<pre class="brush: js">from django.contrib.syndication.feeds import Feed

class LatestItems(Feed):

    title = "My Tumblelog: Links"

    link = "/tumblelog/"

    description = "Latest Items posted to mysite.com"

    description_template = 'feeds/description.html'



    def items(self):

        return TumbleItems.objects.all.order_by('-pub_date')[:10]



</pre>

<p>Here we&#8217;ve imported the syndication class <code>Feed</code> and then defined our own feed class to fill in some basic data. The last step is returning the items using a normal <code>objects</code> query.



</p><p>We need to create the URLs first. There are several places you could do this, I generally opt for the main project URLs.py file. Open it up and paste this code just below the other import statements:

</p>

<pre class="brush: js">from tumblelog.models import LatestItems

feeds = {

    'tumblelog': LatestItems

}

</pre>

<p>Now add this line to your <code>urlpattern</code> function:

</p>

<pre class="brush: js">(r'^feeds/(?P&lt;url&gt;.*)/$', 'django.contrib.syndication.views.feed', {'feed_dict': feeds}),

</pre>

<p>The last step is creating the description template in a new folder we&#8217;ll lable &#8220;feeds.&#8221; Just plug in the same code from the tumblelog template, but delete the <code>forloop</code> tag since we&#8217;re only passing a single object this time.



</p><p>And there you have it. Fire up the development server and point it to <a href="http://127.0.0.1:8000/feeds/tumblelog/" class="external free" title="http://127.0.0.1:8000/feeds/tumblelog/" rel="nofollow">http://127.0.0.1:8000/feeds/tumblelog/</a>. If you want to add separate feeds for links or just blog entries, all you need to do is repeat the process, creating new <code>feed</code> classes for each.

</p>

<a name="Conclusion"></a><h2> <span class="mw-headline"> Conclusion </span></h2>

<p>Whew! It&#8217;s been a long journey and we wrote a lot of code, but hopefully you learned a good bit about how Django works. You not only have a blog/linklog/tumblelog, but hopefully some ideas of how to approach other projects.

</p><p>Speaking of projects, although we used one, there&#8217;s really no need to organize your code this way. Sometimes the projects come in handy, but other times they make your PYTHONPATH into a snarled mess. For some other ideas on how organize you code, check out James Bennet&#8217;s <a href="http://www.b-list.org/weblog/2007/nov/09/projects/" class="external text" title="http://www.b-list.org/weblog/2007/nov/09/projects/" rel="nofollow">article on the subject</a>.

</p><p>If you ever have questions about Django, jump on the <a href="irc://irc.freenode.net/django" class="external text" title="irc://irc.freenode.net/django" rel="nofollow">#Django IRC channel</a>, there&#8217;s load of friendly and helpful developers who can point you in the right direction, and be sure to <a href="http://groups.google.com/group/django-users" class="external text" title="http://groups.google.com/group/django-users" rel="nofollow">join the mailing list</a>. Happy coding!



</p>

<div id="series">

<div class="series_hdr">From the Django Tutorial series</div>

<table style="background: rgb(229, 249, 255) none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" width="620">

<tbody><tr>

<td>

<p><a href="/2010/02/Get_Started_With_Django" title="Tutorial:Get Started With Django"> Lesson 1: Get Started With Django</a><br />

<a href="/2010/02/Install_Django_and_Build_Your_First_App" title="Tutorial:Install Django and Build Your First App"> Lesson 2: Install Django and Build Your First App</a><br />

<a href="/2010/02/Use_URL_Patterns_and_Views_in_Django" title="Tutorial:Use URL Patterns and Views in Django"> Lesson 3: Use URL Patterns and Views in Django</a><br />

<a href="/2010/02/Use_Templates_in_Django" title="Tutorial:Use Templates in Django"> Lesson 4: User Templates in Django</a><br />



<a href="/2010/02/Integrate_Web_APIs_into_Your_Django_Site" title="Tutorial:Integrate Web APIs into Your Django Site"> Lesson 5: Use Web API Data in Django</a><br />

<strong class="selflink"> Lesson 6: Build a Microblog with Django</strong>

</p>

</td></tr></tbody></table>

</div><div id='linker_widget' class='contextly-widget'></div>]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2010/02/build_a_microblog_with_django/feed/</wfw:commentRss>
        <slash:comments>2</slash:comments>

        
    </item>
    
    <item>
        <title>The Problem With Python</title>
        <link>http://www.webmonkey.com/2008/10/the_problem_with_python/</link>
        <comments>http://www.webmonkey.com/2008/10/the_problem_with_python/#comments</comments>
        <pubDate>Fri, 10 Oct 2008 18:18:45 +0000</pubDate>

                <dc:creator>Michael Calore</dc:creator>

        <guid isPermaLink="false">http://www.webmonkey.com/blog/theproblemwithpython</guid>
        		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[python]]></category>
        <description><![CDATA[If you were a young programmer trying to pick a language to learn, based on these two websites, which would you choose? Python or Java?]]></description>

            <content:encoded><![CDATA[<p><!-- wpautop enabled --><img class="blogimg" src="http://howto.wired.com/mediawiki/images/Java_babes.jpg" /></p>
<p>If you were a young programmer trying to pick a language to learn, based on these two websites, which would you choose?</p>
<h3><a href="http://www.python.org">Python</a> or <strong><a href="http://www.java.com">Java</a></strong><strong>?</strong></h3>
<div id='linker_widget' class='contextly-widget'></div>
]]></content:encoded>
            <wfw:commentRss>http://www.webmonkey.com/2008/10/the_problem_with_python/feed/</wfw:commentRss>
        <slash:comments>0</slash:comments>

        
    </item>
    </channel>
</rss>