<?xml version="1.0" encoding="UTF-8"?>

<rss version='2.0' 
     xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule"
     xmlns:doap="http://usefulinc.com/ns/doap#"
     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">

    <channel>
        <!-- This XML Feed shows details for the page django 
             and everything recently tagged django -->
        <creativeCommons:license>http://creativecommons.org/licenses/by-sa/2.5/
          </creativeCommons:license>
        <title>django on SWiK</title>
        <doap:name>django</doap:name>
        <doap:description>&lt;p&gt;&amp;#8220;The Web Framework for Perfectionists with Deadlines.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;Django is a high-level &lt;a class="wikilink" href="http://swik.net/Python"&gt;Python&lt;/a&gt; Web framework that encourages rapid development and clean, pragmatic design.&lt;/p&gt;


	&lt;p&gt;Initially developed at a local newspaper in Kansas, it has since found favour for developing all kinds of sites and applications, from content-heavy sites such as &lt;a rel="nofollow" href="http://www.lawrence.com"&gt;www.lawrence.com&lt;/a&gt; to &lt;a class="wikilink" href="http://swik.net/Web-2.0"&gt;Web 2.0&lt;/a&gt; applications such as &lt;a rel="nofollow" href="http://www.tabblo.com"&gt;www.tabblo.com&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Django is quite popular for its extensive documentation.&lt;/p&gt;
</doap:description>
        <description>&amp;#8220;The Web Framework for Perfectionists with Deadlines.&amp;#8221;


	Django is a high-level Python Web framework that encourages rapid development and clean, pragmatic design.


	Initially developed at a local newspaper in Kansas, it has since found favour for developing all kinds of sites and applications, from content-heavy sites such as www.lawrence.com to Web 2.0 applications such as www.tabblo.com.


	Django is quite popular for its extensive documentation.
</description> 
	  <!-- see doap:description for full description -->
        <link>http://swik.net/django</link>
        <doap:homepage>http://www.djangoproject.com/</doap:homepage>
                <category>Framework</category>
        <category>python</category>
        <category>Web</category>
        <category>CMS</category>
        <category>django</category>
        <category>web-framework</category>
        <category>License:BSD</category>

        <pubDate>Mon, 18 Jul 2005 03:16:20 -0700</pubDate>
        <lastBuildDate>Sun, 27 Jan 2008 14:02:41 -0800</lastBuildDate>
            
        <item>
            <title>Will Larson: Dynamic Ad Targeting With django-monetize</title>
            <link>http://swik.net/django/Django+Community+Aggregator/Will+Larson%3A+Dynamic+Ad+Targeting+With+django-monetize/cc5sb</link>
            <description>&lt;p&gt;This is probably the most exciting Django project I have worked on, and I&#039;m glad that it has gotten to sufficient usable point to share. It is my pleasure to present &lt;code&gt;django-monetize&lt;/code&gt;.
&lt;/p&gt;
&lt;p&gt;&lt;code&gt;django-monetize&lt;/code&gt; is a pluggable Django app which aims to make it trivial to intelligently monetize your Django projects. It was designed with two guiding principles:
&lt;/p&gt;
&lt;ol&gt;
 &lt;li&gt;&lt;p&gt;There are many forms of monetization, and generally a mix-and-match approach will outperform a single monetization solution (for example, a thoughtful combination of donations, Amazon Affiliates and AdSense will perform better than AdSense alone). Switching between and experimenting with different forms and combinations of monetization is a key part of success.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;You can greatly enhance monetization by effectively targeting subgroups of your readers. Your monetization will be more effective if you have the ability to display different ads to users coming from search engines (perhaps AdSense would perform better) or Reddit (perhaps... silly tshirts would sell?), using different browsers (wait, I&#039;m marketing my OSX app to internet explorer users?), and viewing different kinds of materials (someone reading an indepth tutorial would be more likely to donate than someone reading your rant about licorice jellybeans).
&lt;/p&gt;

 &lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;Supported Forms of Monetization&lt;/h3&gt;
&lt;p&gt;So far, &lt;code&gt;django-monetize&lt;/code&gt; has built in support for Amazon Affiliates&#039; Custom Links, Amazon Affiliates&#039; Omakase, Amazon Affiliates&#039; Search Links, Amazon Honor System donations, Dreamhost referrals, Google Adsense ad units, Paypal donations, and SliceHost referrals.
&lt;/p&gt;
&lt;p&gt;Its trivial (and encouraged) to add more of your own or customize the existng ones to be more appropriate for your website. It is easy to create your own custom adverts (perhaps an e-book you wrote, linking to a popular blog entry you put together, or advertising your new startup).
&lt;/p&gt;

&lt;h3&gt;Installation&lt;/h3&gt;
&lt;p&gt;Install &lt;code&gt;django_monetize&lt;/code&gt; like you would any other application. Check it out from its &lt;a href=&quot;http://github.com/lethain/django-monetize/tree/master&quot;&gt;repository&lt;/a&gt;, add the &lt;code&gt;django_monetize&lt;/code&gt; directory to your Python site-packages folder so that:
&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;django_monetize&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;works without throwing an error.
&lt;/p&gt;
&lt;p&gt;Then simply add &lt;code&gt;django_monetize&lt;/code&gt; to the &lt;code&gt;INSTALLED_APPS&lt;/code&gt; setting in your &lt;code&gt;settings.py&lt;/code&gt; file and you&#039;re good to go. &lt;code&gt;django_monetize&lt;/code&gt; doesn&#039;t contain any models (or use the database in any way), so you don&#039;t need to perform a sync.
&lt;/p&gt;

&lt;h3&gt;Using &lt;code&gt;django-monetize&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;The real magic in &lt;code&gt;django-monetize&lt;/code&gt; is the level of customization and control that it allows. First lets examine usage at the template level. We&#039;ll start with the simplest examples and get more complex as we explore the flexibility.
&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;load&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;monetize&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;

&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;monetize_slot&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;p&amp;gt;&lt;/span&gt; Welcome to my site! &lt;span class=&quot;nt&quot;&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;monetize_slot&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;That will display two slots, both using the default monetization option (we&#039;ll look at setting up the targetting and default logic after we look at template configuration).
&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;load&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;monetize&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;

&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;monetize_slot&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;header&amp;quot;&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;p&amp;gt;&lt;/span&gt; Welcome to my site! &lt;span class=&quot;nt&quot;&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;monetize_slot&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;footer&amp;quot;&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Now we are labeling the slots. We can use labeling to display different types of monetization options in different locations. This is the simplest concept of targeting.
&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;load&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;monetize&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;

&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;monetize_slot&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;header&amp;quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;request.META.HTTP_REFERER&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;p&amp;gt;&lt;/span&gt; Welcome to my site! &lt;span class=&quot;nt&quot;&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;monetize_slot&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;footer&amp;quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;request.META.HTTP_USER_AGENT&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Now we&#039;re labeling slots and passing them them the referer and user agent respectively. &lt;code&gt;django-monetize&lt;/code&gt; will check against our targeting configuration and see if the current referer/user_agent is something we have specified targeting for, and will use the targeted advertisement if it exists, but will otherwise revert to the default advertisement.
&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;load&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;monetize&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;

&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;monetize_slot&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;header&amp;quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;object.title&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;object.series&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;object.tags&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;p&amp;gt;&lt;/span&gt; Welcome to my site! &lt;span class=&quot;nt&quot;&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;monetize_slot&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;footer&amp;quot;&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Here for the top slot we are beginning to see the flexibility of the targeting mechanism. It will first check if we have a targeted value for the object&#039;s title, will then check if we have targeted for any of the values in the &lt;code&gt;object.series&lt;/code&gt; list, and will finally check if we have targeted any of the values in the &lt;code&gt;object.tags&lt;/code&gt; list.
&lt;/p&gt;
&lt;p&gt;It will target on the first targeted value it reaches, and won&#039;t process the remaining parameters.
&lt;/p&gt;
&lt;p&gt;Finally, note that once you have found the targeted term, you are also able to specify the type of monetization for that targeted term in different slots. Thus you can display different ads in differently named slots even if you target on something as simple as this (which might be sufficient for mostly static content):
&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;load&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;monetize&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;

&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;monetize_slot&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;header&amp;quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;django&amp;quot;&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;p&amp;gt;&lt;/span&gt; Welcome to my site! &lt;span class=&quot;nt&quot;&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;monetize_slot&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;footer&amp;quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;django&amp;quot;&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Pretty flexible, eh?
&lt;/p&gt;

&lt;h3&gt;Valid Parameters for &lt;code&gt;monetize_slot&lt;/code&gt; template tag&lt;/h3&gt;
&lt;p&gt;We were using &lt;code&gt;monetize_slot&lt;/code&gt; in a variety of different ways in the above examples, and it behoves us to clarify the arguments that it can accept.
&lt;/p&gt;
&lt;ol&gt;
 &lt;li&gt;&lt;p&gt;It can be called with zero arguments, in which case it uses the default monetization option.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;It can be called with one argument, which must be the name of the slot. In that case it will use the default monetization option&#039;s targeted value for that slot--if such a targeting exists--and will otherwise resort to using the default option.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;It can be called with two or more arguments. The first argument &lt;em&gt;must be a string representing the slot&#039;s name&lt;/em&gt;. Subsequent arguments may be: strings (they may be strings stored in a context variable, or may be absolute strings declared in the template like&lt;code&gt;{% monetize_slot &amp;quot;header&amp;quot; &amp;quot;django&amp;quot; %}&lt;/code&gt;), dictionaries (whose values are processed using &lt;code&gt;iteritems()&lt;/code&gt;), or iterable items (defined as non-dictionary-non-string objects which have the &lt;code&gt;__iter__&lt;/code&gt; method).
   If it runs into a type of object which is not one of the above types (for example, when it is handling the contents of a queryset of your tags) it will convert the object into a string by calling &lt;code&gt;unicode(obj)&lt;/code&gt;. This means you&#039;ll target a specific object by using the string returned by its &lt;code&gt;__unicode__&lt;/code&gt; method.
&lt;/p&gt;

 &lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;Configuration&lt;/h3&gt;
&lt;p&gt;First, &lt;code&gt;django-monetize&lt;/code&gt;makes an important distinction between &lt;code&gt;None&lt;/code&gt; and &lt;code&gt;False&lt;/code&gt;. &lt;code&gt;None&lt;/code&gt; indicates &#039;use the default monetization method&#039;, whereas &lt;code&gt;False&lt;/code&gt; indicates &#039;do not use a monetization method.&#039; Acknowledging that this is an arbitrary and confusing decision, thus far it seems like a reasonable solution.
&lt;/p&gt;
&lt;p&gt;Configuration of ad targeting is done within your project&#039;s &lt;code&gt;settings.py&lt;/code&gt; file. There is an at least somewhat similar Django project, &lt;a href=&quot;http://code.google.com/p/django-ads/&quot;&gt;django-ads&lt;/a&gt;, which stores its configuration within the database. While that allows for a more dynamically modifiable system, &lt;code&gt;django-ads&lt;/code&gt; doesn&#039;t address the issue of ad targeting and customization to the extent that &lt;code&gt;django-monetize&lt;/code&gt; does, and I didn&#039;t see a reasonable way to store the configuration within the database (short of storing strings of Python code that were then evaluated, which strikes me as far from an acceptable solution).
&lt;/p&gt;
&lt;p&gt;There are three values used in the &lt;code&gt;settings.py&lt;/code&gt; file: &lt;code&gt;MONETIZE_TARGET&lt;/code&gt;, &lt;code&gt;MONETIZE_DEFAULT&lt;/code&gt;, and &lt;code&gt;MONETIZE_CONFIG&lt;/code&gt;. Lets start with a complex example an break it down.
&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;n&quot;&gt;MONETIZE_DEFAULT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&#039;django_monetize/amazon_search.html&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;amazon_search_terms&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;Django book&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;amazon_search_title&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;Search for Django books!&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;MONETIZE_TARGET&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&#039;django&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;django_monetize/paypal_donate.html&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&#039;Author (Will Larson)&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;django_monetize/amazon_honor.html&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&#039;Author (Joe Somebody)&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:(&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&#039;django_monetize/amazon_honor.html&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;amazon_paypage&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;Joe Somebodys Amazon Honor Paypage url&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&#039;tutorial&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&#039;header&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;django_monetize/paypal_donate.html&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&#039;footer&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;django_monetize/amazon_omakase.html&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:(&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;&#039;django_monetize/amazon_search.html&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;amazon_search_terms&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;JQuery&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;amazon_search_title&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;Buy books on JQuery!&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;MONETIZE_CONTEXT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&#039;amazon_affiliates_id&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;your affiliates tracking id&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&#039;amazon_paypage&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;default amazon paypages url&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&#039;paypal_business&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;paypal accounts email address&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&#039;paypal_item_name&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;My website&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&#039;paypal_currency_code&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;USD&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&#039;paypal_tax&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;0&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&#039;paypal_lc&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;US&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&#039;paypal_bn&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;PP-DonationsBF&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&#039;paypal_image&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;http://www.paypal.com/en_US/i/btn/btn_donate_LG.gif&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Okay. So the first thing to realize is that monetization options have three possible appearances:
&lt;/p&gt;
&lt;ol&gt;
 &lt;li&gt;&lt;p&gt;They can be a string that is the name of a template. In that case the template will be rendered using the context in &lt;code&gt;MONETIZE_CONTEXT&lt;/code&gt;.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;They can be a tuple or list whose first value is a template name, and other values are tuples/lists in the form (key,value) which are used to override the default values in &lt;code&gt;MONETIZE_CONTEXT&lt;/code&gt; when rendering that monetization option.
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;They can be a dictionary whose keys are ad slots (&lt;code&gt;header&lt;/code&gt;, &lt;code&gt;footer&lt;/code&gt;, or whatever you name them) and their values are either form #1 or form #2. There is also a magic value, &lt;code&gt;None&lt;/code&gt; which is used to specify its default value if it doesn&#039;t define its value for all slots.
&lt;/p&gt;

 &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Next, &lt;code&gt;MONETIZE_DEFAULT&lt;/code&gt; is where you establish the default monetization option, which is one of the three appearances above (string, list with string and overrides, dictionary with slot names that each have a string or list of string and overrides).
&lt;/p&gt;
&lt;p&gt;Finally, &lt;code&gt;MONETIZE_TARGET&lt;/code&gt; is a dictionary of terms to target on, where each target has one of the three monetization appearances.
&lt;/p&gt;

&lt;h3&gt;Up and At &#039;Em&lt;/h3&gt;
&lt;p&gt;Right now the &lt;a href=&quot;http://github.com/lethain/django-monetize/tree/master&quot;&gt;repository is stored at GitHub&lt;/a&gt;, which I realize isn&#039;t Google Code and thus will be problematic for some Django users. I am moving up to New Jersey this weekend, and won&#039;t have time to setup the Google Code repository until next week.
&lt;/p&gt;
&lt;p&gt;In that same vein, I haven&#039;t had the time to integrate it into this site yet, and thus it hasn&#039;t received heavy testing. Forking it on GitHub and making your changes followed by a push request would be the easiest way to contribute, but mailing patches to me at &lt;code&gt;lethain@gmail.com&lt;/code&gt; would work as well.
&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;README&lt;/code&gt; file in the repository should be helpful, but at the present time you should consider this blog entry to be a more authoritative resource until I vet &lt;code&gt;README&lt;/code&gt; for changes as I refined things (I tried practicing Documentation Driven Development, meaning that I wrote the documentation before I wrote the code, and it worked out pretty well for me, but I imagine it has introduced a few inconsistencies).
&lt;/p&gt;</description>
            
            <pubDate>Fri, 29 Aug 2008 12:55:37 -0700</pubDate>
        </item>
            
        <item>
            <title>Eric Holscher: Screencast 2: Logging in Django, for fun and profit</title>
            <link>http://swik.net/django/Django+Community+Aggregator/Eric+Holscher%3A+Screencast+2%3A+Logging+in+Django%2C+for+fun+and+profit/cc46y</link>
            <description>&lt;p&gt;&lt;strong&gt;This is the second screencast of a week long series.&lt;/strong&gt;
&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;
     Part 1: &lt;a href=&quot;http://ericholscher.com/blog/2008/aug/28/screencast-debugging-django-error-page/&quot;&gt;Using Django&#039;s Error Page&lt;/a&gt;
 &lt;/li&gt;

 &lt;li&gt;
     Part 2: Logging in Django
 &lt;/li&gt;

 &lt;li&gt;
     Part 3: Using the Debugger (teaser)
 &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So that I don&#039;t spam all of the Django Community Feed (Bad RSS handling has done that more than once, Sorry!) I&#039;m only going to be posting this post and the last post summarizing all of the screencasts on the aggregator. So if you&#039;re trying to keep up with all of the screencasts that will be coming out this week, either stay tuned to the site or subscribe to my &lt;a href=&quot;http://feeds.feedburner.com/EricsThoughts&quot;&gt;feed&lt;/a&gt;.
&lt;/p&gt;

&lt;h2&gt;Screencast 2: Logging in Django&lt;/h2&gt;

&lt;h3&gt;Setup&lt;/h3&gt;
&lt;p&gt;This screencast is going to be about how to use the python logging module in Django. It&#039;s in the Python standard library, so there is nothing extra to install to use the simple python logging module. The screencast also makes use of the excellent &lt;a href=&quot;http://code.google.com/p/django-logging/&quot;&gt;Django-Logging&lt;/a&gt;, which should be downloaded and installed beforehand.
&lt;/p&gt;
&lt;p&gt;&lt;code&gt;svn checkout http://django-logging.googlecode.com/svn/trunk/ django-logging&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;This allows for you to follow along on the second part of the screencast. I also do a little bit of work inside my &lt;a href=&quot;http://code.google.com/p/django-testmaker/&quot;&gt;django-testmaker&lt;/a&gt; app, so you can go grab that if you want to follow along as well. If not no big deal, the screencast is more about general logging anyway.
&lt;/p&gt;

&lt;h3&gt;Video and Download&lt;/h3&gt;
&lt;p&gt;The video is available to download in higher res or for streaming.
&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://ericholscher.com/media/movies/Using%20Logging%20in%20Django.mov&quot;&gt;Download&lt;/a&gt; (21MB H.264 .mov)
&lt;/p&gt;
&lt;p&gt;            &lt;br/&gt;&lt;a href=&quot;http://vimeo.com/1624166?pg=embed&amp;sec=1624166&quot;&gt;Screencast 2: Using Logging in Django&lt;/a&gt; from &lt;a href=&quot;http://vimeo.com/user627770?pg=embed&amp;sec=1624166&quot;&gt;Eric Holscher&lt;/a&gt; on &lt;a href=&quot;http://vimeo.com?pg=embed&amp;sec=1624166&quot;&gt;Vimeo&lt;/a&gt;.
&lt;/p&gt;

&lt;h3&gt;Writeup&lt;/h3&gt;

&lt;h4&gt;Part 1: python logging module&lt;/h4&gt;
&lt;p&gt;We start out with some really simple logging methods. The first is a simple &lt;code&gt;print&lt;/code&gt; statement inside of your views. This outputs the command to the terminal in your development server. The next way to do it is with a simple logging command:
&lt;/p&gt;
&lt;p&gt;&lt;code&gt;import logging
logging.error(&#039;your error goes here!&#039;)&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;During the screencast I say that logging.error goes to Standard Out, when in actuality it goes to Standard Error. In this case they&#039;re the same thing...Then I go through how logging is done within the testmaker app. This is the basic setup for python&#039;s logging module that I used:
&lt;/p&gt;
&lt;p&gt;&lt;code&gt;logging.basicConfig(level=logging.INFO,
                   format=&#039;%(message)s&#039;,
                   filename= &amp;quot;/file/to/log/to&amp;quot;,
                   filemode=&#039;w&#039;
                   )&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;More documentation about this and the python logging module is &lt;a href=&quot;http://docs.python.org/lib/module-logging.html&quot;&gt;available here&lt;/a&gt; It includes a lot of really good information about the logging module, like &lt;a href=&quot;http://docs.python.org/lib/node421.html&quot;&gt;lots of message formatting options&lt;/a&gt;. I show how you can tail a log file from testmaker and talk about the neat advanced features of the logging module like &lt;a href=&quot;http://docs.python.org/lib/network-logging.html&quot;&gt;logging across a network&lt;/a&gt;. As you can see the logging module is &lt;strong&gt;very powerful!&lt;/strong&gt;
&lt;/p&gt;

&lt;h4&gt;Part 2: django-logging&lt;/h4&gt;
&lt;p&gt;In the second part of the screencast we show how to use the Django Logging middleware. This is what is going to go into your settings_debug.py:
&lt;/p&gt;
&lt;p&gt;&lt;code&gt;from settings import *
DEBUG = True
INTERNAL_IPS = [&#039;YOUR.IP.HERE&#039;]
MIDDLEWARE_CLASSES += (&#039;djangologging.middleware.LoggingMiddleware&#039;,)
LOGGING_LOG_SQL = True&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;This then has all of your logging output appended to the bottom of the page you&#039;re currently on. This gives you a similiar capability of using the error page to debug, except you don&#039;t have to have an error. You can debug while the pages are still working. 
&lt;/p&gt;
&lt;p&gt;The next and last really neat feature is showing the SQL queries that are being executed to render a page. This is incredibly useful for fine-tuning your django sites. With the ORM, there are tiny little tweaks that you can sometimes make to decrease (or increase!) the numbers of queries you execute pretty dramatically. Having this enabled during development is a good way to catch those mistakes, and really understand what is going on under the hood of your Django apps.
&lt;/p&gt;
&lt;p&gt;Remember, when you wrap all of your logging stuff in the logging module, you can do some really neat things after the fact. I was able to use all of the django-logging stuff while still logging output to a file and whatever else happened to be going on with the logger at the time. This in incredibly powerful, and allows you to almost have django-style &#039;pluggable logging backends&#039; that do different things.
&lt;/p&gt;
&lt;p&gt;Again in this one I end a little silly: Thanks for your time and have a good day (since I&#039;l hopefully see you again tomorrow :))
&lt;/p&gt;</description>
            
            <pubDate>Fri, 29 Aug 2008 09:55:08 -0700</pubDate>
        </item>
            
        <item>
            <title>Nuno Mariz: Portuguese translation of Django 1.0</title>
            <link>http://swik.net/django/Django+Community+Aggregator/Nuno+Mariz%3A+Portuguese+translation+of+Django+1.0/cc4ou</link>
            <description>I&#039;ve just submitted a &lt;a href=&quot;http://code.djangoproject.com/ticket/8685&quot;&gt;patch&lt;/a&gt; for the Portuguese translation.&lt;br/&gt;
If you are a &lt;a href=&quot;http://www.djangoproject.com&quot;&gt;Django&lt;/a&gt; user and know Portuguese, please take a look to the translation strings and submit any fix before the &lt;a href=&quot;http://code.djangoproject.com/wiki/VersionOneRoadmap#schedule&quot;&gt;final 1.0 release&lt;/a&gt;.&lt;br/&gt;
Meanwhile, you can &lt;a href=&quot;http://mariz.org/downloads/file/4/&quot;&gt;download&lt;/a&gt; the unofficial version in the &lt;a href=&quot;http://mariz.org/downloads/&quot;&gt;downloads section&lt;/a&gt;.</description>
            
            <pubDate>Fri, 29 Aug 2008 07:55:21 -0700</pubDate>
        </item>
            
        <item>
            <title>Alberto García Hierro: Postback: Why I choose AGPLv3 for my code</title>
            <link>http://swik.net/django/Django+Community+Aggregator/Alberto+Garc%C3%ADa+Hierro%3A+Postback%3A+Why+I+choose+AGPLv3+for+my+code/cc3oz</link>
            <description>&lt;p&gt;It&#039;s been a few days since I posted my decision to release all my code related to Django under the AGPLv3 license. It generated quite a few reactions I didn&#039;t expect, so let me tell you the full story.
&lt;/p&gt;
&lt;p&gt;It all started when I needed to support, let&#039;s call it &lt;em&gt;technology X&lt;/em&gt; - which is pretty hot right now -, in &lt;a href=&quot;http://bynotes.com&quot;&gt;byNotes&lt;/a&gt;. I first searched if someone had done it and I found there was a generic and abstract Python implementation, but it needed a lot of work to be adapted to Django. So I decided to build my own solution from scratch. The same day I released the first version, I found an announcement posted the previous day from another developer who had also coded technology X support for Django. It&#039;s a pity when that happens, since one of us could have spent that time implementing technology Y. However, it&#039;s difficult to avoid those situations, so we must live with it.
&lt;/p&gt;
&lt;p&gt;The bad thing (TM) happened a few days later, when I was chatting with a friend on freenode. I told him I&#039;ve written support for technology X and it could be useful for a project he&#039;s working on. He told me about a relatively popular site - I didn&#039;t know it was built on Django - which had been supporting technology X for a few months. I checked the site and I found nothing about the source code for technology X, even when it&#039;s something potentially useful for a lot of sites.
&lt;/p&gt;
&lt;p&gt;I don&#039;t blame them for not releasing their technology X implementation, after all they&#039;re free to do what they want with their code as long as they respect the licenses for other projects or frameworks they may rely on. However, the Django community lost something in this scenario. If &lt;em&gt;relatively popular site&lt;/em&gt; had released their implementation of technology X, the other developer would have worked on Y while I would have worked on Z. Django would now have support for X, Y and Z, but thanks to the decision of &lt;em&gt;relatively popular site&lt;/em&gt; to keep their implementation of X closed, we now have 2 free implementations of X. And that hurts the community, since now someone will have to spend time working on Y and Z instead of doing another things.
&lt;/p&gt;
&lt;p&gt;Are you starting to see my point? Now, with my code released under AGPLv3 instead of BSD, any site using it would have to contribute their changes back. So, if they improve my implementation of technology X, I can spend more time working on technology Y and that benefits the Django community.
&lt;/p&gt;
&lt;p&gt;I fail to see how this is being greedy. And if, as someone suggested, my code is so trivial, there&#039;s no problem reimplementing it. Anyway, I didn&#039;t claim my code does something extraordinary. In fact, I&#039;m sure anyone could implement it. When I release something I&#039;ve written, my intention is not rocking your world, but saving you from wasting time. If I&#039;ve already written support for X, you&#039;re better working on Y instead of reinventing the wheel.
&lt;/p&gt;
&lt;p&gt;However, I&#039;m not totally happy with the AGPLv3, because of its viral nature. I would be fine with something like the LGPL but with the Affero clause and I&#039;m sure I&#039;m not alone. Id est, you may link closed source code with my software, but you must release any modifications you make to my code. However, there&#039;s no such license for now, so I have to use AGPLv3. Do you want this to change? Spread the word, I&#039;m sure a new license by the FSF combining the LGPL with the Affero clause it&#039;s going to benefit us all.
&lt;/p&gt;</description>
            
            <pubDate>Fri, 29 Aug 2008 02:55:58 -0700</pubDate>
        </item>
            
        <item>
            <title>Two-Faced Django Part 5: JQuery Ajax @ Irrational Exuberance</title>
            <link>http://swik.net/json/del.icio.us%2Ftag%2Fjson/Two-Faced+Django+Part+5%3A+JQuery+Ajax+%40+Irrational+Exuberance/cc3mg</link>
            <description></description>
            
            <pubDate>Fri, 29 Aug 2008 02:05:45 -0700</pubDate>
        </item>
            
        <item>
            <title>Alberto García Hierro: Wapi 0.2 released</title>
            <link>http://swik.net/django/Django+Community+Aggregator/Alberto+Garc%C3%ADa+Hierro%3A+Wapi+0.2+released/cc3hu</link>
            <description>&lt;p&gt;I&#039;ve just finished preparing the Wapi code for the 0.2 release, so you can now &lt;a href=&quot;http://abra.rm-fr.net/~fiam/code/wapi-0.2.zip&quot;&gt;download it&lt;/a&gt;. oauthsp will be ready in a few days (probably this weekend).
&lt;/p&gt;</description>
            
            <pubDate>Fri, 29 Aug 2008 01:59:57 -0700</pubDate>
        </item>
            
        <item>
            <title>Eric Holscher: Screencast: Debugging with the Django Error Page</title>
            <link>http://swik.net/django/Django+Community+Aggregator/Eric+Holscher%3A+Screencast%3A+Debugging+with+the+Django+Error+Page/cc2bo</link>
            <description>Screencast: Debugging with the Django Error Page</description>
            
            <pubDate>Thu, 28 Aug 2008 18:55:07 -0700</pubDate>
        </item>
            
        <item>
            <title>... Django on Jython on GlassFish, JavaFX performance</title>
            <link>http://swik.net/GlassFish/The+Aquarium/...+Django+on+Jython+on+GlassFish%2C+JavaFX+performance/cc0xs</link>
            <description>&lt;p&gt;
A compilation of today&#039;s news of interest: 
&lt;/p&gt;
&lt;table&gt;&lt;tr&gt;&lt;td valign=&quot;top&quot;&gt;
&lt;p&gt;
&lt;a href=&quot;http://glassfish.org&quot; title=&quot;GlassFish&quot;&gt;
&lt;img src=&quot;http://blogs.sun.com/theaquarium/resource/RadioReceiver-89_99px.png&quot; alt=&quot;Radio Receiver Icon&quot; width=&quot;89&quot; height=&quot;99&quot;/&gt;
&lt;/a&gt;
&lt;/p&gt;
&lt;/td&gt;
&lt;td valign=&quot;top&quot;&gt;
&lt;p&gt;
From &lt;strong&gt;Chris&lt;/strong&gt;
a report on the performance improvements of
&lt;a href=&quot;http://www.sun.com/software/javafx/&quot;&gt;JavaFX&lt;/a&gt;:
where
&lt;a href=&quot;http://blogs.sun.com/chrisoliver/entry/javafx_vs_actionscript_performance&quot;&gt;JavaFX is close to Java&lt;/a&gt; in performance.
Big improvements since this
&lt;a href=&quot;http://blogs.sun.com/chrisoliver/entry/hotspot_vs_adobe_tamarin_vm&quot;&gt;Earlier Post&lt;/a&gt;.
I know the JavaFX compiler team (Robert, Per, Brian) and they are all top notch.
&lt;/p&gt;

&lt;p&gt;
From &lt;strong&gt;Leo Soto&lt;/strong&gt;,
the Django Framework now runs on 
&lt;a href=&quot;http://www.jython.org/Project/&quot;&gt;Jython&lt;/a&gt;.
See
&lt;a href=&quot;http://blog.leosoto.com/2008/08/django-on-jython-its-here.html&quot;&gt;Leo&#039;s blog entry&lt;/a&gt;
and the
&lt;a href=&quot;http://wiki.python.org/jython/DjangoOnJython&quot;&gt;Wiki page&lt;/a&gt; for details...
and
&lt;a href=&quot;http://blog.leosoto.com/2008/08/deploying-djangojython-projects-on-j2ee.html&quot;&gt;How to Run it on GlassFish&lt;/a&gt;.
One more scripting language and framework!
Jython is moving much faster than I had anticipated;
Frank is already
&lt;a href=&quot;http://fwierzbicki.blogspot.com/2008/08/jythons-trunk-now-targets-25.html&quot;&gt;Working on Jython 2.5&lt;/a&gt;.
&lt;/p&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;

</description>
            
            <pubDate>Thu, 28 Aug 2008 18:08:13 -0700</pubDate>
        </item>
            
        <item>
            <title>Simon Willison: Django 1.0 release party</title>
            <link>http://swik.net/django/Django+Community+Aggregator/Simon+Willison%3A+Django+1.0+release+party/cczy8</link>
            <description>&lt;div class=&quot;blogmark segment&quot;&gt;&lt;p&gt;&lt;a href=&quot;http://www.djangoproject.com/weblog/2008/aug/26/party/&quot;&gt;Django 1.0 release party&lt;/a&gt;. The big ass-party will be at the Tied House in Mountain View on Saturday the 6th from 7pm. RSVP on the linked announcement.&lt;/p&gt;
&lt;/div&gt;</description>
            
            <pubDate>Thu, 28 Aug 2008 18:03:14 -0700</pubDate>
        </item>
            
        <item>
            <title>Simon Willison: Django 1.0 beta 2 released!</title>
            <link>http://swik.net/django/Django+Community+Aggregator/Simon+Willison%3A+Django+1.0+beta+2+released%21/cczy7</link>
            <description>&lt;div class=&quot;blogmark segment&quot;&gt;&lt;p&gt;&lt;a href=&quot;http://www.djangoproject.com/weblog/2008/aug/27/10-beta-2/&quot;&gt;Django 1.0 beta 2 released!&lt;/a&gt;. 1.0 draws ever closer. Important new features include major documentation and comment system refactorings, plus the removal of a bunch of deprecated code (including oldforms). Feature and string freezes are now in place, so it’s just bugs and documentation improvements between now and the final release.&lt;/p&gt;
&lt;/div&gt;</description>
            
            <pubDate>Thu, 28 Aug 2008 18:03:14 -0700</pubDate>
        </item>
            
        <item>
            <title>Alberto García Hierro: Building a website API with Django. Part 6: Documentation</title>
            <link>http://swik.net/django/Django+Community+Aggregator/Alberto+Garc%C3%ADa+Hierro%3A+Building+a+website+API+with+Django.+Part+6%3A+Documentation/cczy6</link>
            <description>&lt;p&gt;This entry puts and end to &quot;Building a website API with Django&quot;. I think I&#039;ve covered everything you need to build a website API with Wapi, so it&#039;s now time for you to start playing with it. I hope you&#039;ve enjoyed reading this series as much as I enjoyed writing it. I&#039;ve finally pylinted and documented almost all the code, so Wapi 0.2 should be released in the next few hours.  From now, I&#039;ll try to keep the current API and every backwards incompatible change will be documented.
&lt;/p&gt;

&lt;h2&gt;Documenting your API with Wapi&lt;/h2&gt;

&lt;h3&gt;Documenting your functions&lt;/h3&gt;
&lt;p&gt;As we&#039;ve seen on &lt;a href=&quot;http://fi.am/entry/building-a-website-api-with-django-part-4-complex-/&quot;&gt;part 4 on this series&lt;/a&gt;, every API parameter takes an optional third argument which documents it. In addition, every function docstring is also passed to the documentation template. Furthermore, validators applied to parameters are also autodocumented. Let&#039;s see an example:
&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nd&quot;&gt;@readonly&lt;/span&gt;
&lt;span class=&quot;nd&quot;&gt;@required_parameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;type&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;Admin division type, ranging from 1 to 4.&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;validators&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RangeValidator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;min_value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;max_value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;nd&quot;&gt;@required_parameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;id&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;The administrative division id.&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;geo__admin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Returns information for the given administrative division type and id. Keep&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    in mind that administrative divisions identificators are not guaranteed to&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    be permanent, as it happens with geoname identifiers.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you want to check how it looks when passed to the documentation, check the &lt;a href=&quot;http://bynotes.com/api/1.0/doc/#geo__admin&quot;&gt;byNotes API documentation&lt;/a&gt;.
&lt;/p&gt;

&lt;h3&gt;urls.py&lt;/h3&gt;
&lt;p&gt;You&#039;ll also need to plug your documentation view into your urls.py, but it&#039;s pretty simple:
&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;wapi.documentator&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ApiDocumentator&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;notes.api&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BynotesApi&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;urlpatterns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;r&#039;^api/1.0/doc/&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ApiDocumentator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;api&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BynotesApi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Grouping functions into namespaces&lt;/h3&gt;
&lt;p&gt;By default, Wapi orders your functions alphabetically. However, usually you&#039;ll want to reorder this namespaces and given them friendly names. In Wapi, you can do this using the NAMESPACES class attribute in your API class:
&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BynotesApi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;NAMESPACES&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; 
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;User information&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&#039;user&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;Positions&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&#039;position&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;Fetching notes&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&#039;notes&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;Friends&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&#039;friends&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;Posting notes&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&#039;post&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;Geographic functions&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&#039;geo&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The format of the tuples is (namespace_friendly_name, namespace_prefix).
&lt;/p&gt;

&lt;h3&gt;Example template&lt;/h3&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span class=&quot;x&quot;&gt;     &lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;namespaces&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;    &amp;lt;div class=&amp;quot;api-ns&amp;quot; id=&amp;quot;ns-&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{{&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;namespace.short_name&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;}}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&amp;quot;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;        &amp;lt;h2&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{{&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;namespace.name&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;}}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&amp;lt;/h2&amp;gt;&amp;lt;ol&amp;gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;        &amp;lt;li id=&amp;quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{{&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;function.name&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;}}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&amp;quot; class=&amp;quot;function&amp;quot;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;            &amp;lt;h3&amp;gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                &lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{{&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;function.endpoint&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;}}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;.{ format }&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                &lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;function.requires_login&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                    &amp;lt;span class=&amp;quot;warn&amp;quot;&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;trans&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Requires login&amp;quot;&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                &lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;endif&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;            &amp;lt;/h3&amp;gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;            &amp;lt;span&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;trans&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;allowed methods&amp;quot;&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;:&amp;lt;/span&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;function.is_read&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt; GET&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;endif&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;function.is_write&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt; POST&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;endif&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;            &amp;lt;p class=&amp;quot;fdoc&amp;quot;&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{{&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;function.doc&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;}}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;function.required_parameters&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                &amp;lt;h4&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;trans&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Required parameters&amp;quot;&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;:&amp;lt;/h4&amp;gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                &lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;parameter&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;function.required_parameters&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                    &amp;lt;p class=&amp;quot;parameter&amp;quot;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                        &amp;lt;span&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{{&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;parameter.name&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;}}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{{&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;parameter.type_name&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;}}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;):&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                        &lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{{&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;parameter.doc&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;}}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                    &amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                    &lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;parameter.doc_info&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                        &lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;parameter.doc_info&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                            &amp;lt;p class=&amp;quot;parameter-info&amp;quot;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                                &amp;lt;span&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{{&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;}}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;:&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                                &lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{{&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;}}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                            &amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                        &lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;endfor&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                    &lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;endif&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                &lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;endfor&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;endif&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;function.optional_parameters&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                &amp;lt;h4&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;trans&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Optional parameters&amp;quot;&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;:&amp;lt;/h4&amp;gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                &lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;parameter&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;function.optional_parameters&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                    &amp;lt;p class=&amp;quot;parameter&amp;quot;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                        &amp;lt;span&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{{&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;parameter.name&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;}}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt; (&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{{&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;parameter.type_name&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;}}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;):&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                        &lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{{&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;parameter.doc&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;}}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                    &amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                    &lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;parameter.has_default&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                        &amp;lt;p class=&amp;quot;parameter-info&amp;quot;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                            &amp;lt;span&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;trans&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Default&amp;quot;&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;:&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                            &lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{{&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;parameter.default&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;}}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                        &amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                    &lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;endif&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                    &lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;parameter.doc_info&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                        &lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;parameter.doc_info&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                            &amp;lt;p class=&amp;quot;parameter-info&amp;quot;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                                    &amp;lt;span&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{{&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;}}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;:&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                                &lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{{&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;}}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                            &amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                        &lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;endfor&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                    &lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;endif&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;                &lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;endfor&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;            &lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;endif&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;        &amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;endfor&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;        &amp;lt;/ol&amp;gt;&lt;/span&gt;
&lt;span class=&quot;x&quot;&gt;    &amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;{%&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;endfor&lt;/span&gt; &lt;span class=&quot;cp&quot;&gt;%}&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Current limitations&lt;/h3&gt;
&lt;p&gt;As you may have noticed, translating function documentation is currently not supported in Wapi, since the docstring must be a bare string. Some work has been done on this, but the current solution requires modifications to &lt;em&gt;makemessages&lt;/em&gt;, so I think it was better to leave this changes for Wapi 0.3, which will be released post Django 1.0.
&lt;/p&gt;</description>
            
            <pubDate>Thu, 28 Aug 2008 18:03:14 -0700</pubDate>
        </item>
            
        <item>
            <title>Simon Willison: Django snippets: Sign a string using SHA1, then shrink it using url-safe base65</title>
            <link>http://swik.net/django/Django+Community+Aggregator/Simon+Willison%3A+Django+snippets%3A+Sign+a+string+using+SHA1%2C+then+shrink+it+using+url-safe+base65/cczy5</link>
            <description>&lt;div class=&quot;blogmark segment&quot;&gt;&lt;p&gt;&lt;a href=&quot;http://www.djangosnippets.org/snippets/1004/&quot;&gt;Django snippets: Sign a string using SHA1, then shrink it using url-safe base65&lt;/a&gt;. I needed a way to create tamper-proof URLs and cookies by signing them, but didn’t want the overhead of a full 40 character SHA1 hash. After some experimentation, it turns out you can knock a 40 char hash down to 27 characters by encoding it using a custom base65 encoding which only uses URL-safe characters.&lt;/p&gt;
&lt;/div&gt;</description>
            
            <pubDate>Thu, 28 Aug 2008 18:03:14 -0700</pubDate>
        </item>
            
        <item>
            <title>Alberto García Hierro: AGPLv3 explained</title>
            <link>http://swik.net/django/Django+Community+Aggregator/Alberto+Garc%C3%ADa+Hierro%3A+AGPLv3+explained/cczy4</link>
            <description>&lt;p&gt;I think there are lots of people which misunterstand the &lt;a href=&quot;http://www.fsf.org/licensing/licenses/agpl-3.0.html&quot;&gt;Affero GPL v3&lt;/a&gt;, so I decided to write this entry to clarify some things.
&lt;/p&gt;
&lt;p&gt;Keep in mind I&#039;m not a lawyer, so you should read my advice with a grain of salt. I&#039;ve been using free software licenses for some years and I always take the time to read and understand them, but that doesn&#039;t mean I cannot make mistakes or misunderstand some sections.
&lt;/p&gt;

&lt;h2&gt;You can&lt;/h2&gt;
&amp;nbsp;

&lt;ul&gt;
 &lt;li&gt;
     &lt;strong&gt;Sell commercial software under an AGPLv3 license&lt;/strong&gt;: Nobody prevents you from selling AGPLv3 licensed code, even when you didn&#039;t write it. However, customers buying the software  from you must abide by the license terms. Paying for an AGPLv3 product doesn&#039;t mean you can avoid the license terms. However, if you&#039;re the copyright owner, you can sell the same software under a different license.
 &lt;/li&gt;

 &lt;li&gt;
     &lt;strong&gt;Build another software on top of it&lt;/strong&gt;: AGPLv3 grants you permission to download and modify any software which you can use, even if it&#039;s over a network (this an importante difference with the GPLv3). You&#039;re free to modify it or use it into another project, making your project a derivative work of the original software.
 &lt;/li&gt;

 &lt;li&gt;
     &lt;strong&gt;Link to or use BSD licensed code&lt;/strong&gt;: 3-clause BSD licensed code (don&#039;t confuse it with 4-clause BSD license) let&#039;s you use or import it into AGPLv3 projects. You can also distribute both codebases as a single package. However, keep in mind that you are not allowed to change the license in the file headers nor claim copyright over the external project you imported.
 &lt;/li&gt;

 &lt;li&gt;
     &lt;strong&gt;Look at code under AGPLv3 license, even when you work on projects with more restrictive licenses&lt;/strong&gt;: AGPLv3  is about code freedom, not about patents nor algorithms. You&#039;re free to look at AGPLv3 code and then do a clean-room reimplementation of it.
 &lt;/li&gt;

 &lt;li&gt;
     &lt;strong&gt;Use GPLv3 libraries&lt;/strong&gt;: Using a GPLv3 library doesn&#039;t impose additional restrictions over the library nor over the AGPLv3 code, so there&#039;s no problem here.
 &lt;/li&gt;

 &lt;li&gt;
     &lt;strong&gt;Use LGPLvx libraries&lt;/strong&gt;: No version of the LGPL imposes any restrictions over the code using it. 
 &lt;/li&gt;
&lt;/ul&gt;
&amp;nbsp;


&lt;h2&gt;You can&#039;t&lt;/h2&gt;
&amp;nbsp;

&lt;ul&gt;
 &lt;li&gt;
     &lt;strong&gt;Write BSD or closed source software on top of it&lt;/strong&gt;: AGPLv3 is designed to keep the code always free, so you can&#039;t use nor import AGPLv3 code into a closed source project.
 &lt;/li&gt;

 &lt;li&gt;
     &lt;strong&gt;Copy AGPLv3 code into another project under a non-AGPLv3 license&lt;/strong&gt;: Even a single line. It&#039;s no allowed, because you&#039;re bypassing the license term under the code was released.
 &lt;/li&gt;

 &lt;li&gt;
     &lt;strong&gt;Mix GPLv3 and AGPLv3 code&lt;/strong&gt;: This may seem counterintuitive, but it&#039;s true. You can&#039;t make a GPLv3 derivate work and an AGPLv3 software, since you&#039;re removing the obligation to distribute the source to users over a network. On the other hand, you can&#039;t add the Affero clause to a GPLv3 codebase, since you&#039;re imposing additional restrictions on it. The same applies for GPLv2.
 &lt;/li&gt;

 &lt;li&gt;
     &lt;strong&gt;Use GPLv2 libraries&lt;/strong&gt;: GPLv2 only libraries don&#039;t allow you to use them in GPLv3 projects, so you&#039;re in the same case when using AGPLv3.
 &lt;/li&gt;
&lt;/ul&gt;
&amp;nbsp;


&lt;h2&gt;You must&lt;/h2&gt;
&amp;nbsp;

&lt;ul&gt;
 &lt;li&gt;
     &lt;strong&gt;License your derivative works under AGPLv3&lt;/strong&gt;: If you modify AGPLv3 code or use it in another project, the resulting code must be under an AGPLv3 license.
 &lt;/li&gt;

 &lt;li&gt;
     &lt;strong&gt;Provide a way to download the code over the same medium used to deliver the software service to the user&lt;/strong&gt;: If you run a website which uses AGPLv3 code, your pages must provide a link to the software you&#039;re running in the webserver (zipfile or version control system, it doesn&#039;t matter).
 &lt;/li&gt;
&lt;/ul&gt;
&amp;nbsp;


&lt;h3&gt;For Django developers&lt;/h3&gt;
&lt;p&gt;Django is released under a 3-clause BSD license, so you&#039;re free to build AGPLv3 software on top of it.
&lt;/p&gt;</description>
            
            <pubDate>Thu, 28 Aug 2008 18:03:14 -0700</pubDate>
        </item>
            
        <item>
            <title>Alberto García Hierro: URLsafe base64 encoding/decoding in two lines</title>
            <link>http://swik.net/django/Django+Community+Aggregator/Alberto+Garc%C3%ADa+Hierro%3A+URLsafe+base64+encoding%2Fdecoding+in+two+lines/cczy3</link>
            <description>&lt;p&gt;Simon has recently &lt;a href=&quot;http://simonwillison.net/2008/Aug/27/snippets/&quot;&gt;featured&lt;/a&gt; this &lt;a href=&quot;http://www.djangosnippets.org/snippets/1004/&quot;&gt;snippet&lt;/a&gt; which shrinks a SHA1 hash from 40 to 27 characters using base65 encoding. I&#039;ve been using another approach for some time and, modestly, I think mine is better, so let me tell you how I do it before you start using the suboptimal approach.
&lt;/p&gt;

&lt;h3&gt;Python does it for us&lt;/h3&gt;
&lt;p&gt;First, the &lt;em&gt;base64&lt;/em&gt; module already provides a pair of functions, aptly named &lt;em&gt;urlsafe_b64encode&lt;/em&gt; and &lt;em&gt;urlsafe_b64decode&lt;/em&gt;, which do quasi-safe url encoding using base64. For example:
&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;base64&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;urlsafe_b64encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sha1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;foobar&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;digest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&#039;iEPX-SQWIR3p67lj_0zigSWTKHg=&#039;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The problem here is the equal sign, since we can&#039;t put it safely in a URL. However, since we are using this to store a hash and we&#039;re going to generate the hash again when we verify the data, we can encode the hash again instead of decoding the base64-encoded string, which lets us safely remove the equal sign. Furthermore, we are also using 27 characters, the same as the other more complex implementation.
&lt;/p&gt;

&lt;h3&gt;Can we decode it? Sure!&lt;/h3&gt;
&lt;p&gt;Sometimes, you&#039;ll want to decode the base64 encoded data. However, once we remove the equal sign, we can&#039;t no longer pass the base64 encoded string to &lt;em&gt;urlsafe_b64decode&lt;/em&gt;:
&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;base64&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;urlsafe_b64decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;iEPX-SQWIR3p67lj_0zigSWTKHg&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Traceback&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;most&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;recent&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;call&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;File&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;File&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;/usr/lib/python2.5/base64.py&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;112&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;urlsafe_b64decode&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b64decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&#039;-_&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;File&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;/usr/lib/python2.5/base64.py&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;76&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b64decode&lt;/span&gt;
     &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;TypeError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
 &lt;span class=&quot;ne&quot;&gt;TypeError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Incorrect&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;padding&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let&#039;s examine how base64 works. The input string is processed in 3-byte blocks which are split into 6-bits pieces. Hence, we have 2^6 == 64 possible values per piece which translates to a single character into our base64 alphabet. So, every three byte block is translated to a 4 characters string. When the last block has less than three bytes, it&#039;s padded with zeros and one equal sign is added for every padding byte. This leads us to the conclusion that base64 encoded strings always have a length divisible by four. Let&#039;s take advantage of this:
&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&#039;iEPX-SQWIR3p67lj_0zigSWTKHg&#039;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;base64&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;urlsafe_b64decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&#039;=&#039;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&#039;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x88&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\xd7\xf9&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x16&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x1d\xe9\xeb\xb9&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\xff&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;L&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\xe2\x81&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x93&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;(x&#039;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So now we have our original string back.
&lt;/p&gt;

&lt;h3&gt;Putting it all together&lt;/h3&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;base64&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;urlsafe_b64encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;urlsafe_b64decode&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;uri_b64encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
     &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;urlsafe_b64encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;=&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;uri_b64decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
     &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;urlsafe_b64decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&#039;=&#039;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;</description>
            
            <pubDate>Thu, 28 Aug 2008 18:03:14 -0700</pubDate>
        </item>
            
        <item>
            <title>Peter Baumgartner: Managing Django Projects on Your Server with Style</title>
            <link>http://swik.net/django/Django+Community+Aggregator/Peter+Baumgartner%3A+Managing+Django+Projects+on+Your+Server+with+Style/cczy2</link>
            <description>My preferred directory structure and third party repo management for hosting multiple projects (running multiple versions of Django) on a single server.</description>
            
            <pubDate>Thu, 28 Aug 2008 18:03:14 -0700</pubDate>
        </item>
            
        <item>
            <title>Simon Willison: Using Akismet with Django&#039;s new comments framework</title>
            <link>http://swik.net/django/Django+Community+Aggregator/Simon+Willison%3A+Using+Akismet+with+Django%27s+new+comments+framework/cczy1</link>
            <description>&lt;div class=&quot;blogmark segment&quot;&gt;&lt;p&gt;&lt;a href=&quot;http://sciyoshi.com/blog/2008/aug/27/using-akismet-djangos-new-comments-framework/&quot;&gt;Using Akismet with Django’s new comments framework&lt;/a&gt;. A nice example that demonstrates two features that were recently rolled in to the Django 1.0 betas: the new signals library and the new comments framework.&lt;/p&gt;
&lt;/div&gt;</description>
            
            <pubDate>Thu, 28 Aug 2008 18:03:13 -0700</pubDate>
        </item>
            
        <item>
            <title>Ivan Sagalaev: Празднование релиза Django 1.0</title>
            <link>http://swik.net/django/Django+Community+Aggregator/Ivan+Sagalaev%3A+%D0%9F%D1%80%D0%B0%D0%B7%D0%B4%D0%BD%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5+%D1%80%D0%B5%D0%BB%D0%B8%D0%B7%D0%B0+Django+1.0/cczy0</link>
            <description>Куда все идутЯ приглашаю:07.09.2008 15:00, PodМосковье, М.Кисловский пер., 6Празднование релиза Django 1.0Есть идея отпраздновать вместе с остальным миром долгожданный релиз Django 1.0!

Приглашаются все, кому это интересно. Познакомимся (кто не знаком), пообщаемся, расскажем друг о друге, сделаем фотки и пожелаем доброго пути любимому фреймворку. Программировать не будем :-)

В качестве места сбора предлагается клуб &amp;#8220;PodМосковье&amp;#8221;. Говорят, [...]</description>
            
            <pubDate>Thu, 28 Aug 2008 18:03:13 -0700</pubDate>
        </item>
            
        <item>
            <title>Simon Willison: Capital Radio (the new site)</title>
            <link>http://swik.net/django/Django+Community+Aggregator/Simon+Willison%3A+Capital+Radio+%28the+new+site%29/cczyz</link>
            <description>&lt;div class=&quot;blogmark segment&quot;&gt;&lt;p&gt;&lt;a href=&quot;http://www.capitalradio.co.uk/&quot;&gt;Capital Radio (the new site)&lt;/a&gt;. Launched today, this is the Django-powered project I’ve been working on with the fantastic team at GCap.&lt;/p&gt;
&lt;/div&gt;</description>
            
            <pubDate>Thu, 28 Aug 2008 18:03:13 -0700</pubDate>
        </item>
            
        <item>
            <title>Django 1.0 release party</title>
            <link>http://swik.net/django/The+Django+weblog/Django+1.0+release+party/cczix</link>
            <description>&lt;p&gt;Come help us celebrate the release of Django&amp;nbsp;1.0!&lt;/p&gt;

&lt;p&gt;Next week is going to be huge. We&amp;#8217;ll be releasing Django 1.0 early in the week, and then the first &lt;a href=&quot;http://djangocon.org/&quot;&gt;DjangoCon&lt;/a&gt; kicks next Friday.&lt;/p&gt;

&lt;p&gt;To celebrate the release of Django 1.0, we&amp;#8217;ll be holding a dinner party at the &lt;a href=&quot;http://tiedhouse.com/&quot;&gt;Tied House&lt;/a&gt; in Mountain View on &lt;strong&gt;Saturday, September 6th at 7pm&lt;/strong&gt;. The date and time are designed to tie in with DjangoCon, but &lt;strong&gt;anyone is invited&lt;/strong&gt; &amp;#8212; especially those who can&amp;#8217;t attend DjangoCon.&lt;/p&gt;

&lt;p&gt;We&amp;#8217;ve reserved the whole restaurant for Django friends and fans. Dinner starts at 7pm, and the festivities should continue until about 10:30 or so. The party&amp;#8217;s &lt;strong&gt;free&lt;/strong&gt;, though the dinner and drinks aren&amp;#8217;t. Tied House has &lt;a href=&quot;http://www.tiedhouse.com/dinner-menu&quot;&gt;good food&lt;/a&gt; and &lt;a href=&quot;http://www.tiedhouse.com/beers&quot;&gt;great beer&lt;/a&gt;; come hungry!&lt;/p&gt;

&lt;p&gt;To make the night extra fun, we&amp;#8217;ll be holding &amp;#8220;lightning talks&amp;#8221; at the party &amp;#8212; five minute presentations on various Django-related topics. We&amp;#8217;ll be asking speakers at the conference to present vastly twimmed-down versions of their conference talks, and we&amp;#8217;ll be opening the floor up to anyone to present their own cool shit.&lt;/p&gt;

&lt;p&gt;Tied House is located in downtown Mountain View (&lt;a href=&quot;http://bit.ly/tied-house-map&quot;&gt;map&lt;/a&gt;). For DjangoCon attendees, that&amp;#8217;s about 15 minutes away from the conference venue; we&amp;#8217;ll caravan over (and provide transportation for folks without cars) right after the day&amp;#8217;s talks end. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you&amp;#8217;ll be coming, &lt;a href=&quot;http://spreadsheets.google.com/viewform?key=pSqnCvef6OXm50myizj38Ug&quot;&gt;please RSVP&lt;/a&gt; so that we can get an accurate headcount.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We&amp;#8217;re also looking for sponsors for the party, so if you&amp;#8217;re interested please &lt;a href=&quot;http://www.djangoproject.com/contact/foundation/&quot;&gt;contact us&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We hope to see you all there!&lt;/p&gt;
</description>
            
            <pubDate>Thu, 28 Aug 2008 17:59:59 -0700</pubDate>
        </item>
            
        <item>
            <title>Django 1.0 beta 2 released!</title>
            <link>http://swik.net/django/The+Django+weblog/Django+1.0+beta+2+released%21/ccziw</link>
            <description>&lt;p&gt;In accordance with &lt;a href=&quot;http://code.djangoproject.com/wiki/VersionOneRoadmap#schedule&quot;&gt;the (updated) Django 1.0 release roadmap&lt;/a&gt;, today we&#039;ve released the second &quot;beta&quot; testing version of Django 1.0.&lt;/p&gt;

&lt;p&gt;To grab a copy of 1.0 beta 2, head over to &lt;a href=&quot;http://www.djangoproject.com/download/&quot;&gt;the Django downloads page&lt;/a&gt;, and be sure to read &lt;a href=&quot;http://docs.djangoproject.com/en/dev/releases/1.0-beta-2/&quot;&gt;the release notes&lt;/a&gt;. Please keep in mind, though, that this release &lt;b&gt;is not meant for production use&lt;/b&gt;, and is intended primarily for developers who are interested in checking out the new features in 1.0 and helping to identify and resolve bugs prior to the final release. The 1.0 alpha and beta releases will not receive long-term support and will not be updated with security fixes, since their main purpose is to serve as a stepping-stone on the path to the final Django 1.0, due to be released on September 2, 2008.&lt;/p&gt;

&lt;p&gt;As of this release, Django is officially in a feature freeze for 1.0; from here on out, we&#039;ll only be working on bugs and stability before the final 1.0 release. If you&#039;d like to help out, please review &lt;a href=&quot;http://www.djangoproject.com/documentation/contributing/&quot;&gt;our documentation for contributors&lt;/a&gt; and feel free to join in one of the development sprints scheduled for the run up to 1.0.&lt;/p&gt;
</description>
            
            <pubDate>Thu, 28 Aug 2008 17:59:59 -0700</pubDate>
        </item>
            
        <item>
            <title>JSON &quot; Blog Archives &quot; Standardizing RESTful JSON</title>
            <link>http://swik.net/json/del.icio.us%2Ftag%2Fjson/JSON+%22+Blog+Archives+%22+Standardizing+RESTful+JSON/ccykh</link>
            <description>At work, I&amp;#039;ve been putting together a Django layer I&amp;#039;m calling Djata that provides a RESTful interface with multiple, extensible parsers and formatters…that you can plug into your urls.py in one line and optionally write an api module to configure and extend each of your data views.  I can easily conform to this JSON spec and largely already do with many more features (ranges, indexing, pagination, predicates, authentication, field selection, map and table JSON).  I have permission to publish it and my driving application &amp;quot;Bugwar&amp;quot; (yet another test result database), so Ryan&amp;#039;s been working on setting up an open source project server.</description>
            
            <pubDate>Tue, 19 Aug 2008 20:09:31 -0700</pubDate>
        </item>
            
        <item>
            <title>Pydev adventures: Configuring pydev to work with django</title>
            <link>http://swik.net/Eclipse/del.icio.us%2Ftag%2Feclipse/Pydev+adventures%3A+Configuring+pydev+to+work+with+django/ccycy</link>
            <description></description>
            
            <pubDate>Tue, 19 Aug 2008 19:05:50 -0700</pubDate>
        </item>
            
        <item>
            <title>minidetector</title>
            <link>http://swik.net/iphone/deli.cio.us%2Ftags%2Fiphone/minidetector/ccxrs</link>
            <description>Sign in with  OpenID
Simon Willison’s Weblog
minidetector. Neat piece of Django middleware that adds a “mobile = True” attribute to the request object if the request’s user-agent matches a list of strings of known low-power browsers in mobiles, PDAs or ga</description>
            
            <pubDate>Tue, 19 Aug 2008 14:57:06 -0700</pubDate>
        </item>
            
        <item>
            <title>Using Eclipse and PyDev for django | magpiebrain</title>
            <link>http://swik.net/Eclipse/del.icio.us%2Ftag%2Feclipse/Using+Eclipse+and+PyDev+for+django+%7C+magpiebrain/ccxnz</link>
            <description></description>
            
            <pubDate>Tue, 19 Aug 2008 14:53:34 -0700</pubDate>
        </item>
            
        <item>
            <title>Pydev adventures: Configuring pydev to work with django</title>
            <link>http://swik.net/Eclipse/del.icio.us%2Ftag%2Feclipse/Pydev+adventures%3A+Configuring+pydev+to+work+with+django/ccxny</link>
            <description></description>
            
            <pubDate>Tue, 19 Aug 2008 14:53:34 -0700</pubDate>
        </item>
            
        <item>
            <title>Alberto García Hierro: Building a website API with Django. Part 4: Complex functions</title>
            <link>http://swik.net/django/Django+Community+Aggregator/Alberto+Garc%C3%ADa+Hierro%3A+Building+a+website+API+with+Django.+Part+4%3A+Complex+functions/ccv08</link>
            <description>&lt;p&gt;We&#039;ve talked about how the &lt;a href=&quot;http://fi.am/entry/building-a-website-api-with-django-part-1-api-func/&quot;&gt;API functions are defined&lt;/a&gt; in WAPI, but we&#039;ve only scratched the surface. This entry will go on details about function namespacing, optional parameters, parameter sets, parameter validation and allowed request methods, showing some real examples from the code I wrote for &lt;a href=&quot;http://bynotes.com&quot;&gt;byNotes&lt;/a&gt;.
&lt;/p&gt;

&lt;h2&gt;Namespacing your functions&lt;/h2&gt;
&lt;p&gt;As we&#039;ve seen in the &lt;a href=&quot;http://fi.am/entry/building-a-website-api-with-django-part-1-api-func/&quot;&gt;first post in this series&lt;/a&gt;, you API is loaded at an URL, for example http://example.com/api/1.0/rest/, so if you define a function named &lt;em&gt;foo&lt;/em&gt;, it will be accessible from &lt;em&gt;http://example.com/api/1.0/rest/foo.xml&lt;/em&gt; (or json or yaml). This is enough if your API consists only of a few functions. But what happens when your API has 50 functions?
&lt;/p&gt;
&lt;p&gt;WAPI provides support for namespacing your API. You only need to prepend your method with your namespace name and the binding will take care of splitting them. For example, the ReST binding uses the pattern &lt;em&gt;namespace/function_name&lt;/em&gt;, while the upcoming XML-RPC binding will use &lt;em&gt;namespace.function_name&lt;/em&gt;. Let&#039;s see an example:
&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BynotesApi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;nd&quot;&gt;@required_parameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;id&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;The geoname id you want to retrieve information for.&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;geo__hierarchy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Returns the hierarchy for the given geoname id, starting from itself.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;geoname&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Geoname&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;objects&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pk&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;id&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Geoname&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DoesNotExist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SingleSerializableResponse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SerializableResponse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;geoname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;geoname&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hierarchy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you see, the namespace separator in WAPI is &quot;__&quot; (two underscores). So when this method gets exposed with the rest binding it will live at geo/geoname.{ format }, while the XML-RPC binding will serve it from geo.geoname.
&lt;/p&gt;

&lt;h2&gt;Optional parameters and parameter sets&lt;/h2&gt;
&lt;p&gt;Sometimes your functions will accept optional parameters, so WAPI also provides support for working with them and lets you provide a default parameter. Note that if you don&#039;t specify a default value, there&#039;s always an implicit default value: None. Id est, the key in the &lt;em&gt;dct&lt;/em&gt; parameter will always be present, so you don&#039;t need to check for it. The syntax for optional parameters is:
&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nd&quot;&gt;@required_parameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;id&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;The geoname id you want to retrieve information for.&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;nd&quot;&gt;@optional_parameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;parent&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;Wheter to include information for the parent location.&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;geo__geoname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Returns information about a given geoname, like class and code, coordinates, ...&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;geoname&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Geoname&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;objects&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pk&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dct&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;id&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Geoname&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DoesNotExist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SingleSerializableResponse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;parent&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&#039;parent&#039;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SingleSerializableResponse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;geoname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Well, you can also see that this serialization is receiving an additional parameter we haven&#039;t seen before (method). That&#039;s related to the complex serializations we&#039;ll see in the next article.
&lt;/p&gt;
&lt;p&gt;Another common use case is having multiple functions which receive the same parameters (or a subset of them). In WAPI, this is implemented using parameter sets. For example, there are multiple API functions at &lt;a href=&quot;http://bynotes.com&quot;&gt;byNotes&lt;/a&gt; which support pagination, so I&#039;ve defined a parameter set I add to all those functions, saving me from DRY:
&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;wapi.parameters&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FunctionParameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FunctionParameterSet&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;PAGINATION_PARAM_SET&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FunctionParameterSet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;FunctionParameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;since_id&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;Return only notes with id greater than since_id.&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)),&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;FunctionParameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;offset&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;Skip the first offset notes.&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;validators&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RangeValidator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;min_value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)),&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;FunctionParameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;limit&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;The maximum number of notes returned.&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;validators&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RangeValidator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;min_value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;max_value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)),&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ignore the validators argument for now, we&#039;ll see it in the next paragraph. As you can see, parameter sets don&#039;t specify if the arguments are required or optional, since this approach provides more flexibility. Adding them to one of you functions uses the same syntax we&#039;ve seen before:
&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nd&quot;&gt;@optional_parameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;geoname&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;Geoname identifier for the area you want to restrict notes to.&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;nd&quot;&gt;@optional_parameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PAGINATION_PARAM_SET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;timeline&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Returns latest public notes. If a geoname is provided, only notes&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    posted from it and its children will be returned.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;since_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;end&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get_range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;nset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Note&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;live&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;order_by&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;-id&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id__gt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;since_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dct&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;geoname&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;geoname&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get_object_or_404&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Geoname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dct&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;geoname&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;nset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nset&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Note&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;in_geoname_q&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;geoname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SerializableResponse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;optional_parameter&lt;/em&gt; and &lt;em&gt;required_parameter&lt;/em&gt; decorators know how to deal with parameter sets, so you don&#039;t need to learn a new syntax. Parameter sets also support iteration and slicing, just in case you want to use only a subset of them.
&lt;/p&gt;

&lt;h2&gt;Extended parameter validation&lt;/h2&gt;
&lt;p&gt;As we saw in &lt;a href=&quot;http://fi.am/entry/building-a-website-api-with-django-part-1-api-func/&quot;&gt;part1&lt;/a&gt;, WAPI does basic type validation and conversion to all the parameters a function receives. However, sometimes you want to perform additional validation and that&#039;s when wapi.validators comes handy. First, let me say this validators are not same as django.core.validators (altought some wapi.validators call django.core.validators) and aren&#039;t incompatible with them, so you can&#039;t pass a validator from django.core.validators to a WAPI function. However, by the next release of WAPI I may add some code to &quot;automagically&quot; convert them, so you&#039;ll be able to pass any validator.
&lt;/p&gt;
&lt;p&gt;Currently WAPI provides validators for string length, unicode, range, comma separated values and multiple choices. If you want another validator added before the next release, ping me as soon as possible with the details.
&lt;/p&gt;
&lt;p&gt;Validators are specified using the &lt;em&gt;validators&lt;/em&gt; keyword when creating a function parameter, and it can be a single instance of wapi.validators.Validator or an iterable containing some of them. For example:
&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nd&quot;&gt;@required_parameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;place_name&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;unicode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#039;Place name for the event (this is only for display, this parameter is not for the full address).&#039;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;validators&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StringValidator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max_length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Allowed request methods&lt;/h2&gt;
&lt;p&gt;By default, functions in WAPI are readwrite. Id est, RestBinding exposes them as GET and POST methods. There are two decorators for altering this behavior, &lt;em&gt;readonly&lt;/em&gt; and &lt;em&gt;writeonly&lt;/em&gt;. As you surely have guessed, readonly methods get exposed only as GET, while writeonly methods only work with POST. As a final note, keep in mind that WAPI does not mix GET and POST, parameters passed by GET are ignored in POST requests.
&lt;/p&gt;

&lt;h2&gt;Next article in this series&lt;/h2&gt;
&lt;p&gt;In the next article, I&#039;ll write about object serialization using wapi.serializers and how you can chain and include other serializations and pass parameters to them.
&lt;/p&gt;</description>
            
            <pubDate>Tue, 19 Aug 2008 05:49:05 -0700</pubDate>
        </item>
            
        <item>
            <title>Google App Engine Open Source Projects</title>
            <link>http://swik.net/opensource/del.icio.us+tag%2Fopensource/Google+App+Engine+Open+Source+Projects/ccvth</link>
            <description></description>
            
            <pubDate>Tue, 19 Aug 2008 03:23:47 -0700</pubDate>
        </item>
            
        <item>
            <title>Ohloh, the open source network</title>
            <link>http://swik.net/open-source/del.icio.us+tag%2Fopen-source/Ohloh%2C+the+open+source+network/ccvaj</link>
            <description></description>
            
            <pubDate>Mon, 18 Aug 2008 22:16:44 -0700</pubDate>
        </item>
            
        <item>
            <title>antonius - Ohloh</title>
            <link>http://swik.net/open-source/del.icio.us+tag%2Fopen-source/antonius+-+Ohloh/ccvai</link>
            <description></description>
            
            <pubDate>Mon, 18 Aug 2008 22:16:40 -0700</pubDate>
        </item>
            
        <item>
            <title>Ed Menendez: Celebrity Fantasy Game In Django</title>
            <link>http://swik.net/django/Django+Community+Aggregator/Ed+Menendez%3A+Celebrity+Fantasy+Game+In+Django/ccu91</link>
            <description>&lt;img src=&quot;http://www.menendez.com/site_media/images/blog/django_r.jpg&quot; width=&quot;281&quot; height=&quot;297&quot; border=&quot;0&quot;/&gt;

&lt;p&gt;If you&#039;ve played fantasy football or any fantasy sport you know what I&#039;m takling about. If you&#039;re new to the concept, you pick a roster of celebrities and if they show up in the news, you get points.&lt;/p&gt;

&lt;p&gt;The site was written using Django (trunk as of the 13th!) and Postgres 8.2. We&#039;ve built a fantasy games package on top of the Django core which we would probably open-source if the community showed some interest in it.&lt;/p&gt;

&lt;p&gt;This is our 2nd major site in Django and we really love it. To begin with, Python is a great language. When we built our fantasy engine, it was originally coded on MySQL. We encountered quite a few problems porting it over to Postgres. There are lots of little things where MySQL does type conversions for you automatically and Postgres (correctly in my opinion) does not. I definitely feel the conversion was worth it so that now we&#039;re on an enterprise level database.&lt;/p&gt;</description>
            
            <pubDate>Mon, 18 Aug 2008 22:13:31 -0700</pubDate>
        </item>
                </channel>
</rss>
