<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>pydanny</title><link href="http://pydanny.com/" rel="alternate"></link><link href="http://pydanny.com/feeds/django.atom.xml" rel="self"></link><id>http://pydanny.com/</id><updated>2013-06-13T15:33:00-07:00</updated><entry><title>Core Concepts of Django ModelForms</title><link href="http://pydanny.com/core-concepts-django-modelforms.html" rel="alternate"></link><updated>2013-06-13T15:33:00-07:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2013-06-13:core-concepts-django-modelforms.html</id><summary type="html">&lt;p&gt;In my opinion, the concepts behind Django's model forms can be listed in just six (6) bullets. The bullets I've marked in &lt;strong&gt;bold&lt;/strong&gt; at the top are the topic of this blog post, while the two of these that were &lt;a class="reference external" href="http://pydanny.com/core-concepts-django-forms.html"&gt;covered in a previous blog post on Django forms&lt;/a&gt; are at bottom of my list.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;strong&gt;ModelForms render Model fields as HTML.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ModelForms select validators based off of Model field definitions.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ModelForms don't have to display/change all available fields.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ModelForms save dictionaries to SQL tables.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Forms are &amp;quot;just&amp;quot; Python constructs. (covered previous)&lt;/li&gt;
&lt;li&gt;Forms validate Python dictionaries. (covered previous)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="section" id="modelforms-render-model-fields-as-html"&gt;
&lt;h2&gt;ModelForms render Model fields as HTML.&lt;/h2&gt;
&lt;p&gt;If I create a Django model:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# myapp/models.py&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then attach it to a ModelForm:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# myapp/forms.py&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MyModel&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyModelForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ModelForm&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

        &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MyModel&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I can render it in a template, or for better clarity in this post, the Python REPL:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;myapp.forms&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MyModelForm&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;mf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MyModelForm&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;mf&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;__main__&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MyForm&lt;/span&gt; &lt;span class="nb"&gt;object&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="mh"&gt;0x1023c8bd0&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mf&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;tr&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;th&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;id_title&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;th&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;td&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;input&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;id_title&amp;quot;&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;title&amp;quot;&lt;/span&gt; &lt;span class="n"&gt;maxlength&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;100&amp;quot;&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;text&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;td&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;tr&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="modelforms-select-validators-based-off-of-model-field-definitions"&gt;
&lt;h2&gt;ModelForms select validators based off of Model field definitions.&lt;/h2&gt;
&lt;p&gt;One of the nice things about Django is that its forms library protects your models. It does this by assigning one or more of Django's many built-in validators to the form fields it generates, and using them to check incoming data. Let's dive in:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;myapp.forms&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MyModelForm&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;mf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MyModelForm&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;mf&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;__main__&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MyForm&lt;/span&gt; &lt;span class="nb"&gt;object&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="mh"&gt;0x1023c8bd0&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;mf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;title&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt; &lt;span class="nb"&gt;object&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="mh"&gt;0x102474bd0&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;title&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;
&lt;span class="mi"&gt;100&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;validators&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;core&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;validators&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MaxLengthValidator&lt;/span&gt; &lt;span class="nb"&gt;object&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="mh"&gt;0x102403b10&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Each individual field contains a list of validators  (in this case, just one validator) supplied by Django and any ModelForm customizations that might have been done.&lt;/p&gt;
&lt;p&gt;If you want to add more validators to a ModelForm (perhaps we want our title field to require at least 20 characters) one way to do it is by overriding the field definition in the ModelForm class's &lt;tt class="docutils literal"&gt;__init__&lt;/tt&gt; method. That's a mouthful, so I'll just demonstrate in code:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# myapp/forms.py&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.core.validators&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MinLengthValidator&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MyModel&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyModelForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ModelForm&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MyModelForm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;title&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;min_length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;title&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;validators&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MinLengthValidator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

        &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MyModel&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If we stop/start the shell, we now see some new elements added to the form object:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;# Don&amp;#39;t forget to stop/start the Django shell!&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;myapp.forms&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MyModelForm&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;mf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MyModelForm&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;mf&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;__main__&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MyForm&lt;/span&gt; &lt;span class="nb"&gt;object&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="mh"&gt;0x1023c8bd0&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;mf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;title&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt; &lt;span class="nb"&gt;object&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="mh"&gt;0x1023ee810&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;title&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;
&lt;span class="mi"&gt;100&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;min_length&lt;/span&gt;
&lt;span class="mi"&gt;20&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;validators&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;core&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;validators&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MaxLengthValidator&lt;/span&gt; &lt;span class="nb"&gt;object&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="mh"&gt;0x10240c7d0&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;core&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;validators&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MinLengthValidator&lt;/span&gt; &lt;span class="nb"&gt;object&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="mh"&gt;0x1023eef90&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we have two validators for the field!&lt;/p&gt;
&lt;p&gt;There are other ways to override the title field validators. The easiest but not necessarily the best way is to replicate the ModelForm definition of the field in the form like so:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# myapp/forms.py&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MyModel&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyModelForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ModelForm&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;min_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

        &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MyModel&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I don't like this technique. This makes it so we are defining the title field in two places, once in the model and once in the form. I go into more of the details and problems of this approach in my previous blog post at &lt;a class="reference external" href="http://pydanny.com/overloading-form-fields.html"&gt;Overloading Django Form Fields&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="modelforms-don-t-have-to-display-change-all-available-fields"&gt;
&lt;h2&gt;ModelForms don't have to display/change all available fields.&lt;/h2&gt;
&lt;p&gt;Before we dive into this section, let's increase our model to have two fields as shown below:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# myapp/models.py&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;slug&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SlugField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let's say that we don't want to allow users the ability to change slugs on existing content, otherwise URLs will be broken. In this case, we rely on the &lt;tt class="docutils literal"&gt;fields&lt;/tt&gt; attribute of &lt;tt class="docutils literal"&gt;ModelForm.Meta&lt;/tt&gt; to make it so we only display what we want to display:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# myapp/forms.py&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MyModel&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyModelForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ModelForm&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

        &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MyModel&lt;/span&gt;
        &lt;span class="n"&gt;fields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;title&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Easy!&lt;/p&gt;
&lt;div class="section" id="but-what-about-modelform-meta-excludes"&gt;
&lt;h3&gt;But what about ModelForm.Meta.excludes?&lt;/h3&gt;
&lt;p&gt;We advocate strongly against using &lt;tt class="docutils literal"&gt;ModelForm.Meta.excludes&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;In fact, when we were writing &lt;a class="reference external" href="https://django.2scoops.org"&gt;Two Scoops of Django&lt;/a&gt; the majority of our technical reviewers as well as our security reviewer fervently insisted that we advocate against use of &lt;tt class="docutils literal"&gt;ModelForm.Meta.excludes&lt;/tt&gt;. We provide numerous warnings about it's usage, and go in-depth as to why in &lt;em&gt;section 21.12&lt;/em&gt;. For reference, Django's own documentation is now including a rather mild warning (no warning box) on the subject at &lt;a class="reference external" href="https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#modelforms-selecting-fields"&gt;selecting the fields to use&lt;/a&gt;. I might try and get that addressed in the next few days...&lt;/p&gt;
&lt;p&gt;In any case, the problem with &lt;tt class="docutils literal"&gt;ModelForm.Meta.excludes&lt;/tt&gt; is similar to but worse than duplicating field functionality. It means that changes to models (new fields for example) will display in associated forms &lt;strong&gt;unless&lt;/strong&gt; you remember to modify the associated forms. Since a single model can have multiple forms, and we developers forget or leave projects, you can understanding what sort of security nightmare this can cause.&lt;/p&gt;
&lt;p&gt;Do yourself a favor and stay away from &lt;tt class="docutils literal"&gt;ModelForm.Meta.excludes&lt;/tt&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="modelforms-save-dictionaries-to-sql-tables"&gt;
&lt;h2&gt;ModelForms save dictionaries to SQL tables&lt;/h2&gt;
&lt;p&gt;In my &lt;a class="reference external" href="http://pydanny.com/core-concepts-django-forms.html"&gt;previous post of Django forms&lt;/a&gt; I covered &lt;em&gt;forms validate dictionaries&lt;/em&gt;. Well, ModelForms do the same thing AND give us the power to save that validated dictionary to SQL tables. We don't even need to involve web pages!&lt;/p&gt;
&lt;p&gt;This is really useful because it means that we can take data from any source, be it user input from the web, JSON data fetched from an API, and even CSVs generated from Excel reports and transform that into data that resides in SQL.&lt;/p&gt;
&lt;p&gt;Let's go over using our ModelForm with title/slug fields used with all those methods. In our samples (web page, json, csv), we'll use generating a timestamp to demonstrate how we can modify the model data before it's saved, and we'll base all three examples off the model and ModelForm combination listed below.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# myapp/models.py&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;timestamp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateTimeField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# myapp/forms.py&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Forms&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MyModel&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ModelForm&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

        &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MyModel&lt;/span&gt;
        &lt;span class="n"&gt;fields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;title&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And now to our three examples!&lt;/p&gt;
&lt;div class="section" id="example-1-web-page"&gt;
&lt;h3&gt;Example #1 Web Page&lt;/h3&gt;
&lt;p&gt;This should look pretty familiar to many Django developers. it's the traditional Django view pattern of processing simple model forms.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# myapp/views.py&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.core.shortcuts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;redirect&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.utils&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;timezone&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;.forms&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MyModelForm&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;POST&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MyModelForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_valid&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;

            &lt;span class="c"&gt;# commit=False means the form doesn&amp;#39;t save at this time.&lt;/span&gt;
            &lt;span class="c"&gt;# commit defaults to True which means it normally saves.&lt;/span&gt;
            &lt;span class="n"&gt;model_instance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;model_instance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timestamp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;timezone&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="n"&gt;model_instance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;victory&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MyModelForm&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;my_template.html&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;form&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="example-2-api-json"&gt;
&lt;h3&gt;Example #2 API/JSON&lt;/h3&gt;
&lt;p&gt;In this example, we're validating the output of a RESTful API before letting it touch our database. It's critical that such APIs are not allowed to touch our systems without proper validation - don't make my mistakes! Also, even internally within a project it's really important to validate all data coming from different databases. And Django makes it easy!&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# myapp/api/reitz.py&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.utils&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;timezone&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;requests&lt;/span&gt;  &lt;span class="c"&gt;# You are using requests-python, right?&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;.forms&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MyModelForm&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ReitzApiException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ne"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;pass&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch_reitz_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target_url&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target_url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;200&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

        &lt;span class="c"&gt;# generate the form from the response&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MyModelForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_valid&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="n"&gt;model_instance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;model_instance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timestamp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;timezone&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="n"&gt;model_instance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;model_instance&lt;/span&gt;

        &lt;span class="c"&gt;# Simplistic exception handling&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;ReitzApiException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;# Simplistic exception handling&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;ReitzApiException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="example-3-csv-import"&gt;
&lt;h3&gt;Example #3 CSV Import&lt;/h3&gt;
&lt;p&gt;I'll admit my mistake again: I've written my own validation tools to handle data coming from CSVs and Excel documents into Django projects. My validation scripts always seem fragile, and they are. What I'm doing going forward is I'm leaning on form libraries to do the hard work of validating data and saving it to models.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;csv&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.utils&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;timezone&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;.forms&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MyModelForm&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;import_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;records_added&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="n"&gt;errors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="c"&gt;# Generate a dict per row, with the first CSV row being the keys.&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;csv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DictReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;delimiter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;,&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

        &lt;span class="c"&gt;# Bind the row data to the MyModelForm&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MyModelForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_valid&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="n"&gt;model_instance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;model_instance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timestamp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;timezone&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="n"&gt;model_instance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="n"&gt;records_added&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;records_added&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="closing-thoughts"&gt;
&lt;h2&gt;Closing Thoughts&lt;/h2&gt;
&lt;p&gt;I can think of three things:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Forget the HTML&lt;/strong&gt;: For nearly every sort of occasion where new data is coming into your system, form libraries save you from doing extra work and cover your behind.  While my experience is with Django forms, there are many form libraries out there. The patterns explored in this post are certainly available in other web frameworks (see &lt;a class="reference external" href="http://flask.pocoo.org/snippets/category/forms/"&gt;http://flask.pocoo.org/snippets/category/forms/&lt;/a&gt; for proof).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HTML Rendering Issues&lt;/strong&gt;: No form library is going to do everything, and because of evolving standards, decent HTML rendering is a pain for form library authors. For example, Django's default form HTML rendering remains stuck in 2005 because if they had kept up with modern trends of HTML form layout we would have many different flavors of forms in Django core (a testing nightmare). Which means, as a developer, it's important when using a new form library to learn how to override the default form HTML rendering.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What about AJAX?&lt;/strong&gt;: Whoops! Does this mean I have to write another blog post? Not at all. In Django, AJAX is just another view, either function- or class-based. The secret is to validate the incoming data the same way as you would any other view request by using forms.&lt;/p&gt;
&lt;/div&gt;
</summary><category term="python"></category><category term="django"></category><category term="forms"></category></entry><entry><title>The Easy Form Views Pattern Controversy</title><link href="http://pydanny.com/the-easy-form-views-pattern-controversy.html" rel="alternate"></link><updated>2013-05-10T12:00:00-07:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2013-05-10:the-easy-form-views-pattern-controversy.html</id><summary type="html">&lt;p&gt;In the summer of 2010 &lt;a class="reference external" href="http://twitter.com/fwiles"&gt;Frank Wiles&lt;/a&gt; of &lt;a class="reference external" href="http://revsys.com"&gt;Revsys&lt;/a&gt; exposed me to what I later called the &amp;quot;&lt;strong&gt;Easy Form Views&lt;/strong&gt;&amp;quot; pattern when creating Django form function views. I used this technique in a variety of places, including &lt;a class="reference external" href="https://www.djangopackages.com"&gt;Django Packages&lt;/a&gt; and the documentation for django-uni-form (which is rebooted as &lt;a class="reference external" href="https://github.com/maraujop/django-crispy-forms"&gt;django-crispy-forms&lt;/a&gt;). At DjangoCon 2011 &lt;a class="reference external" href="http://tothinkornottothink.com/"&gt;Miguel Araujo&lt;/a&gt; and I opened our &lt;a class="reference external" href="http://lanyrd.com/2011/djangocon-us/shbrd/"&gt;Advanced Django Forms Usage&lt;/a&gt; talk at DjangoCon 2011 with this technique. It’s a pattern that reduces the complexity of using forms in Django function-based views by flattening the form handling code.&lt;/p&gt;
&lt;div class="section" id="how-the-easy-form-views-pattern-works"&gt;
&lt;h2&gt;How the Easy Form Views pattern works&lt;/h2&gt;
&lt;p&gt;Normally, function-based views in Django that handle form processing look something like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;my_view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;template_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;my_app/my_form.html&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;POST&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MyForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_valid&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="n"&gt;do_x&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c"&gt;# custom logic here&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;home&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MyForm&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;template_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;form&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In contrast, the Easy Form Views pattern works like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;my_view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;template_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;my_app/my_form.html&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MyForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_valid&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="n"&gt;do_x&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c"&gt;# custom logic here&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;home&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;template_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;form&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The way this works is that the &lt;tt class="docutils literal"&gt;django.http.HttpRequest&lt;/tt&gt; object has a POST attribute that defaults to an empty dictionary-like object, even if the request’s method is equal to &amp;quot;GET&amp;quot;. Since we know that &lt;cite&gt;request.POST&lt;/cite&gt; exists in every Django view, and os at least as an empty dictionary-like object, we can skip the &lt;tt class="docutils literal"&gt;request.method == 'POST'&lt;/tt&gt; by doing a simple boolean check on the &lt;tt class="docutils literal"&gt;request.POST&lt;/tt&gt; dictionary.&lt;/p&gt;
&lt;p&gt;In other words:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;If &lt;tt class="docutils literal"&gt;request.POST&lt;/tt&gt; dictionary evaluates as &lt;tt class="docutils literal"&gt;True&lt;/tt&gt;, then instantiate the form bound with &lt;tt class="docutils literal"&gt;request.POST&lt;/tt&gt;.&lt;/li&gt;
&lt;li&gt;If &lt;tt class="docutils literal"&gt;the request.POST&lt;/tt&gt; dictionary evaluates as &lt;tt class="docutils literal"&gt;False&lt;/tt&gt;, then instantiate an unbound form.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Great! Faster to write and shallower code! What could possibly be wrong with that?&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="the-controversy"&gt;
&lt;h2&gt;The Controversy&lt;/h2&gt;
&lt;p&gt;Before you jump to convert all your function based forms to this pattern, consider the following argument raised against it by a good friend:&lt;/p&gt;
&lt;blockquote class="epigraph"&gt;
&lt;p&gt;This one of those things where &amp;quot;empty dictionary and null both evaluate as false&amp;quot; can bite you.&lt;/p&gt;
&lt;p&gt;There's a difference between &amp;quot;There is no POST data&amp;quot;, and &amp;quot;This wasn't a POST&amp;quot;.&lt;/p&gt;
&lt;p class="attribution"&gt;&amp;mdash;by &lt;a class="reference external" href="http://cecinestpasun.com/"&gt;Russell Keith-Magee&lt;/a&gt; (paraphrased)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The problem he is talking about is data besides &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;multipart/form-data&lt;/span&gt;&lt;/tt&gt; or &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;application/x-www-form-urlencoded&lt;/span&gt;&lt;/tt&gt; would still end up in the &lt;tt class="docutils literal"&gt;request.POST&lt;/tt&gt; dictionary-like attribute.&lt;/p&gt;
&lt;p&gt;Where is the controversy? Well, I didn't write a retraction until now. Arguably I should have done it earlier. However, since I never ran into the edge case, I didn't see the need. Yet when it comes down to it, the &amp;quot;Easy Forms&amp;quot; approach has an implicit assumption about the incoming object, which in Python terms is not a good thing.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="getting-bit-by-the-easy-form-views-method"&gt;
&lt;h2&gt;Getting bit by the Easy Form Views method&lt;/h2&gt;
&lt;p&gt;Here's how it happens:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Before Django 1.5&lt;/strong&gt; HTTP methods such as DELETE or PUT would see their data placed into Django's &lt;tt class="docutils literal"&gt;request.POST&lt;/tt&gt; attribute. The form would fail, but it might not be clear to the developer or user why. HTTP GET and POST methods work as expected.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;For Django 1.5 (and later)&lt;/strong&gt; if a non-POST comes in then the form fails because request.POST is empty. HTTP GET and POST methods also work as expected.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="conclusion"&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Going forward, I prefer to use Django's class-based views or &lt;a class="reference external" href="http://djangorestframework.com"&gt;Django Rest Framework&lt;/a&gt; which make the issue of this pattern moot. When I do dip into function-based views handling classic HTML forms, I'm leery of using this pattern anymore. Yes, it is an edge case, but to inaccurately paraphrase Russell, &amp;quot;edge cases are where you get bit&amp;quot;.&lt;/p&gt;
&lt;p&gt;What I'm not going to do is rush to change existing views on existing projects.  That's because personally I've yet to run into an actual problem with using this pattern. As they say, &amp;quot;&lt;em&gt;If it ain't broke, don't fix it.&lt;/em&gt;&amp;quot; While I'm not saying my code isn't broken, I'm also aware that 'fixing' things that aren't reporting errors is a dangerous path to tread.&lt;/p&gt;
&lt;p&gt;Also, next time I get called on something by a person I respect, I'll respond more quickly. Nearly two years is too long a wait.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Changed some of the text to be more succinct and took out the leading sentence.&lt;/p&gt;
&lt;/div&gt;
</summary><category term="python"></category><category term="django"></category><category term="howto"></category></entry><entry><title>Tools we used to write Two Scoops of Django</title><link href="http://pydanny.com/tools-we-used-to-write-2scoops.html" rel="alternate"></link><updated>2013-05-03T10:00:00-07:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2013-05-03:tools-we-used-to-write-2scoops.html</id><summary type="html">&lt;p&gt;Because of the ubiquitousness of &lt;a class="reference external" href="http://en.wikipedia.org/wiki/Restructured_Text"&gt;reStructuredText&lt;/a&gt; in the lives of &lt;a class="reference external" href="http://python.org"&gt;Python&lt;/a&gt; developers and the advocacy of it, it's not uncommon for people to assume we used it to write our book. However, that's not really the case.&lt;/p&gt;
&lt;p&gt;The short Answer is we used:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;reStructuredText (RST)&lt;/li&gt;
&lt;li&gt;Google Documents&lt;/li&gt;
&lt;li&gt;Apple Pages&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://en.wikipedia.com/wiki/LateX"&gt;LaTeX&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The long answer is the rest of this posting. Since writing the book was broken up into three major stages '&lt;em&gt;alpha&lt;/em&gt;', '&lt;em&gt;beta&lt;/em&gt;', and '&lt;em&gt;final&lt;/em&gt;', so have I broken up blog article.&lt;/p&gt;
&lt;div class="section" id="alpha-days"&gt;
&lt;h2&gt;Alpha Days&lt;/h2&gt;
&lt;p&gt;Some of the original alpha material was written in rough draft form as RST since it was what we were used to using. Unfortunately, the PDF generation wasn't to our liking, so we immediately began looking at other options. Since she enjoyed using it at MIT and because it gave us greater individual control, &lt;a class="reference external" href="http://audreymroy.com"&gt;Audrey&lt;/a&gt; wanted to switch to &lt;a class="reference external" href="http://en.wikipedia.com/wiki/LateX"&gt;LaTeX&lt;/a&gt;. I was worried about the challenges of learning LaTeX, so we compromised and moved to Google Documents.&lt;/p&gt;
&lt;p&gt;For the most part, Google Documents was great in the early stages. The real-time collaborative nature was handy, but the gem was the comment system. It gave us the ability to have line-by-line written dialogues with our technical reviewers. However, Google Documents makes it nigh-impossible to use WYSIWYG editor styles, add in better print fonts, forced us to cut-and-paste code examples, and finally the PDF export system was flakey on our massive document.&lt;/p&gt;
&lt;p&gt;Our original thought was to convert the Google Document output to PDF and then modify it with Adobe InDesign. Upon trying it, we found it had a lackluster user interface that had a steep learning curve and was prohibitively expensive ($550-$700). Our friend and reviewer, Kenneth Love of &lt;a class="reference external" href="http://gettingstartedwithdjango.com"&gt;Getting Started with Django&lt;/a&gt; fame, offered to do the conversion work, but we wanted to be able to update our work at will. Awesome as Kenneth might be, we couldn't expect him to drop what he was doing to update the final output of our work whenever we wanted.&lt;/p&gt;
&lt;p&gt;Therefore, what we did in the week of January 10th-16th was convert the book to Apple Pages, which is the word processor in Apple iWorks. This was as painful as it sounds. We also discovered the day before launch that Apple Pages doesn't create a sidebar PDF table of contents, which a lot of people enjoy (including ourselves). Tired and exhausted from weeks of 16 hour days, we launched anyway on January 17th with the book weighing in at 5.1 MB.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="beta-experiences"&gt;
&lt;h2&gt;Beta Experiences&lt;/h2&gt;
&lt;p&gt;People were so positive it really gave us a boost. Hundreds of people sent us feedback and we were delighted beyond words, with a significant portion sending us commentary/corrections about our writing and code. I'll admin did get tired over a certain 'moat' mistake since I got corrected on it over 50 times. However, the number of code corrections we were getting was higher than expected. It was clear we needed to be able to import the code modules from testable chunks of real code.  We had so many kindle/epub requests we also needed the ability to render the text attractively across multiple formats.&lt;/p&gt;
&lt;p&gt;After stumbling through RST, Google Documents, and Apple Pages different tools, I finally agreed with Audrey that the challenges of learning LaTeX was worth it. While we could have used RST, we would have had to use LaTeX anyway for our customizations since when RST is converted to PDF it actually uses an interim step of LaTeX!&lt;/p&gt;
&lt;p&gt;So while I handled the corrections and feedback from thousands, Audrey built the fundamentals of the LaTeX file structure. Audrey really got her hands dirty by teaching me LaTeX, since my brain is slow and thick. Here's a sample of what I've learned how to do, taken from Chapter 6, Section 1, Subsection 5 (6.1.5):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;\subsection&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;Model Inheritance in Practice: The TimeStampedModel&lt;span class="nb"&gt;}&lt;/span&gt;
It&amp;#39;s very common in Django projects to include a &lt;span class="k"&gt;\inlinecode&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;created&lt;span class="nb"&gt;}&lt;/span&gt; and &lt;span class="k"&gt;\inlinecode&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;modified&lt;span class="nb"&gt;}&lt;/span&gt; timestamp field on all your models. We could manually add those fields to each and every model, but that&amp;#39;s a lot of work and adds the risk of human error. A better solution is to write a &lt;span class="k"&gt;\inlinecode&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;TimeStampedModel&lt;span class="nb"&gt;}&lt;/span&gt; &lt;span class="k"&gt;\index&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;TimeStampedModel&lt;span class="nb"&gt;}&lt;/span&gt; to do the work for us:

&lt;span class="k"&gt;\goodcodefile&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;chapter&lt;span class="nb"&gt;_&lt;/span&gt;06/myapp/core/timestampedmodel.py&lt;span class="nb"&gt;}&lt;/span&gt;

Take careful note of the very last two lines in the example, which turn our example into an abstract base class: &lt;span class="k"&gt;\index&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;abstract base classes&lt;span class="nb"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;\goodcodefile&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;chapter&lt;span class="nb"&gt;_&lt;/span&gt;06/myapp/core/class&lt;span class="nb"&gt;_&lt;/span&gt;meta.py&lt;span class="nb"&gt;}&lt;/span&gt;

By defining &lt;span class="k"&gt;\inlinecode&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;TimeStampedModel&lt;span class="nb"&gt;}&lt;/span&gt; as an abstract base class &lt;span class="k"&gt;\index&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;abstract base classes&lt;span class="nb"&gt;}&lt;/span&gt; when we define a new class that inherits from it, Django doesn&amp;#39;t create a &lt;span class="k"&gt;\inlinecode&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;model&lt;span class="k"&gt;\_&lt;/span&gt;utils.time&lt;span class="k"&gt;\_&lt;/span&gt;stamped&lt;span class="k"&gt;\_&lt;/span&gt;model&lt;span class="nb"&gt;}&lt;/span&gt; table when syncdb is run.
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Once I got the hang of LaTeX, then began the hard work of converting the book's current content from Apple Pages That was a couple weeks of grueling effort on my part. Daily I would request a new LaTeX customizations, which Audrey would address. However, as she was working on literally rewriting the content of a dozen chapters including templates, testing, admin, and logging my interruptions became an issue. So we enlisted the help of Italian economist and LaTeX expert Laura Gelsomino. Thanks to her the desired text formatting was achieved.&lt;/p&gt;
&lt;p&gt;During the conversion process we also rewrote every single code example, putting them into easily testable projects, and pull them into via use of custom LaTeX commands called &lt;tt class="docutils literal"&gt;\goodcodefile{}&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;\badcodefile{}&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Eventually I joined Audrey on rewriting and reviewing chapters and on February 28th, the beta was launched. LaTeX generates lean PDFs so the book came in at just 1.6 MB while adding a whopping 50 pages (25% more) of content.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="final-efforts"&gt;
&lt;h2&gt;Final Efforts&lt;/h2&gt;
&lt;p&gt;The final effort was focused on cleanup, new formats, presentation, and art.&lt;/p&gt;
&lt;p&gt;For cleanup, our amazing readers gave us so much feedback we could barely keep up. We fought to keep our dialogues with them personal yet brief. With reader oversight we corrected many of the 'quirks' of my writing style (Audrey is a stickler for Strunk and White, I am not). We also made numerous corrections based on feedback and our own observations.&lt;/p&gt;
&lt;p&gt;With the guidance of fellow Python author &lt;a class="reference external" href="http://hairysun.com/"&gt;Matt Harrison&lt;/a&gt; I wrote scripts that took the archaic HTML generated by LaTeX module tex4ht and rendered it into something that Kindlegen could use to generate Kindle .mobi files. At first the results looked awesome on modern kindles and other new ebook readers, but was terrible on older devices. So I toned back the fancy stuff to what you see today. Getting technical books to look nice on all readers is really, really hard - and unfortunately some publishers take shortcuts that hurt the efforts of the authors. If you have problem with an e-book's format, please consider that before writing a negative review about the final output.&lt;/p&gt;
&lt;p&gt;Speaking of mobile editions, we also wrote a second version of each Python example to deal with the smaller format. While libraries exist to do the work for you, since I did a lot of it from scratch (albeit coached by Matt) I had to dig into the lackluster .mobi/.epub documentation to figure out things like .ncx files.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;note:&lt;/strong&gt; If you want to be the self-published author of a technical book I &lt;em&gt;strongly recommend&lt;/em&gt; you read Matt's &lt;a class="reference external" href="http://www.amazon.com/Ebook-Formatting-Mobi-EPUB-ebook/dp/B00BWQXHU6/ref=la_B0077BQLH6_1_2?ie=UTF8&amp;amp;qid=1366041987&amp;amp;sr=1-2&amp;amp;tag=cn-001-20"&gt;Ebook Formatting: KF8, Mobi &amp;amp; EPUB&lt;/a&gt;. Also check out his rst2epub2 library for converting RST files to various formats.&lt;/p&gt;
&lt;p&gt;While I worked on the mobile editions, Audrey focused on the print version and adding more art and tiny bit of new content. She focused on clarity and flow, and the result is that the book feels even lighter to read and yet is dense with useful information. To test how the book launched, she would order a copy from the printer and wait several days for it to arrive. Then she would inspect the cover and interior with her incredibly exacting eye. It's a slow process, but Audrey wanted to make absolutely certain our readers would enjoy and use the print edition.&lt;/p&gt;
&lt;p&gt;On April 10th we launched the final in PDF, Kindle, and ePub form. The PDF weighs in at 2.7 MB, and the Kindle file is a bit heaver. At some point we'll do the work to reduce file size, but for now we're working on other things.&lt;/p&gt;
&lt;p&gt;A week later we announced the launch of the &lt;a class="reference external" href="http://www.amazon.com/Two-Scoops-Django-Best-Practices/dp/1481879707/ref=sr_1_2?ie=UTF8&amp;amp;qid=1366166104&amp;amp;sr=8-2&amp;amp;tag=cn-001-20"&gt;print version of the book&lt;/a&gt;. People seem to really like the design and feel of the physical book, and we've even had requests for t-shirts.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="thoughts"&gt;
&lt;h2&gt;Thoughts&lt;/h2&gt;
&lt;p&gt;Writing a technical book was really hard. Crazy hard. Also very satisfying. We could have made more money doing just client work, but this was a dream come true. Sometimes money doesn't matter.&lt;/p&gt;
&lt;div class="section" id="whither-two-scoops-of-django"&gt;
&lt;h3&gt;Whither Two Scoops of Django?&lt;/h3&gt;
&lt;p&gt;&lt;a class="reference external" href="http://django.2scoops.org"&gt;Two Scoops of Django: Best Practices for Django 1.5&lt;/a&gt; will still receive periodic corrections, but won't see new content unless it's security related for Django 1.5. Don't worry though, for when Django 1.6 comes nigh, we'll commence work on Two Scoops of Django: Best Practices for Django &lt;strong&gt;1.6&lt;/strong&gt; (&lt;strong&gt;TSD 1.6&lt;/strong&gt;). The plan is to update practices as needed and hopefully add more content on testing, logging, continuous integration, and more. Like it's predecessor TSD 1.6 will be written using LaTeX.&lt;/p&gt;
&lt;p&gt;That said, if I ever fulfill my dream of writing fiction I'll just use Matt Harrison's &lt;a class="reference external" href="https://github.com/mattharrison/rst2epub2"&gt;rst2epub2&lt;/a&gt; library.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="concerns-about-open-sourcing"&gt;
&lt;h3&gt;Concerns about Open Sourcing&lt;/h3&gt;
&lt;p&gt;We've considered open sourcing our current book generation system, but installation is rather challenging and requires serious Audrey/Laura-level LaTeX knowledge combined with my experience with Python. Unfortunately, from our experience on managing other open source projects, dealing with requests for documentation and assistance would take up a prohibitive amount of our time. Honestly, we would rather write another book or sling code.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="book-generation-as-a-service"&gt;
&lt;h3&gt;Book Generation as a Service?&lt;/h3&gt;
&lt;p&gt;Another option is turning our system into a service, which would convert existing RST or even MarkDown to LaTeX so it could generate books in the Two Scoops format. Doing this would require at least a month of full-time work on both of our parts, and we have no idea as to the interest level. We think it would be a low amount of interest, but then again, hasn't &lt;a class="reference external" href="http://leanpub.com"&gt;leanpub&lt;/a&gt; done pretty well using this model of business?&lt;/p&gt;
&lt;p&gt;In any case we're working on other projects. Maybe even a new technical book...&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</summary><category term="django"></category><category term="python"></category><category term="twoscoops"></category><category term="book"></category></entry><entry><title>Filepicker.io and South</title><link href="http://pydanny.com/filepicker-and-south.html" rel="alternate"></link><updated>2013-04-23T10:00:00-07:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2013-04-23:filepicker-and-south.html</id><summary type="html">&lt;p&gt;I've heard good things about filepicker.io, which is a service that makes file uploading a much better experience. Unfortunately, the Django package for filepicker.io doesn't work with South. When I try to create a migration using the filepicker.io field using code like the following...&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# products/models.py&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django_filepicker.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FPFileField&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FPFileField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;upload_to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;uploads&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;...when I try to run the command:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
(tsd)$ python manage.py schemamigration products --initial
&lt;/pre&gt;
&lt;p&gt;It results in this unpleasant looking response:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
(tsd)$ python manage.py schemamigration products --initial
Creating migrations directory at '/Users/danielgreenfeld/code/tsp/tsp/products/migrations'...
Creating __init__.py in '/Users/danielgreenfeld/code/tsp/tsp/products/migrations'...
 ! Cannot freeze field 'products.product.fpfile'
 ! (this field has class django_filepicker.models.FPFileField)
 ! Cannot freeze field 'products.release.fpfile'
 ! (this field has class django_filepicker.models.FPFileField)

 ! South cannot introspect some fields; this is probably because they are custom
 ! fields. If they worked in 0.6 or below, this is because we have removed the
 ! models parser (it often broke things).
 ! To fix this, read http://south.aeracode.org/wiki/MyFieldsDontWork
&lt;/pre&gt;
&lt;p&gt;The last line in the error report is important. I'll repeat it to illustrate it more clearly:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
! To fix this, read http://south.aeracode.org/wiki/MyFieldsDontWork
&lt;/pre&gt;
&lt;p&gt;Experience working on other projects has taught me I can simply add two lines of code to &lt;tt class="docutils literal"&gt;products/models.py&lt;/tt&gt; and everything should just work:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# South migration rules for the FPFileField field&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;south.modelsinspector&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;add_introspection_rules&lt;/span&gt;
&lt;span class="n"&gt;add_introspection_rules&lt;/span&gt;&lt;span class="p"&gt;([],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;django_filepicker\.models\.FPFileField&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In case it's not clear, here's my new &lt;tt class="docutils literal"&gt;products/models.py&lt;/tt&gt; file:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# products/models.py&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django_filepicker.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FPFileField&lt;/span&gt;

&lt;span class="c"&gt;# South migration rules for the FPFileField field&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;south.modelsinspector&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;add_introspection_rules&lt;/span&gt;
&lt;span class="n"&gt;add_introspection_rules&lt;/span&gt;&lt;span class="p"&gt;([],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;django_filepicker\.models\.FPFileField&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FPFileField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;upload_to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;uploads&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now I can create South migrations and they'll just work.&lt;/p&gt;
&lt;p&gt;Unfortunately, the problem is that for any model where I need to use filepicker's FPFileField I need to add those two lines of code. I don't like this approach, since it violates &lt;strong&gt;Don't Repeat Yourself&lt;/strong&gt; (DRY).&lt;/p&gt;
&lt;p&gt;At some point I'll demonstrate how to fix this violation of DRY with an easy fix. In fact, I plan submit that fix as a pull request to django-filepicker.&lt;/p&gt;
</summary><category term="django"></category><category term="python"></category><category term="filepicker"></category></entry><entry><title>Off to Europe!</title><link href="http://pydanny.com/off-to-europe.html" rel="alternate"></link><updated>2013-04-20T09:00:00-07:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2013-04-20:off-to-europe.html</id><summary type="html">&lt;p&gt;I feel like I'm dreaming, but &lt;strong&gt;we're on our way to Europe!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A few weeks &lt;a class="reference external" href="http://audreymroy.com"&gt;Audrey&lt;/a&gt; and I decided to move. While looking at possible rentals or even mortgages, we were idly (dreaming really... still paying off debts incurred from last year) looking at how much a room/apartment would cost to rent in Europe. To our surprise, we found a lot of good options that cost less then it would to pay monthly rent/mortgage in Los Angeles.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;o_O&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Then, we discovered an amazing travel deal. It combined a very cheap red-eye flight from Los Angeles to Fort Lauderdale, and a slow trans-atlantic ship from Port Miami to Barcelona, about as much as a cheap hotel but with free food! If we avoid alcohol and any extra fees, it's actually extremely inexpensive. Being mostly disconnected from the internet would mean we could really focus on a couple of critical projects. If only we had a business justification for going to Europe...&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It just so happens that we have business in Europe.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Our plan is to spend a few months in Europe before returning back to the USA. We'll work hard on the ship, work hard when we arrive, and just get stuff done. It's not a vacation, but it is Europe, and there is such a thing as weekends.&lt;/p&gt;
&lt;p&gt;We'll be spending a few days in early May in Barcelona, then making our way to Poland for several weeks. Yes, we're attending &lt;a class="reference external" href="http://djangocircus.com"&gt;Django Circus&lt;/a&gt;, plus I want to investigate some family roots. After Poland, we're thinking either France, Italy, Hungary, England, Belgium, Scotland, Ireland, and other options. We'll see where the winds and affordable AirBNB places take us.&lt;/p&gt;
&lt;p&gt;When do we go back? Well, we plan to stay for at least two months. Even if we go back to the USA, we would have at least been in Europe for May and June. How cool is that?&lt;/p&gt;
&lt;p&gt;We could have talked ourselves out of going. We nearly did. However, even with our workload this is the chance of a lifetime.&lt;/p&gt;
&lt;p&gt;Finally, for the next two weeks I'll only be able to access the internet for a few minutes per day. Please expect my responses to emails and tweets to be slower than normal.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; In the middle of all of this, I was invited to keynote Django Circus: &lt;a class="reference external" href="http://blog.djangocircus.com/post/48439600279/meet-daniel-greenfeld"&gt;http://blog.djangocircus.com/post/48439600279/meet-daniel-greenfeld&lt;/a&gt;&lt;/p&gt;
</summary><category term="europe"></category><category term="travel"></category><category term="django"></category><category term="djangocon"></category></entry><entry><title>Two Scoops of Django is in print!</title><link href="http://pydanny.com/two-scoops-of-django-is-in-print.html" rel="alternate"></link><updated>2013-04-17T09:00:00-07:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2013-04-17:two-scoops-of-django-is-in-print.html</id><summary type="html">&lt;p&gt;Since I was a child I wanted to be a published author. I've dreamt of people reading my book. While one could say that dream was fulfilled when we launched the e-book version in January, it's not the same as seeing the printed copy. Today I got to see my dream come true, a printed &lt;a class="reference external" href="http://www.amazon.com/Two-Scoops-Django-Best-Practices/dp/1481879707/ref=sr_1_2?ie=UTF8&amp;amp;qid=1366166104&amp;amp;sr=8-2&amp;amp;tag=cn-001-20"&gt;book&lt;/a&gt; is out there with my name on it.&lt;/p&gt;
&lt;p&gt;Also, I have a confession to make. When it comes to technical books, I really prefer the print version. For me, nothing beats being able to flip through pages of a hardcopy next to a keyboard, or simply reading while I'm on a bus, train, or plane. So this adds to my excitement when I get to say that the book that &lt;a class="reference external" href="http://audreymroy.com/"&gt;Audrey Roy&lt;/a&gt; and I wrote together is in &lt;a class="reference external" href="http://www.amazon.com/Two-Scoops-Django-Best-Practices/dp/1481879707/ref=sr_1_2?ie=UTF8&amp;amp;qid=1366166104&amp;amp;sr=8-2&amp;amp;tag=cn-001-20"&gt;print&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Note: As of April 17th it's only available in the US. However, it's in the queue for being available for Amazon Europe. Enough people are asking that we are also looking into getting it bulk shipped to &lt;a class="reference external" href="http://djangocircus.com/"&gt;Django Circus&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;While it's been an amazing journey, it's also been a long hard road. Starting with a late night dinner with &lt;a class="reference external" href="http://rdegges.com"&gt;Randall Degges&lt;/a&gt;, his wife &lt;a class="reference external" href="http://hardlyfunny.com"&gt;Samantha&lt;/a&gt;, and &lt;a class="reference external" href="https://bravoflix.com/"&gt;Sean Bradley&lt;/a&gt;, to spending hours upon hours writing and revising, to taking painfully honest critiques from mentors, to alpha launch, then rewriting the book followed by the beta launch. It wasn't easy, but the growing volume of positive feedback and suggestions from readers kept us going.&lt;/p&gt;
&lt;p&gt;Between the Alpha and Beta releases we switched over to LaTeX. Audrey taught it to me in February, and I'm proud to say I've progressed from absolute neophyte to beginner. We chose it because of it's fine-grained control over layout for the PDF and print versions. Creating the Kindle and ePub versions from LaTeX was harder thanks to using LaTeX, but everything's automated now so making updates is easy. Future editions of this &lt;a class="reference external" href="http://www.amazon.com/Two-Scoops-Django-Best-Practices/dp/1481879707/ref=sr_1_2?ie=UTF8&amp;amp;qid=1366166104&amp;amp;sr=8-2&amp;amp;tag=cn-001-20"&gt;book&lt;/a&gt; (1.6, 1.7, etc) or other technical books I hope to write will continue to be in LaTeX, but if I publish fiction I'll probably go with RestructuredText.&lt;/p&gt;
&lt;p&gt;While working on the final version we were greatly saddened by the death of Malcolm Tredennick, to whom the &lt;a class="reference external" href="http://www.amazon.com/Two-Scoops-Django-Best-Practices/dp/1481879707/ref=sr_1_2?ie=UTF8&amp;amp;qid=1366166104&amp;amp;sr=8-2&amp;amp;tag=cn-001-20"&gt;book&lt;/a&gt; is dedicated. We miss him terribly. I've tried to write about Malcolm's volume of his contribution to the &lt;a class="reference external" href="http://www.amazon.com/Two-Scoops-Django-Best-Practices/dp/1481879707/ref=sr_1_2?ie=UTF8&amp;amp;qid=1366166104&amp;amp;sr=8-2&amp;amp;tag=cn-001-20"&gt;book&lt;/a&gt;, but it's still too hard. For now, let's just say that he gave and taught us so much and asked us for nothing in return, which is why we continue to give free copies of the PDF edition of the &lt;a class="reference external" href="http://www.amazon.com/Two-Scoops-Django-Best-Practices/dp/1481879707/ref=sr_1_2?ie=UTF8&amp;amp;qid=1366166104&amp;amp;sr=8-2&amp;amp;tag=cn-001-20"&gt;book&lt;/a&gt; to developers in need, as well as try to stay in contact with all recipients of the free PDF.&lt;/p&gt;
&lt;p&gt;In fact, if you are a developer in need, and can't afford a copy, drop us a note at &lt;a class="reference external" href="mailto:2scoops&amp;#64;cartwheelweb.com"&gt;2scoops&amp;#64;cartwheelweb.com&lt;/a&gt; explaining your situation. Our quick rule of thumb is that if you can afford to buy games for your favorite device, then you can afford to buy our &lt;a class="reference external" href="http://www.amazon.com/Two-Scoops-Django-Best-Practices/dp/1481879707/ref=sr_1_2?ie=UTF8&amp;amp;qid=1366166104&amp;amp;sr=8-2&amp;amp;tag=cn-001-20"&gt;book&lt;/a&gt;. Also, please do your friends a favor and don't just give them a copy without having them ask us. Why not? Well, &lt;strong&gt;we update the book frequently, and have a strong commitment for adding security related content&lt;/strong&gt; even now that the final edition is out.&lt;/p&gt;
&lt;p&gt;What now? Well, we aren't certain. We're maintaining a couple client projects but aren't taking on new ones. We've got a couple projects we're working on and I'm talking employment with a couple companies who do good things for the community.&lt;/p&gt;
</summary><category term="python"></category><category term="twoscoops"></category><category term="book"></category><category term="django"></category></entry><entry><title>Generating NCX files with Python</title><link href="http://pydanny.com/generating-ncx-files-with-python.html" rel="alternate"></link><updated>2013-04-15T09:00:00-07:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2013-04-15:generating-ncx-files-with-python.html</id><summary type="html">&lt;p&gt;With the help of fellow Python developer Matt Harrison's excellent &lt;a class="reference external" href="http://www.amazon.com/Ebook-Formatting-Mobi-EPUB-ebook/dp/B00BWQXHU6/ref=la_B0077BQLH6_1_2?ie=UTF8&amp;amp;qid=1366041987&amp;amp;sr=1-2&amp;amp;tag=cn-001-20"&gt;Ebook Formatting: KF8, Mobi &amp;amp; EPUB&lt;/a&gt;, we managed to create pretty decent looking Kindle and ePub versions of &lt;a class="reference external" href="http://django.2scoops.org/"&gt;Two Scoops of Django&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;One of many things we did was focus on providing an excellent table of contents. Of course we provided one inside the content of the book, but much like the PDF version we also provided one that various ebook readers can display in sidebars or drop down menus. Unfortunately, building this navigation isn't well documented (except for Matt's book), and I've yet to see any good ways to generate it via code.&lt;/p&gt;
&lt;p&gt;Which is why I present the following code. It looks at the HTML that KindleGen and ePub generators demand and pulls from it a chapter-based table of contents. Then constructs a .ncx file, which is what ebook readers use to generate the sidebar/dropdown table of contents.&lt;/p&gt;
&lt;p&gt;Our requirements:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
Jinja2
Django
BeautifulSoup4
&lt;/pre&gt;
&lt;p&gt;And now the code:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;#!/usr/bin/python&lt;/span&gt;
&lt;span class="c"&gt;# -*- coding: utf-8 -*-&lt;/span&gt;


&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;bs4&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BeautifulSoup&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.utils.text&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;slugify&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;jinja2&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Template&lt;/span&gt;

&lt;span class="n"&gt;TEMPLATE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;quot;&amp;quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;/span&gt;
&lt;span class="s"&gt;&amp;lt;!DOCTYPE ncx PUBLIC &amp;quot;-//NISO//DTD ncx 2005-1//EN&amp;quot; &amp;quot;http://www.daisy.org/z3986/2005/ncx-2005-1.dtd&amp;quot;&amp;gt;&lt;/span&gt;
&lt;span class="s"&gt;&amp;lt;ncx xmlns=&amp;quot;http://www.daisy.org/z3986/2005/ncx/&amp;quot; version=&amp;quot;2005-1&amp;quot; xml:lang=&amp;quot;en&amp;quot;&amp;gt;&lt;/span&gt;
&lt;span class="s"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;

&lt;span class="s"&gt;&amp;lt;!-- The content of dtb:uid must be exactly the same as the uuid specified in the OPF file. --&amp;gt;&lt;/span&gt;

&lt;span class="s"&gt;&amp;lt;meta name=&amp;quot;dtb:uid&amp;quot; content=&amp;quot;urn:uuid:BLAH-BLAH-BLAH&amp;quot;/&amp;gt;&lt;/span&gt;
&lt;span class="s"&gt;&amp;lt;meta name=&amp;quot;dtb:depth&amp;quot; content=&amp;quot;1&amp;quot;/&amp;gt;&lt;/span&gt;
&lt;span class="s"&gt;&amp;lt;meta name=&amp;quot;dtb:totalPageCount&amp;quot; content=&amp;quot;0&amp;quot;/&amp;gt;&lt;/span&gt;
&lt;span class="s"&gt;&amp;lt;meta name=&amp;quot;dtb:maxPageNumber&amp;quot; content=&amp;quot;0&amp;quot;/&amp;gt;&lt;/span&gt;
&lt;span class="s"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

&lt;span class="s"&gt;&amp;lt;docTitle&amp;gt;&amp;lt;text&amp;gt;Two Scoops of Django: Best Practices for Django 1.5&amp;lt;/text&amp;gt;&amp;lt;/docTitle&amp;gt;&lt;/span&gt;
&lt;span class="s"&gt;&amp;lt;docAuthor&amp;gt;&amp;lt;text&amp;gt;Greenfeld, Daniel&amp;lt;/text&amp;gt;&amp;lt;/docAuthor&amp;gt;&lt;/span&gt;
&lt;span class="s"&gt;&amp;lt;docAuthor&amp;gt;&amp;lt;text&amp;gt;Roy, Audrey&amp;lt;/text&amp;gt;&amp;lt;/docAuthor&amp;gt;&lt;/span&gt;
&lt;span class="s"&gt;&amp;lt;navMap&amp;gt;&lt;/span&gt;
&lt;span class="s"&gt;&amp;lt;/navPoint&amp;gt;&lt;/span&gt;
&lt;span class="s"&gt;{&lt;/span&gt;&lt;span class="si"&gt;% f&lt;/span&gt;&lt;span class="s"&gt;or chapter in chapters %}&lt;/span&gt;
&lt;span class="s"&gt;&amp;lt;navPoint id=&amp;quot;{{ chapter.slug }}&amp;quot; playOrder=&amp;quot;{{ loop.index }}&amp;quot;&amp;gt;&lt;/span&gt;
&lt;span class="s"&gt;&amp;lt;navLabel&amp;gt;&amp;lt;text&amp;gt;{{ chapter.string.strip() }}&amp;lt;/text&amp;gt;&amp;lt;/navLabel&amp;gt;&lt;/span&gt;
&lt;span class="s"&gt;&amp;lt;content src=&amp;quot;{{ chapter.href }}&amp;quot; /&amp;gt;&lt;/span&gt;
&lt;span class="s"&gt;&amp;lt;/navPoint&amp;gt;&lt;/span&gt;
&lt;span class="s"&gt;{&lt;/span&gt;&lt;span class="si"&gt;% e&lt;/span&gt;&lt;span class="s"&gt;ndfor %}&lt;/span&gt;
&lt;span class="s"&gt;&amp;lt;/navMap&amp;gt;&lt;/span&gt;
&lt;span class="s"&gt;&amp;lt;/ncx&amp;gt;&lt;/span&gt;
&lt;span class="s"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="c"&gt;# Grab the base file for review&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c"&gt;# load the text into a bs4 object&lt;/span&gt;
    &lt;span class="n"&gt;soup&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;BeautifulSoup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;# grab the nav element&lt;/span&gt;
    &lt;span class="n"&gt;nav&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;soup&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;nav&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;# loop through the TOC for chapters.&lt;/span&gt;
    &lt;span class="c"&gt;# Sections/Subsections can&amp;#39;t be displayed, so don&amp;#39;t worry about them&lt;/span&gt;
    &lt;span class="c"&gt;# li.chapter is how we constructed our TOC. Your mileage may vary.&lt;/span&gt;
    &lt;span class="n"&gt;chapters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;li&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;nav&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;li&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;chapter&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;chapters&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;href&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;slug&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;slugify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;li&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="c"&gt;# Render the template&lt;/span&gt;
    &lt;span class="n"&gt;template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TEMPLATE&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chapters&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;chapters&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;# convert to ASCII&lt;/span&gt;
    &lt;span class="n"&gt;template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;ascii&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;xmlcharrefreplace&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;# Save to the toc.ncx&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;toc.ncx&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;w&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;__main__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;book.html&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There is more to adding a table of contents then just this simple module. You also have to construct the .opf file, which is another undocumented mess that I'll blog about.&lt;/p&gt;
</summary><category term="python"></category><category term="twoscoops"></category><category term="book"></category><category term="django"></category></entry><entry><title>Core Concepts of Django Forms</title><link href="http://pydanny.com/core-concepts-django-forms.html" rel="alternate"></link><updated>2013-03-29T11:00:00-07:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2013-03-29:core-concepts-django-forms.html</id><summary type="html">&lt;p&gt;In my opinion, the concepts behind Django's non-model forms can be listed in just three (3) bullets:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Forms render HTML.&lt;/li&gt;
&lt;li&gt;Forms are &amp;quot;just&amp;quot; Python constructs.&lt;/li&gt;
&lt;li&gt;Forms validate dictionaries (Python's Key/Value structure).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let's dig in!&lt;/p&gt;
&lt;div class="section" id="forms-render-html"&gt;
&lt;h2&gt;Forms render HTML.&lt;/h2&gt;
&lt;p&gt;If I construct a Django form:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# myapp/forms.py&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I can render it in a template, or for better clarity in this post, the Python REPL:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;myapp.forms&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MyForm&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MyForm&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;__main__&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MyForm&lt;/span&gt; &lt;span class="nb"&gt;object&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="mh"&gt;0x1016c6990&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;tr&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;th&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;id_title&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;th&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;td&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;input&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;id_title&amp;quot;&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;title&amp;quot;&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;text&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;td&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;tr&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can even see this done with initial values in the Django docs: &lt;a class="reference external" href="https://docs.djangoproject.com/en/1.5/ref/forms/api/#django.forms.Form.initial"&gt;https://docs.djangoproject.com/en/1.5/ref/forms/api/#django.forms.Form.initial&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="forms-are-just-python-constructs"&gt;
&lt;h2&gt;Forms are &amp;quot;just&amp;quot; Python constructs.&lt;/h2&gt;
&lt;p&gt;I believe it was &lt;a class="reference external" href="https://twitter.com/alex_gaynor"&gt;Alex&lt;/a&gt; &lt;a class="reference external" href="http://alexgaynor.net/"&gt;Gaynor&lt;/a&gt; who said back in 2008 that Django forms were &amp;quot;just&amp;quot; Python constructs. He's right:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;myapp.forms&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MyForm&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;# class&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;MyForm&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="err"&gt;&amp;#39;&lt;/span&gt;&lt;span class="nc"&gt;myapp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MyForm&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;# object&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MyForm&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;myapp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MyForm&lt;/span&gt; &lt;span class="nb"&gt;object&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="mh"&gt;0x1023f1450&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;# iterable&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BoundField&lt;/span&gt; &lt;span class="nb"&gt;object&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="mh"&gt;0x102495990&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;title&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;# dictionary-like&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;title&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;django&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt; &lt;span class="nb"&gt;object&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="mh"&gt;0x1024a17d0&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Understanding the structure of Django forms is really useful. This structure is what allows the modification mechanism that I described in my &lt;a class="reference external" href="http://pydanny.com/overloading-form-fields.html"&gt;previous post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We don't have to stop in just the &lt;tt class="docutils literal"&gt;forms.py&lt;/tt&gt; module. You can also modify forms in views (either the classic &lt;tt class="docutils literal"&gt;views.py&lt;/tt&gt; module or in whatever API library you might be using):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.shortcuts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;redirect&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.views.generic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FormView&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyFormView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FormView&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;form_class&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MyForm&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;form_class&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;form_class&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_form_kwargs&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;favorite_icecream&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ChoiceField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;What is your favorite flavor from this list?&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Chocolate&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Vanilla&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Berry&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
            &lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RadioSelect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;form_valid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c"&gt;# Get user&amp;#39;s favorite ice cream.&lt;/span&gt;
        &lt;span class="c"&gt;# You can do anything you want with it&lt;/span&gt;
        &lt;span class="n"&gt;favorite_icecream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cleaned_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;favorite_icecream&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="c"&gt;# return the anticipated redirect&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;home&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you can see, with an understanding of basic Python types and some experience with Django forms you can become very creative in applications of forms. Please keep in mind that the devil is in the details, and overly creative use of forms (or anything) is a road you should carefully tread. It's always good to remember that simplicity is best and that the goal isn't to just write code, but to write maintainable code.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="forms-validate-dictionaries"&gt;
&lt;h2&gt;Forms validate dictionaries.&lt;/h2&gt;
&lt;p&gt;One of the primary functions of any HTTP-friendly form libraries is validating dictionary-like data objects. HTTP query strings are key/value structures and in order to avoid corruption in the persistence layer of any project, regardless of framework or language, validation needs to occur.&lt;/p&gt;
&lt;p&gt;During it's request/response cycle Django converts &lt;tt class="docutils literal"&gt;HTTP POST&lt;/tt&gt; (and &lt;tt class="docutils literal"&gt;HTTP GET&lt;/tt&gt;) objects into something called a &lt;tt class="docutils literal"&gt;QueryDict&lt;/tt&gt;, which is an merely an extended Django dictionary. See the comments in the code example below for proof:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;logging&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.http&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;HttpResponse&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.http.request&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;QueryDict&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.utils.datastructures&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MultiValueDict&lt;/span&gt;

&lt;span class="n"&gt;logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__main__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;my_form_view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="c"&gt;# logs True because request.POST is an instance of QueryDict&lt;/span&gt;
        &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;QueryDict&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="c"&gt;# logs True because QueryDict is a dictionary&lt;/span&gt;
        &lt;span class="nb"&gt;issubclass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;QueryDict&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;HttpResponse&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is all fine and good, but what does it mean for developers trying to solve problems? Well, it means that Django forms serve quite handily as a means for validation of dictionaries:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;myapp.forms&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MyForm&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;good_form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MyForm&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;title&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Two Scoops of Django&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;good_form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_valid&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="bp"&gt;True&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;good_form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;errors&lt;/span&gt;
&lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;bad_form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MyForm&lt;/span&gt;&lt;span class="p"&gt;({})&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;bad_form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_valid&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="bp"&gt;False&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;bad_form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;errors&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;title&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;u&amp;#39;This field is required.&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The power of this can't be understated. In fact, I'll be exploring this particular facet of Django forms more in at least one upcoming blog post.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="epilogue"&gt;
&lt;h2&gt;Epilogue&lt;/h2&gt;
&lt;p&gt;ModelForms adds at least three more bullets...&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;ModelForms render Model fields as HTML&lt;/li&gt;
&lt;li&gt;ModelForms automatically choose validators based off of Model field definitions.&lt;/li&gt;
&lt;li&gt;ModelForms save dictionaries to SQL tables.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;... and I'll be touching on them in the future.&lt;/p&gt;
&lt;/div&gt;
</summary><category term="python"></category><category term="django"></category><category term="forms"></category><category term="class-based-views"></category></entry><entry><title>Overloading Django Form Fields</title><link href="http://pydanny.com/overloading-form-fields.html" rel="alternate"></link><updated>2013-03-27T09:00:00-07:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2013-03-27:overloading-form-fields.html</id><summary type="html">&lt;p&gt;One of the patterns we get positive feedback for mentioning in our &lt;a class="reference external" href="https://django.2scoops.org/"&gt;book&lt;/a&gt; is &lt;strong&gt;overloading form fields&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The problem this pattern handles is the use case of when we have a model with a field(s) that allows for blank values, how do we force users to enter values?&lt;/p&gt;
&lt;p&gt;For example, assuming the following model:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# myapp/models.py&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IntegerField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;profession&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;bio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TextField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;How do we make all those fields (name, age, profession, bio) required without modifying the database?&lt;/p&gt;
&lt;p&gt;This is the way I used to do it:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# myapp/forms.py&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MyModel&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyModelForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ModelForm&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IntegerField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;profession&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;bio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TextField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MyModel&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;See the problems with this approach?&lt;/p&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;MyModelForm&lt;/tt&gt; is nearly a copy of &lt;tt class="docutils literal"&gt;MyModel&lt;/tt&gt;, and was in fact created by copy/pasting model and then modifying it. In software engineering parlance, it violates the principal of Don't Repeat Yourself (&lt;a class="reference external" href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself"&gt;DRY&lt;/a&gt;) and is fertile ground for introducing bugs.&lt;/p&gt;
&lt;div class="section" id="mymodelform-has-a-bug"&gt;
&lt;h2&gt;&lt;tt class="docutils literal"&gt;MyModelForm&lt;/tt&gt; has a bug!&lt;/h2&gt;
&lt;p&gt;Can you spot the bug?&lt;/p&gt;
&lt;p&gt;The code example below illuminates where I purposefully/gleefully placed an error:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="c"&gt;# 50 character database field&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyModelForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ModelForm&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="c"&gt;# Most people don&amp;#39;t write tests to check for field length.&lt;/span&gt;
    &lt;span class="c"&gt;# 100 character form field - probably not spotted until deployed.&lt;/span&gt;
    &lt;span class="c"&gt;# Easy error to make when violating DRY since the model can change&lt;/span&gt;
    &lt;span class="c"&gt;#   and leave the form definition behind.&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Bugs like this happen either because developers are human and make mistakes, or because the model evolves over time and the forms are left behind. This is a serious maintenance issue, and one that will bite you or the developers who end up maintaining code you've written.&lt;/p&gt;
&lt;p&gt;Can you spot the second bug? ;-)&lt;/p&gt;
&lt;p&gt;How do we fix this?&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="a-better-way"&gt;
&lt;h2&gt;A Better Way&lt;/h2&gt;
&lt;p&gt;In instantiated Django forms, fields are kept in a dict-like object. Which means, instead of writing forms in a way that duplicates the model, a better way is to explicitly modify only what we want to modify:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MyModel&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyModelForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ModelForm&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MyModelForm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c"&gt;# Making name required&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;required&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;age&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;required&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;bio&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;required&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;profession&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;required&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;

    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MyModel&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;div class="section" id="other-field-attributes"&gt;
&lt;h3&gt;Other field attributes&lt;/h3&gt;
&lt;p&gt;This isn't just limited to the &lt;tt class="docutils literal"&gt;required&lt;/tt&gt; attribute. It can also be applied to &lt;tt class="docutils literal"&gt;help_text&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;label&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;choices&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;widgets&lt;/tt&gt;, or any other form field attribute:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MyModel&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyModelForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ModelForm&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MyModelForm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c"&gt;# snip the other fields for the sake of brevity&lt;/span&gt;
        &lt;span class="c"&gt;# Adding content to the form&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;profession&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;help_text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Job title here&amp;quot;&lt;/span&gt;

    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MyModel&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="try-it-with-inheritance"&gt;
&lt;h3&gt;Try it with Inheritance!&lt;/h3&gt;
&lt;p&gt;We can even do this with inheritance:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BaseEmailForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EmailField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Email&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;email2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EmailField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Email 2&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;clean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cleaned_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;email&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;email2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cleaned_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;email2&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;email2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ValidationError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Emails don&amp;#39;t match&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cleaned_data&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ContactForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseEmailForm&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ContactForm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;email2&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Confirm your email&amp;quot;&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;email2&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;help_text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;We want to be sure!&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="summary"&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;From the perspective of general software development, it's always a good thing to avoid repeating yourself. This might seem like as much or in some cases even more typing, but it's a lot better than making an embarrassing/costly mistake.&lt;/p&gt;
&lt;p&gt;From the perspective of a Python developer our approach more closely matches the &lt;a class="reference external" href="http://www.python.org/dev/peps/pep-0020/"&gt;Zen of Python&lt;/a&gt;. This is because we only modify the field properties that need to be modified, the approach specified is more explicit.&lt;/p&gt;
&lt;p&gt;Today's reading is Matt Harrison's &lt;a class="reference external" href="http://www.amazon.com/Guide-Learning-Iteration-Generators-ebook/dp/B007JR4FCQ/?ie=UTF8&amp;amp;qid=1364400929&amp;amp;sr=1-5&amp;amp;tag=cn-001-20"&gt;Guide to Learning Iteration and Generators in Python&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
</summary><category term="python"></category><category term="django"></category><category term="forms"></category></entry><entry><title>Beginner's Guide to PyCon 2013 Part III</title><link href="http://pydanny.com/beginners-guide-pycon-2013-part-3.html" rel="alternate"></link><updated>2013-03-10T23:50:00-07:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2013-03-10:beginners-guide-pycon-2013-part-3.html</id><summary type="html">&lt;p&gt;This is Part III in a series of blog posts about &lt;a class="reference external" href="https://us.pycon.org/2013/"&gt;PyCon US 2013&lt;/a&gt;. The goal is to provide a handy reference guide for first time attendees of the world's largest &lt;a class="reference external" href="http://python.org"&gt;Python&lt;/a&gt; conference.  &lt;a class="reference external" href="http://pydanny.com/beginners-guide-pycon-2013-part-1.html"&gt;Part I&lt;/a&gt; was mostly about &lt;a class="reference external" href="https://us.pycon.org/2013/schedule/tutorials/"&gt;tutorials&lt;/a&gt;, &lt;a class="reference external" href="http://pydanny.com/beginners-guide-pycon-2013-part-2.html"&gt;Part II&lt;/a&gt; was mostly about the first day of talks, this third post in the series will be about the second day of talks.&lt;/p&gt;
&lt;div class="section" id="early-saturday-morning"&gt;
&lt;h2&gt;Early Saturday Morning&lt;/h2&gt;
&lt;p&gt;The &lt;a class="reference external" href="https://us.pycon.org/2013/5k/"&gt;PyCon 5K Charity Fun Run&lt;/a&gt; begins at 7 AM. Registration for this event is seperate from PyCon, and all proceeds go to the John Hunter Memorial Fund and the American Cancer Society.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="saturday-morning"&gt;
&lt;h2&gt;Saturday Morning&lt;/h2&gt;
&lt;p&gt;After breakfast ends at 8:30 am, don't miss 30 minutes of lightning talks!&lt;/p&gt;
&lt;p&gt;Then get ready as noted Python experts and proven speakers Jessica McKellar and Raymond Hettiger deliver keynotes to remember. They've changed communities and lives with the speeches given around the world.&lt;/p&gt;
&lt;div class="section" id="am-talks"&gt;
&lt;h3&gt;10:50 AM talks&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/83/"&gt;Getting started with automated testing&lt;/a&gt; (Carl Meyer) - This talk will get you moving into good test automation practices, and is presented by one of the maintainers of Django, pip, and virtualenv.&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/129/"&gt;5 powerful pyramid features&lt;/a&gt; (Carlos de la Guardia) - Pyramid is a minimalist, modular web framework that encourages excellent coding patterns. Carlos will give you a tour of some of the great features that makes this such a powerful tool for application development.&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/120/"&gt;So Easy You Can Even Do It in JavaScript: Event-Driven Architecture for Regular Programmers&lt;/a&gt; (Glyph) - Asynchronous frameworks are said to be the new hotness, but Python's Twisted framework has been around for over 11 years. The creator of the project isn't just a master developer, but an illuminating speaker capable of explaining the most sophisticated concepts in a beginner friendly way.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="id1"&gt;
&lt;h3&gt;11:30 AM talks&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/75/"&gt;Who’s there? - Home Automation with Arduino/RaspberryPi&lt;/a&gt; (Rupa Dachere) - Automate your home with Python! Learn how to use a Arduino or RaspberryPi to notify you by SMS that packages have arrived.&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/41/"&gt;Copyright and You&lt;/a&gt; (Frank Siler) - Using and writing open source software involves a basic understanding of licensing and understanding of copyright law. The presenter, a licensed attorney, will cover the fundamentals needed to work safely in the open source world.&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/104/"&gt;Scaling community diversity outreach&lt;/a&gt; (Asheesh Laroia, Jessica McKellar, Dana Bauer, Daniel Choi) - Leaders of community groups around the USA will explain how they get people of all backgrounds not just coding, but helping each other in order to grow the diversity of the technical community.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="pm-talks"&gt;
&lt;h3&gt;12:10 PM talks&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/114/"&gt;Why you should use Python 3 for text processing&lt;/a&gt; (David Mertz) - The presenter literally wrote the book on text processing using Python (many of his techniques have since made their way into core Python). In this often technical talk he explains why Python 3 is the tool you should be using.&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/42/"&gt;What teachers really need from us&lt;/a&gt; (Selena Deckelman) - Noted speaker and developer, Selena Deckelman, explains what the what the Python community can do to help K-12 teachers need to forward programming education.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="saturday-lunch-12-40-pm"&gt;
&lt;h2&gt;Saturday Lunch (12:40 PM)&lt;/h2&gt;
&lt;p&gt;Food! Chow down! Don't forget the meal tickets you picked up during registration.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="pyladies-lunch-at-pycon-12-30-pm"&gt;
&lt;h2&gt;PyLadies Lunch at PyCon (12:30 PM)&lt;/h2&gt;
&lt;p&gt;PyLadies have organized to host a lunch for &lt;strong&gt;women&lt;/strong&gt; attending the conference who love Python, or who want to learn more about Python or PyLadies. While the event is filled up, you can &lt;a class="reference external" href="http://www.eventbrite.com/event/5227826570"&gt;register to get on the waitlist&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="saturday-afternoon"&gt;
&lt;h2&gt;Saturday Afternoon&lt;/h2&gt;
&lt;div class="section" id="id2"&gt;
&lt;h3&gt;1:40 PM talks&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/56/"&gt;Designers + Developers: Collaborating on your Python project&lt;/a&gt; (Julia Elman, Mark Lavin) - Like many developers I've had good and bad experiences with designers. We both play our critical roles in projects, and it will be good to hear their presentation on how to collaborate and work in tandem as part of a team.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="id3"&gt;
&lt;h3&gt;1:55 PM talks&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/122/"&gt;Teaching with the IPython Notebook&lt;/a&gt; (Matt Davis) - The IPython Notebook is an unbelievably incredible tool. Imagine a Python shell that allows you to embed images and graphs right into the REPL. Designed by and for scientists, the IPython Notebook is useful for developers of all levels. You have to see it in action to believe it!&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="id4"&gt;
&lt;h3&gt;2:35 PM talks&lt;/h3&gt;
&lt;p&gt;This is a rough spot because there are four really beginner good talks by four great speakers happening at the same time. Since all of this are going to be wonderful presentations, I'm labeling them all as 'must-see'.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/141/"&gt;Who are we? A sociological analysis of the indigenous Python tribe&lt;/a&gt; (Jackie Kazil) - Journalist and computer scientist at the Library of Congress, Jackie Kazil uses her amazing skills to analyze the Python community's code bases across thousands of projects to determine where we've been as a people and we are going in the future. If you want to see how an expert analyzes trends in the Python-verse, this is a talk that can't be missed!&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/67/"&gt;Building full-stack scientific applications in Python&lt;/a&gt; (Luke Lee) - Did you know that Python is used in high performance scientific applications? Tools like SciPy and NumPy are built on top of very robust, optimized C and Fortran libraries. Luke will cover their use and also how to present the data using tools like PyQt. If you are into big data, you can't miss this talk!&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/146/"&gt;Customizing the Django Admin: The How and the Why&lt;/a&gt; (Lakshman Prasad) - Following my talk is a deep dive into Django's famous admin interface. I was fortunate enough to get a sneak preview of the talk and I can say with confidence this is going to be an incredible presentation. Don't miss it!&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/92/"&gt;Location, Location, Location&lt;/a&gt; (Julia Grace) - Django, via the GeoDjango toolkit has amazing support for building GIS based applications. Julia's an experienced developer and great speaker, making this a can't miss talk!&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="id5"&gt;
&lt;h3&gt;3:15 PM talks&lt;/h3&gt;
&lt;p&gt;There isn't a beginner-focused talk in this slot, so I'm going to make this the &lt;em&gt;roller-coaster&lt;/em&gt; slot. In other words, I'm going to steer you to the most intensely advanced talk at this time. Attend, buckle in the safety harness, and drink in the extreme knowledge!&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/80/"&gt;Making Apache suck less for hosting Python web applications&lt;/a&gt; (Graham Dumpleton) - It is not hard to find developers who will tell you that Apache sucks for running Python web applications. Is there a valid basis to such claims or have they simply been misguided by the views of others? Well, Graham understands how Python serves up web pages and won't hold back on technical detail.&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/130/"&gt;Numba: A Dynamic Python compiler for Science&lt;/a&gt; (Travis Oliphant, Siu Kwan Lam, Mark Florisson) - Numba is a compiler for Python syntax that uses the LLVM library and llvmpy to convert specifically decorated Python functions to machine code at run-time. It allows Python syntax to be used to do scientific and numerical computing that is blazing fast yet tightly integrated with the CPython run-time.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="talk"&gt;
&lt;h3&gt;4:15 talk&lt;/h3&gt;
&lt;p&gt;For this time period there is a single talk specifically aimed at beginners. There are some other useful talks around this time, but they are aimed at educators and integrators over beginners.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/74/"&gt;Crypto 101&lt;/a&gt; (Laurens Van Houtven) - Cryptography is a tricky subject, and the goal of this 4:15 PM talk isn't to turn attendees into cryptography experts. Instead, you'll have a basic understanding of how some common systems compare, and also a sense for detecting and exposing snake oil.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="pm-talk"&gt;
&lt;h3&gt;4:30 PM talk&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/102/"&gt;Getting Python and Django Through Your Java Shop Front Door (with Jython)&lt;/a&gt; (Frank Wierzbicki) - Work in a Java shop and want to bring in Python? Learn how to do it using Jython, the Python implementation that works in the JVM!&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="id6"&gt;
&lt;h3&gt;5:10 PM talks&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/138/"&gt;MTO On Blast: Using Python's Natural Language Toolkit to Model Gossip Blogs&lt;/a&gt; (Robert Elwell) - Python's powerful Natural Language Toolkit will be featured as the presenter gives an overview of Natural Language Processing.&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/103/"&gt;What is the Python Software Foundation?&lt;/a&gt; (Brian Curtin) - This talk aims to engage us in thinking about what it takes to further Python. Whether it's an idea of code, community, or otherwise, it will jumpstart us into helping the very positive community that has brought us together for the amazing event that is PyCon.&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/128/"&gt;Asset Management in Python&lt;/a&gt; (Robert Kluin, Beau Lyddon) - Coffeescript, Less, SASS, and all those other exciting new front end asset tools can be a challenge to deploy when doing web development in tools like Django, Flask, and Pyramid. The presenters will introduce &lt;em&gt;webassets&lt;/em&gt;, a library designed to make deployment of assets quick and easy.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="evening-activities"&gt;
&lt;h2&gt;Evening Activities&lt;/h2&gt;
&lt;p&gt;Saturday night will be the evening of a huge number of fantastic fun. Two items of note (more to come):&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/sponsors/charityauction/"&gt;The PyCon Charity Auction&lt;/a&gt; (6:30 PM+) - Along with Disney Animation Studios and many others, Audrey and I are contributing! In fact, we're submitting a one of a kind, preview copy of the upcoming print edition of &lt;a class="reference external" href="http://django.2scoops.org"&gt;Two Scoops of Django: Best Practices for Django 1.5&lt;/a&gt;!&lt;/li&gt;
&lt;li&gt;The famously unrecorded Testing in Python Birds of a Feathers event.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="part-iv"&gt;
&lt;h2&gt;Part IV&lt;/h2&gt;
&lt;p&gt;Stay tuned for Part IV of this series where I cover the third day of talks best suited for new Python developers!&lt;/p&gt;
&lt;/div&gt;
</summary><category term="python"></category><category term="django"></category><category term="pycon"></category><category term="pycon-2013-guide"></category></entry><entry><title>PyCon Tutorial: Wiring Up Django Packages</title><link href="http://pydanny.com/wiring-up-django-packages-pycon2013.html" rel="alternate"></link><updated>2013-03-08T11:00:00-08:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2013-03-08:wiring-up-django-packages-pycon2013.html</id><summary type="html">&lt;div class="section" id="you-just-finished-the-django-tutorial-what-now"&gt;
&lt;h2&gt;You just finished the &lt;a class="reference external" href="https://docs.djangoproject.com/en/1.5/intro/tutorial01/"&gt;Django tutorial&lt;/a&gt;. What now?&lt;/h2&gt;
&lt;p&gt;You learn how to Wire Up Django Packages!&lt;/p&gt;
&lt;p&gt;This is a 3+ hour &lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/11/"&gt;PyCon tutorial&lt;/a&gt; on March 14th at 1:20pm, in Santa Clara California at &lt;a class="reference internal" href="#pycon"&gt;PyCon&lt;/a&gt; US.&lt;/p&gt;
&lt;p&gt;In alphabetical order, the instructors:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://audreymroy.com/"&gt;Audrey Roy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Daniel Greenfeld (myself)&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://gettingstartedwithdjango.com/"&gt;Kenneth Love&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div class="section" id="tutorial-description"&gt;
&lt;h2&gt;Tutorial Description&lt;/h2&gt;
&lt;p&gt;Django is part of an ecosphere of over 20,000 packages, which can be leveraged to great effect. This tutorial will teach the evaluation, use, and extension of third party Python and Django applications in your projects. This tutorial will be a lecture with a lot of detailed and annotated code examples.&lt;/p&gt;
&lt;p id="pycon"&gt;This tutorial does much more than instruct on how to wire in third party packages, it also instructs on Django/Python best practices such as PEP-8, loose coupling, good database design, clarity of concept, and workable patterns.&lt;/p&gt;
&lt;p&gt;Material covered:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Evaluating packages using Django Packages, PyPI, Read the Docs, and other sources.&lt;/li&gt;
&lt;li&gt;Must-include packages for every project&lt;/li&gt;
&lt;li&gt;Class-based Views&lt;/li&gt;
&lt;li&gt;Forms&lt;/li&gt;
&lt;li&gt;Models&lt;/li&gt;
&lt;li&gt;Caching&lt;/li&gt;
&lt;li&gt;Comments&lt;/li&gt;
&lt;li&gt;Templates&lt;/li&gt;
&lt;li&gt;Admin&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="format"&gt;
&lt;h2&gt;Format&lt;/h2&gt;
&lt;p&gt;This will be a lecture with detailed and annotated code examples. Attendees will have a chance per section to ask questions and submit alternative packages of their own.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="prerequisites"&gt;
&lt;h2&gt;Prerequisites&lt;/h2&gt;
&lt;p&gt;Practical or professional experience with Django is recommended, but the material covered will be useful to anyone familiar with Python who has completed the Django tutorial.&lt;/p&gt;
&lt;p&gt;If you are a new Python developer, we suggest in addition to our course you sign up for some of the introductory Python tutorials taught at PyCon next week. If that is not possible or you wish reinforcement, please dive into one of the following resources before you attend:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://learnpythonthehardway.org/"&gt;http://learnpythonthehardway.org/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.amazon.com/Treading-Python-Volume-1-ebook/dp/B00639H0AK/ref=sr_1_4?s=digital-text&amp;amp;ie=UTF8&amp;amp;qid=1362769305&amp;amp;sr=1-4&amp;amp;keywords=matt+harrison&amp;amp;tag=cn-001-20"&gt;Treading on Python&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.amazon.com/Think-Python-Allen-B-Downey/dp/144933072X/ref=sr_1_1?ie=UTF8&amp;amp;qid=1362768936&amp;amp;sr=8-1&amp;amp;keywords=think+in+python&amp;amp;tag=cn-001-20"&gt;Think in Python&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.amazon.com/Python-Kids-Playful-Introduction-Programming/dp/1593274076/ref=sr_1_8?s=books&amp;amp;ie=UTF8&amp;amp;qid=1362769005&amp;amp;sr=1-8&amp;amp;keywords=python+programming&amp;amp;tag=cn-001-20"&gt;Python for Kids&lt;/a&gt; (meant for kids but good for beginning developers of all ages)&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="registration"&gt;
&lt;h2&gt;Registration&lt;/h2&gt;
&lt;p&gt;Space is filling up quickly, hurry up and register!&lt;/p&gt;
&lt;p&gt;Registration for this event is $150 and occurs at  &lt;a class="reference external" href="https://us.pycon.org/2013/registration/register/"&gt;https://us.pycon.org/2013/registration/register/&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Note: Registration for the conference part of PyCon is closed, but tutorials are still open.&lt;/p&gt;
&lt;/div&gt;
</summary><category term="python"></category><category term="django"></category><category term="pycon"></category></entry><entry><title>We are not using PayPal</title><link href="http://pydanny.com/we-are-not-using-paypal.html" rel="alternate"></link><updated>2013-03-02T09:00:00-08:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2013-03-02:we-are-not-using-paypal.html</id><summary type="html">&lt;p&gt;In January &lt;a class="reference external" href="http://audreymroy.com"&gt;Audrey Roy&lt;/a&gt; and I launched a &lt;a class="reference external" href="http://django.2scoops.org"&gt;book&lt;/a&gt; about Django called &lt;a class="reference external" href="http://django.2scoops.org"&gt;Two Scoops of Django: Best Practices for Django 1.5&lt;/a&gt;. We decided to not use PayPal. Here's why:&lt;/p&gt;
&lt;div class="section" id="open-source-events-get-burned-by-paypal"&gt;
&lt;h2&gt;Open Source Events Get Burned By PayPal&lt;/h2&gt;
&lt;p&gt;PayPal has a long, sordid history of freezing the accounts of Python related conferences and events around the world. In fact, this article was born out of the fact &lt;a class="reference external" href="http://blog.djangocircus.com/post/43806402173/back-on-track"&gt;DjangoCon Europe 2013 had its PayPal account frozen&lt;/a&gt;. In the past, &lt;a class="reference external" href="http://2012.djangocon.eu/"&gt;DjangoCon Europe 2012&lt;/a&gt;, Plone Conferences 2008, 2011, and at least one PyCon Australia dealt with the same PayPal problem (DjangoCon 2013 was forewarned and took measures to protect itself). We also have unconfirmed reports of other Python and Django events also running into problems with PayPal freezing accounts. Going with just confirmed conferences having issues with PayPal, this is a combined total of assets in excess of over US$100,000 dollars.&lt;/p&gt;
&lt;p&gt;It's not just a Python issue either, it's an issue that &lt;a class="reference external" href="http://conferencesburnedbypaypal.tumblr.com/"&gt;strikes other open source languages and tools&lt;/a&gt;. It's at the point now where &lt;a class="reference external" href="http://aralbalkan.com/3898/"&gt;conference organizers don't trust PayPal&lt;/a&gt; and make a point telling each other to use alternative payment gateways.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="fear-shame-and-paypal"&gt;
&lt;h2&gt;Fear, Shame, and PayPal&lt;/h2&gt;
&lt;p&gt;The terrifying thing to consider is that I suspect that the number of technical conferences affected by PayPal freezes is much, much larger. My reasoning is that &lt;strong&gt;most conferences keep quiet about it&lt;/strong&gt; because &lt;strong&gt;they're afraid that raising a fuss will annoy PayPal's anti-fraud division&lt;/strong&gt;. Let's also face the fact that &lt;strong&gt;most people feel ashamed when bank accounts they are responsible for get frozen&lt;/strong&gt;, so probably don't publicize the issue.&lt;/p&gt;
&lt;p&gt;The usual way conferences deal with these lockouts is conference organizers beg and borrow from friends, family, take second mortgages, local banking institutions, and pray that PayPal will eventually free their account. When you deal with a hostile, inaccessible payment gateway who won't let you provide for the hundreds or even thousands of people who paid you their hard earned money, it's the only way to get by.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="the-needs-of-paypal-s-anti-fraud-division"&gt;
&lt;h2&gt;The 'Needs' of PayPal's Anti-Fraud Division&lt;/h2&gt;
&lt;p&gt;While I could respect the needs of PayPal's anti-fraud division when dealing with non-fungible products like ticket sales, it's &lt;strong&gt;simply unacceptable&lt;/strong&gt; that prominent conferences for open source projects are treated this way.&lt;/p&gt;
&lt;p&gt;The software represented by these conferences drives the modern e-commerce world, including the myriad of systems that use PayPal to process sales. Yet PayPal continues to burn open source conferences year after year, and we've never heard of any conference outreach by their so-called 'developer evangelists' when a conference's account is frozen.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="legal-recourse-against-paypal-is-folly"&gt;
&lt;h2&gt;Legal recourse against PayPal is folly&lt;/h2&gt;
&lt;p&gt;Ask any lawyer and they'll basically say against PayPal you have no options. PayPal has an army of lawyers and in most places isn't a bank, meaning your course of action is constrained from the beginning by your agreeing to PayPal's Terms of Service (TOS). Also, in the United States, their TOS prevents you from joining a class action lawsuit against them. Whether or not that TOS clause is enforceable in court, the fact that it is in their TOS greatly reduces any faith I might have had in them because it paints a picture of a company hostile to my needs.&lt;/p&gt;
&lt;p&gt;In talking to authors and entrepreneurs, we've just heard (and read) too many horror stories. For merchants of non-fungible goods such as digital goods like the e-book I co-authored, PayPal seems even less trustworthy.&lt;/p&gt;
&lt;p&gt;Which means using PayPal places us at an unacceptable risk. We simply don't have the deep pockets to deal with PayPal freezing our funds for sales lost from a more reliable distribution system such as &lt;a class="reference external" href="https://stripe.com"&gt;Stripe&lt;/a&gt; that powers our sales through &lt;a class="reference external" href="https://gumroad.com"&gt;Gumroad&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="it-is-wrong-to-use-paypal"&gt;
&lt;h2&gt;It is Wrong to Use PayPal&lt;/h2&gt;
&lt;p&gt;Considering PayPal's unacceptable behavior in regards to the open source community I love and merchants who try to work in their system, I feel it is wrong to support PayPal. Audrey agrees, and so our policy of not using PayPal to sell the book is set.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="paypal-is-at-risk"&gt;
&lt;h2&gt;PayPal is at Risk&lt;/h2&gt;
&lt;p&gt;There was a day when Microsoft had what seemed to be an unassailable lock on the commercial software world. On many levels, Microsoft is a shadow of its former self, and I contend it wasn't just Apple's competition. Instead, Microsoft's contempt for their own customers and the developer community hurt them just as much.&lt;/p&gt;
&lt;p&gt;PayPal is on the same path of self-destruction. The've gone from the &lt;a class="reference external" href="http://www.amazon.com/The-PayPal-Wars-Battles-Planet/dp/0977898431/?tag=cn-001-20"&gt;scrappy company&lt;/a&gt; helping people grow their business to the monolithic overlord that kills businesses and well-meaning events.&lt;/p&gt;
&lt;p&gt;PayPal's demise won't happen this year, or the next, but every time they damage their customer base and the developer community it's another nail in the coffin. I submit that unless PayPal changes its ways, within 5 years PayPal will be a shadow of its former self as the army of growing competitors such as &lt;a class="reference external" href="https://stripe.com"&gt;Stripe&lt;/a&gt;, &lt;a class="reference external" href="https://www.balancedpayments.com/"&gt;Balanced Payments&lt;/a&gt;, &lt;a class="reference external" href="https://www.wepay.com/"&gt;wepay&lt;/a&gt;, and &lt;a class="reference external" href="https://www.payoneer.com/"&gt;Payoneer&lt;/a&gt; expands their availability and options around the world.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="what-paypal-can-do-for-conferences"&gt;
&lt;h2&gt;What PayPal Can Do for Conferences&lt;/h2&gt;
&lt;p&gt;PayPal does have to worry about ticket sales for bogus events, since that  separates people from their money, but identifying real conferences is easy:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;PayPal developer evangelists and community managers need to track every valid developer event in the world. It's the job of people in these roles to have the connections and subject matter expertise to identify real events from fake ones.&lt;/li&gt;
&lt;li&gt;PayPal needs to sponsor these events. Why? See point #3.&lt;/li&gt;
&lt;li&gt;PayPal's anti-fraud division needs to be informed that any PayPal sponsored event is off-limits.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="section" id="what-paypal-can-do-for-small-business"&gt;
&lt;h2&gt;What PayPal Can Do for Small Business&lt;/h2&gt;
&lt;p&gt;PayPal has its developer evangelists, community managers, and marketing departments working hard. However, at the end of the day, if you treat your customers with disrespect and a lack of trust, none of that matters. Bad press and market forces will see their revenues drop as customers will migrate to solutions that are more trustworthy and less antagonistic.&lt;/p&gt;
&lt;p&gt;I believe that PayPal needs to revise how its anti-fraud division communicates with people who have frozen accounts. They need to change the adversarial pose they take with their own customers to one that is collaborative.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="note"&gt;
&lt;h2&gt;Note&lt;/h2&gt;
&lt;p&gt;If this makes you angry as it did me, take a deep breath and step back. I've found &lt;a class="reference external" href="http://www.amazon.com/gp/product/0807012394/ref=as_li_ss_tl?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=0807012394&amp;amp;linkCode=as2&amp;amp;tag=cn-001-20"&gt;this book&lt;/a&gt; recommended by my friend Randall Degges useful in getting back on track and staying productive.&lt;/p&gt;
&lt;/div&gt;
</summary><category term="twoscoops"></category><category term="python"></category><category term="django"></category><category term="paypal"></category><category term="rant"></category></entry><entry><title>Two Scoops of Django 1.5 Beta Released</title><link href="http://pydanny.com/two-scoops-beta-released.html" rel="alternate"></link><updated>2013-02-28T15:00:00-08:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2013-02-28:two-scoops-beta-released.html</id><summary type="html">&lt;p&gt;After thirty four days of hard work, &lt;a class="reference external" href="http://audreymroy.com"&gt;Audrey Roy&lt;/a&gt; and I are proud to announce that we've released the &lt;strong&gt;beta&lt;/strong&gt; of &lt;a class="reference external" href="http://django.2scoops.org"&gt;Two Scoops of Django: Best Practices for Django 1.5&lt;/a&gt;. It's been a monumental effort, a labor of love, and we hope you find our efforts worthy. You can buy it right now in e-book (PDF) form on the website: &lt;a class="reference external" href="http://django.2scoops.org"&gt;http://django.2scoops.org&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Two Scoops of Django: Best Practices for Django 1.5 is a compilation of best practices for the Django framework. Like any framework, Django has tips, tricks, and pitfalls that aren't documented in one place. Experienced developers know this stuff, but gleaning it off the Internet takes a lot of time. We decided to take everything we know and write it down.&lt;/p&gt;
&lt;p&gt;We stand of the shoulders of giants: We received advice from Django experts including a BDFL, Django core developers, and subject matter experts from around the world. Reader contributions from advanced and beginning developers have also shaped the book, and we can't thank enough those who gave us their insights.&lt;/p&gt;
&lt;a class="reference external image-reference" href="http://django.2scoops.org/"&gt;&lt;img alt="https://s3.amazonaws.com/twoscoops/img/tsd-cover-beta.png" class="align-center" id="two-scoops-of-django" src="https://s3.amazonaws.com/twoscoops/img/tsd-cover-beta.png" /&gt;&lt;/a&gt;
&lt;a name="features"&gt;&lt;/a&gt;&lt;div class="section" id="what-is-different-about-the-beta-release"&gt;
&lt;h2&gt;What is different about the beta release?&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Added 50+ pages of content while reducing the file size from 5.1 MB to 1.5 MB.&lt;/li&gt;
&lt;li&gt;Added list of tables, list of figures, and an index.&lt;/li&gt;
&lt;li&gt;Dramatically improved the chapters on security, testing, logging, admin, and many more.&lt;/li&gt;
&lt;li&gt;Added so many more code samples that even with the new example numbering system we lost count.&lt;/li&gt;
&lt;li&gt;Speaking of code examples, most of the code samples in the book are loaded directly out of fully tested projects.&lt;/li&gt;
&lt;li&gt;Incorporated the feedback of dozens of readers. Thank you so much for your contributions!&lt;/li&gt;
&lt;/ul&gt;
&lt;a name="what-do-i-get"&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="section" id="what-does-buying-the-beta-get-me"&gt;
&lt;h2&gt;What does buying the beta get me?&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Access the PDF version of the book.&lt;/li&gt;
&lt;li&gt;Access to the Kindle and ePub formats when we release the final.&lt;/li&gt;
&lt;li&gt;Access to final release of the book.&lt;/li&gt;
&lt;/ul&gt;
&lt;a name="alternative-formats"&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="section" id="why-aren-t-there-kindle-or-epub-versions-yet"&gt;
&lt;h2&gt;Why aren't there Kindle or ePub versions yet?&lt;/h2&gt;
&lt;p&gt;We want to support more formats, but won't do it poorly. It's going to take us at least several days to render the book in an alternative format that looks good. Since we both have multiple presentations at the upcoming &lt;a class="reference external" href="https://us.pycon.org/2013/"&gt;PyCon US&lt;/a&gt;, we simply don't have time to get it done.&lt;/p&gt;
&lt;a name="alpha-buyers"&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="section" id="if-i-bought-the-alpha-do-i-have-to-buy-the-beta"&gt;
&lt;h2&gt;If I bought the alpha do I have to buy the beta?&lt;/h2&gt;
&lt;p&gt;Alpha buyers get full access the beta. In fact, you should have already received an email with a link to the latest version. If that hasn't arrived, please email us at &lt;a class="reference external" href="mailto:2scoops&amp;#64;cartwheelweb.com"&gt;2scoops&amp;#64;cartwheelweb.com&lt;/a&gt;.&lt;/p&gt;
&lt;a name="beginners"&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="section" id="is-this-book-good-for-beginners"&gt;
&lt;h2&gt;Is this book good for beginners?&lt;/h2&gt;
&lt;p&gt;The response from beginning Django developers reading it has been &lt;strong&gt;unbelievably, overwhelmingly positive&lt;/strong&gt;. This is the book we wanted to have when we learned Django, and we're honored by the response the book has received.&lt;/p&gt;
&lt;p&gt;Since the book isn't a tutorial, we ask that before beginners purchase it, they &lt;a class="reference external" href="http://learnpythonthehardway.org/"&gt;learn the fundamentals of&lt;/a&gt; &lt;a class="reference external" href="http://www.amazon.com/Learn-Python-Hard-Way-Introduction/dp/0321884914/?ie=UTF8&amp;amp;tag=cn-001-20"&gt;Python&lt;/a&gt; and take the &lt;a class="reference external" href="https://docs.djangoproject.com/en/1.5/intro/tutorial01/"&gt;official Django tutorial&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;When beginners find sections of the book above their head, they do what everyone does when reading a technical reference: skip over challenging sections until they have enough grounding to understand.&lt;/p&gt;
&lt;p&gt;If any beginners are confused by our explanations, or have difficulties, please email us at &lt;a class="reference external" href="mailto:2scoops&amp;#64;cartwheelweb.com"&gt;2scoops&amp;#64;cartwheelweb.com&lt;/a&gt;. We'll do our best to answer your questions. Your issues provide invaluable insight into what we need to improve.&lt;/p&gt;
&lt;a name="experienced"&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="section" id="is-this-book-good-for-experienced-developers"&gt;
&lt;h2&gt;Is this book good for experienced developers?&lt;/h2&gt;
&lt;p&gt;We've done our best to provide worthwhile material for developers of all levels. In fact, a lot of intermediate to advanced developers have said they've found good things to use in our book. Many have also found that by using our book as a supplementary manual, it helps them their team work better.&lt;/p&gt;
&lt;a name="updates"&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="section" id="is-this-book-going-to-get-updated"&gt;
&lt;h2&gt;Is this book going to get updated?&lt;/h2&gt;
&lt;p&gt;Absolutely!&lt;/p&gt;
&lt;p&gt;During the &lt;strong&gt;alpha&lt;/strong&gt; we updated the book multiple times before knuckling down on the &lt;strong&gt;beta&lt;/strong&gt; rewrite. Even after the final version comes out, we'll continue to update the book. One of the advantages of self-published e-books is we have total control of content.&lt;/p&gt;
&lt;a name="print"&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="section" id="when-can-i-get-a-print-version"&gt;
&lt;h2&gt;When can I get a print version?&lt;/h2&gt;
&lt;p&gt;After a lot of consideration, we've decided to hold off on the print version of the book until what we call the &lt;a class="reference external" href="http://pydanny.com/two-scoops-beta-released.html#final"&gt;final&lt;/a&gt; release, which won't be released until after &lt;a class="reference external" href="https://us.pycon.org/2013/"&gt;PyCon US&lt;/a&gt;. We're very finicky and don't want buyers of the print version to have an unfinished book.&lt;/p&gt;
&lt;a name="tutorial"&gt;&lt;/a&gt;
&lt;a name="pycon"&gt;&lt;/a&gt;
&lt;a name="wiring-up-django-packages"&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="section" id="tutorial-pycon-are-you-going"&gt;
&lt;h2&gt;Tutorial? PyCon? Are you going?&lt;/h2&gt;
&lt;p&gt;Yes! We're going to be at PyCon next month!  We're giving the &lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/11/"&gt;Wiring Up Django Packages&lt;/a&gt; tutorial, and &lt;a class="reference external" href="http://brack3t.com/"&gt;Kenneth Love&lt;/a&gt; (of &lt;a class="reference external" href="http://gettingstartedwithdjango.com/"&gt;Getting Started with Django&lt;/a&gt; fame) is part of our team.&lt;/p&gt;
&lt;p&gt;While tickets to PyCon itself are sold out, you can still &lt;a class="reference external" href="https://us.pycon.org/2013/registration/register/"&gt;register for the tutorials&lt;/a&gt;.&lt;/p&gt;
&lt;a name="final"&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="section" id="when-is-the-book-s-final-release"&gt;
&lt;h2&gt;When is the book's final release?&lt;/h2&gt;
&lt;p&gt;The final release won't occur until after PyCon.&lt;/p&gt;
&lt;p&gt;Our plan for the final release of Two Scoops of Django: Best Practices for Django 1.5 is to focus on errata, alternative electronic formats, and the print version.&lt;/p&gt;
&lt;a name="bulk"&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="section" id="can-we-purchase-the-book-in-bulk"&gt;
&lt;h2&gt;Can we purchase the book in bulk?&lt;/h2&gt;
&lt;p&gt;We're working on a program to provide organizations the capability to purchase many e-copies and keep the recipients of the book updated constantly. We hope to have this ready in a few days.&lt;/p&gt;
&lt;a name="paypal"&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="section" id="can-i-buy-the-book-via-paypal"&gt;
&lt;h2&gt;Can I buy the book via PayPal?&lt;/h2&gt;
&lt;p&gt;No. I've answered in full &lt;a class="reference external" href="http://pydanny.com/we-are-not-using-paypal.html"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We're considering other non-credit card options to handle payment.&lt;/p&gt;
&lt;a name="known-issue-warnings"&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="section" id="known-issue-warnings"&gt;
&lt;h2&gt;Known Issue Warnings&lt;/h2&gt;
&lt;div class="section" id="copy-paste"&gt;
&lt;h3&gt;Copy/Paste&lt;/h3&gt;
&lt;p&gt;There are problems with copy/pasting of code from the PDF. The new build process is turning the code examples into some sort of image type of object, which explains the strange characters. We're working on it, but aren't sure how long the fix will take.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="android"&gt;
&lt;h3&gt;Android&lt;/h3&gt;
&lt;p&gt;On Android, if you try to open the PDF directly from the Gumroad download, you might get a &amp;quot;Cannot open file&amp;quot; error; however, if you navigate to the download location on your phone/tablet with a file browser (e.g. Samsung's &amp;quot;My Files&amp;quot;), you should be able to open the file from there. Gumroad is currently investigating the issue.&lt;/p&gt;
&lt;a name="errata"&gt;&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="where-should-i-send-errata-or-suggestions"&gt;
&lt;h2&gt;Where should I send errata or suggestions?&lt;/h2&gt;
&lt;p&gt;Please send errata to &lt;a class="reference external" href="mailto:2scoops&amp;#64;cartwheelweb.com"&gt;2scoops&amp;#64;cartwheelweb.com&lt;/a&gt;. We try to respond personally to every request.&lt;/p&gt;
&lt;/div&gt;
</summary><category term="twoscoops"></category><category term="python"></category><category term="django"></category><category term="audrey"></category><category term="pycon"></category></entry><entry><title>Beginner's Guide to PyCon 2013 Part II</title><link href="http://pydanny.com/beginners-guide-pycon-2013-part-2.html" rel="alternate"></link><updated>2013-01-23T16:00:00-08:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2013-01-23:beginners-guide-pycon-2013-part-2.html</id><summary type="html">&lt;p&gt;This is Part II in a series of blog posts about &lt;a class="reference external" href="https://us.pycon.org/2013/"&gt;PyCon US 2013&lt;/a&gt;. The goal is to provide a handy reference guide for first time attendees of the world's largest &lt;a class="reference external" href="http://python.org"&gt;Python&lt;/a&gt; conference. &lt;a class="reference external" href="http://pydanny.com/beginners-guide-pycon-2013-part-1.html"&gt;Part I&lt;/a&gt; was mostly about &lt;a class="reference external" href="https://us.pycon.org/2013/schedule/tutorials/"&gt;tutorials&lt;/a&gt;, this post will be about registration and the first day of talks.&lt;/p&gt;
&lt;div class="section" id="registration"&gt;
&lt;h2&gt;Registration&lt;/h2&gt;
&lt;p&gt;If you haven't done so yet, please &lt;a class="reference external" href="https://us.pycon.org/2013/registration/register/"&gt;register&lt;/a&gt; now. Last year PyCon sold out way in advance, and hundreds missed the event. Which is a shame, because the conference is awesome!&lt;/p&gt;
&lt;p&gt;Keep in mind that the money you spend on registration will go towards a very good thing. You see, after the costs for running PyCon are subtracted, the rest will go to the non-profit Python Software Foundation (&lt;a class="reference external" href="http://python.org/psf/"&gt;PSF&lt;/a&gt;). In addition to supporting the Python language itself, the PSF provides financial aid and grants for aspiring developers around the world. Which means the money you spend registering for PyCon will literally change people's lives. This isn't an idle exaggeration, this outreach has made a difference for you, me, and arguably the world. I would love to say more, but that's an article for another day...&lt;/p&gt;
&lt;p&gt;Alright, on to the talks!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="talk-attendance-guidelines"&gt;
&lt;h2&gt;Talk Attendance Guidelines&lt;/h2&gt;
&lt;p&gt;At PyCon, talks are either 30 or 45 long. They represent the best and brightest in both old hands in the community and rising stars. Some quick guidelines:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;strong&gt;Ask Questions!&lt;/strong&gt; If the speaker leaves time for questions at the end, &lt;a class="reference external" href="http://cecinestpasun.com/entries/i-can-haz-question-or-five/"&gt;go and ask&lt;/a&gt;!&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Shut the Laptop and Turn Off the Device.&lt;/strong&gt; It's disconcerting to give a speech to hundreds of people staring at their portable electronics and not responding to your banter. Unless you are using electronics to actively take notes on the talk, consider turning them off to look at the speaker.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Don't Heckle.&lt;/strong&gt; It's nerve wracking going up in front of hundreds of people live and tens of thousands on streaming video. Heckling is &lt;strong&gt;never&lt;/strong&gt; funny and it's a good way to lose friends and make enemies. Unless the speaker asks for commentary during the talk, wait until the end and then ask your questions.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Alright, that out of the way, let's take a look at what Friday, March 15th, has to offer in terms of beginner friendly talks...&lt;/p&gt;
&lt;div class="section" id="friday-morning"&gt;
&lt;h3&gt;Friday Morning&lt;/h3&gt;
&lt;p&gt;The registration desk opens at 7:00 AM. Breakfast begins at 8:00 AM. From 9:00 AM to 10:20 AM is the welcome and initial keynote speeches. PyCon keynotes aren't boring - &lt;strong&gt;they are crazy awesome!&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;In selecting these talks, I've tried to focus on the more technical ones.&lt;/p&gt;
&lt;div class="section" id="am-talks"&gt;
&lt;h4&gt;10:50 AM talks&lt;/h4&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/35/"&gt;How to Except When You're Excepting&lt;/a&gt; (Esther Nam) - One of the rising stars of the community, Esther works for a group that demands 100% test coverage. She's going to cover the fundamentals of writing tests and why tests are a good thing.&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/50/"&gt;How the Internet works&lt;/a&gt; (Jessica McKellar) - Want to know how the internet actually works? Jessica McKellar (also giving two tutorials and a keynote speech) will use Python to help you understand what's really going on.&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/116/"&gt;Gittip: Inspiring Generosity&lt;/a&gt; (Chad Whitacre) - Gittip is an open source Python platform for sustaining open source development via small, anonymous donations. This is a technical case-study about the story of community.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="id1"&gt;
&lt;h4&gt;11:30 AM talks&lt;/h4&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/135/"&gt;Scrapy: it GETs the web&lt;/a&gt; (Asheesh Laroia) - In 2009 I took a web scraping tutorial by the author. He impressed me with his energy and knowledge. While technically this is an &lt;strong&gt;intermediate&lt;/strong&gt; talk, I know everyone will get something out of this talk&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="id2"&gt;
&lt;h4&gt;12:10 AM talks&lt;/h4&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/39/"&gt;API Design for Library Authors&lt;/a&gt; (Chris McDonough) - Well designed APIs are critical for how other developers interact with your code. Chris is one of the talents in the community when it comes to creating easy-to-use but extremely powerful tools. I'm delighted he's made this an introductory talk.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="friday-lunch"&gt;
&lt;h3&gt;Friday Lunch&lt;/h3&gt;
&lt;p&gt;Quick notes:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Don't forget to keep your PyCon meal tickets you got when you registered in the morning or they won't let you into the lunch room!&lt;/li&gt;
&lt;li&gt;Sit down to people you don't know and introduce yourself. Every time I do this I don't just get to meet interesting people, I get to meet &lt;strong&gt;amazing&lt;/strong&gt; people. PyCon is full of brilliant minds and you'll never get to know any of them unless you try.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="section" id="friday-afternoon"&gt;
&lt;h3&gt;Friday Afternoon&lt;/h3&gt;
&lt;p&gt;Got lunch? Time for more talks!&lt;/p&gt;
&lt;div class="section" id="pm-talks"&gt;
&lt;h4&gt;1:40 PM talks&lt;/h4&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/54/"&gt;You can be a speaker at PyCon!&lt;/a&gt; (Anna Ravenscroft, Lynn Root) - PyCon loves new blood. Get some pointers on how to get your talks ready for submission next year!&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/117/"&gt;Python 3.3: Trust Me, It's Better than 2.7&lt;/a&gt; (Brett Cannon) - The world of Python is heading towards Python 3. Want to know why? Attend this talk!&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="pm-talk"&gt;
&lt;h4&gt;1:55 PM talk&lt;/h4&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/40/"&gt;Twisted Logic&lt;/a&gt; (Ashwini Oruganti) - Twisted is a mature, stable asynchronous framework written in Python that's been around for over a decade. New to the framework, the presenter explains why you shouldn't be scared of Twisted.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="id3"&gt;
&lt;h4&gt;2:35 PM talks&lt;/h4&gt;
&lt;p&gt;This slot is going to be hard because all three beginner talks are things you don't want to miss!&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/76/"&gt;Loop like a native: while, for, iterators, generators&lt;/a&gt; (Ned Batchelder) - One of the really awesome features of Python is that you can write custom looping classes. Factor in generators and you'll be amazed by one of Python's most powerful features.&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/112/"&gt;Visualizing Github, Part I: Data to Information&lt;/a&gt; (Dana Bauer, Idan Gazit) - How can you go wrong with visualizing GitHub data using Python? This first part of the talk is on gathering and processing of data.&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/145/"&gt;Encapsulation with descriptors&lt;/a&gt; (Luciano Ramalho) - Python has no private fields, but the property decorator lets you replace public attributes with getters and setters without breaking client code. It's amazing what Python can do when you delve into it's subtleties!&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="id4"&gt;
&lt;h4&gt;3:15 PM talk&lt;/h4&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/136/"&gt;Music Theory and Performance Analysis with Sebastian and Czerny&lt;/a&gt; (James Tauber) - An amazing speaker talking about one of his favorite subjects, this will be a great beginner talk. James mentored me in my early days of Django and JQuery, and I only have good things to say about him.&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/108/"&gt;Visualizing Github, Part II: Information to Meaning&lt;/a&gt; (Idan Gazit, Dana Bauer) - How can you go wrong with visualizing GitHub data using Python? This second part of the talk is on visualizing the data into something meaningful.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="id5"&gt;
&lt;h4&gt;4:15 PM talks&lt;/h4&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/126/"&gt;Transforming Code into Beautiful, Idiomatic Python&lt;/a&gt; (Raymond Hettinger) - This is the talk that's going to bring down the house, because Raymond covers the basics in such a way that even the most advanced developers pick up new tricks. This talk will be standing room only, filled with beginners to the most senior developers on the planet. Get to this one early or you'll miss it!&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/118/"&gt;Deploy your Python app in 5 min with a PaaS&lt;/a&gt; (Nate Aune) - Long time presenter Nate Aune doesn't just explain and demonstrate various Platforms as a Service, he also gives tips on evaluating which one is best for your needs. For someone getting into the Python web this talk is an invaluable service.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="talk"&gt;
&lt;h4&gt;4:30 talk&lt;/h4&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/124/"&gt;If You Code, You Should Write&lt;/a&gt; (Brian Jones) - Python has an amazing culture of documentation. We believe it's our civic duty to document our work on private and public projects. Brian explains why this is so and how to get across the concepts of your work in the best way possible.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="talks"&gt;
&lt;h4&gt;5:10 talks&lt;/h4&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/65/"&gt;SimpleCV - Computer Vision using Python&lt;/a&gt; (Katherine Scott) - This is a crash course on computer vision using the amazing ipython notebook along with NumPy and SciPy.&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/96/"&gt;Planning and Tending the Garden: The Future of Early Childhood Python Education&lt;/a&gt; (Kurt Grandis) - After his PyCon talk last year about using Python to fend off squirrels, Kurt suddenly found himself in the world of kid's education. This talk goes over the current state of the art for kids learning programming in Python and other tools.&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/113/"&gt;Write the Docs&lt;/a&gt; (James Bennett) - Have you heard of a certain well-documented web framework called 'Django'? James Bennett is one of the people responsible for it's amazingly high documentation standard. In this talk he's going to coach on how to write prose that inspires and invigorates people to use your tools.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="evening-activities"&gt;
&lt;h2&gt;Evening Activities&lt;/h2&gt;
&lt;p&gt;On friday night the social scene will kick into high gear. There will be dinners, parties, Starcraft II contests, and much more.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="part-iii"&gt;
&lt;h2&gt;Part III&lt;/h2&gt;
&lt;p&gt;Stay tuned for Part III of this series where I cover the second day of talks best suited for new Python developers!&lt;/p&gt;
&lt;/div&gt;
</summary><category term="python"></category><category term="django"></category><category term="audrey"></category><category term="pycon"></category><category term="pycon-2013-guide"></category></entry><entry><title>Beginner's Guide to PyCon 2013 Part I</title><link href="http://pydanny.com/beginners-guide-pycon-2013-part-1.html" rel="alternate"></link><updated>2013-01-22T16:00:00-08:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2013-01-22:beginners-guide-pycon-2013-part-1.html</id><summary type="html">&lt;p&gt;New to Python and thinking about going to the upcoming &lt;a class="reference external" href="https://us.pycon.org/2013/"&gt;PyCon US&lt;/a&gt; for the first time? You know, that big &lt;a class="reference external" href="http://python.org"&gt;Python&lt;/a&gt; conference taking place near San Francisco in March?&lt;/p&gt;
&lt;p&gt;Or perhaps you signed up already and are getting worried about being overwhelmed by hundreds of tutorials, talks, and activities?&lt;/p&gt;
&lt;p&gt;No worries! This multi-part guide will aid you in getting the most out of attending one of the best technical conferences on the planet. I'm going to share how to get through the whole event in good shape and cover some incredible beginner friendly events.&lt;/p&gt;
&lt;div class="section" id="the-basics"&gt;
&lt;h2&gt;The Basics&lt;/h2&gt;
&lt;p&gt;First off, &lt;a class="reference external" href="https://us.pycon.org/2013/registration/register/"&gt;register&lt;/a&gt; already! PyCon US sold out last year around this time. Don't be left out in the cold. Buy your ticket now before it's too late!&lt;/p&gt;
&lt;p&gt;Now that you've got that done, keep in mind that Python has two days of &lt;a class="reference external" href="https://us.pycon.org/2013/schedule/tutorials/"&gt;tutorials&lt;/a&gt;, three days of &lt;a class="reference external" href="https://us.pycon.org/2013/schedule/talks/"&gt;talks&lt;/a&gt;, and four days of &lt;a class="reference external" href="https://us.pycon.org/2013/community/sprints/"&gt;sprints&lt;/a&gt;. &lt;strong&gt;Nine days of Python!&lt;/strong&gt; The trick is to not get exhausted or sick. Therefore, do the following every day of the conference:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Take at least one shower. Please.&lt;/li&gt;
&lt;li&gt;Eat at least two good meals. Make a point of sitting with different people at each meal and introducing yourself. Make new friends!&lt;/li&gt;
&lt;li&gt;Get at least three hours of sleep. More if possible because your brain is going to go into learning overdrive.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In addition, PyCon US also has a &lt;a class="reference external" href="https://us.pycon.org/2013/about/code-of-conduct/"&gt;code of conduct&lt;/a&gt;. I like to sum it up as, &amp;quot;Act professionally.&amp;quot; Whether or not you agree with codes of conduct for conferences, PyCon US has one and it will be enforced.&lt;/p&gt;
&lt;p&gt;Alright, enough basics, let's get onto tutorials!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="tutorials"&gt;
&lt;h2&gt;Tutorials&lt;/h2&gt;
&lt;p&gt;Tutorials take place on March 13th and 14th. They each cost $150 but are well worth the price. The following are the talks I believe are best suited for beginners.&lt;/p&gt;
&lt;div class="section" id="wednesday-morning"&gt;
&lt;h3&gt;Wednesday Morning&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;For novice programmers start with Jessica McKellar's &lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/1/"&gt;A hands-on introduction to Python for beginning programmers&lt;/a&gt;. I can vouch that the instructor is amazing, and will jumpstart you on the road to being a Python developer.&lt;/li&gt;
&lt;li&gt;Are you an experienced developer new to Python? I suggest &lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/8/"&gt;Going from web pages to web apps with Python&lt;/a&gt; by Asheesh Loroia and Karen Rustad. In 2009 I took a class by Asheesh and was impressed by his energy, enthusiasm, and depth of knowledge.&lt;/li&gt;
&lt;li&gt;Want to learn Python web that isn't Django? Try out Paul Everitt's &lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/12/"&gt;Pyramid for Humans&lt;/a&gt; class.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="section" id="wednesday-afternoon"&gt;
&lt;h3&gt;Wednesday Afternoon&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;You simply can't go wrong with David Beazley's &lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/2/"&gt;Learn Python Through Public Data Hacking&lt;/a&gt;. He's the author of &lt;a class="reference external" href="http://www.amazon.com/Python-Essential-Reference-4th-Edition/dp/0672329786/?ie=UTF8&amp;amp;tag=cn-001-20"&gt;Python Essential Reference&lt;/a&gt;, an amazing instructor, and delivered a PyCon keynote last year.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol class="arabic simple" start="2"&gt;
&lt;li&gt;If you're interested in the web, check out Nathan Yergler's &lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/9/"&gt;Effective Django&lt;/a&gt;. I can assure you that he knows his Django material and is going to deliver a great experience.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="section" id="thursday-morning"&gt;
&lt;h3&gt;Thursday Morning&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;If you're new to Python, you need to learn the Python environment. This means version control, PyPI, test automation, and more. Matt Harrison covers this in &lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/3/"&gt;Scripting: from Hard-drive to Github to PyPI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Getting back to the web, &lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/10/"&gt;Fully Test-Driven Web Development with Django and Selenium&lt;/a&gt; is another run through the Django tutorial, but done from the test driven perspective.&lt;/li&gt;
&lt;li&gt;A fascinating tutorial offered at this time is &lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/30/"&gt;A Gentle Introduction to Computer Vision&lt;/a&gt;. It's a great way to learn how Python is used in many creative and unexpected ways.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="section" id="thursday-afternoon"&gt;
&lt;h3&gt;Thursday Afternoon&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Jessica McKellar returns to instruct on how to give back to the community with &lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/4/"&gt;Contribute with me! Getting started with open source development&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Want to learn how to program games? Look no further than Richard Jones' &lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/19/"&gt;Introduction to PyGame&lt;/a&gt;. He's taught this class for years, and I can't say enough good things about him.&lt;/li&gt;
&lt;li&gt;This talk is not meant for beginning Django developers, but it's useful anyway. &lt;a class="reference external" href="http://gettingstartedwithdjango.com/"&gt;Kenneth Love&lt;/a&gt; and &lt;a class="reference external" href="http://jacobian.org"&gt;Jacob Kaplan-Moss&lt;/a&gt; are presenting &lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/11/"&gt;Wiring Up Django Packages&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="evening-activities"&gt;
&lt;h2&gt;Evening Activities&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/events/reception/"&gt;Opening Reception&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="part-ii"&gt;
&lt;h2&gt;Part II&lt;/h2&gt;
&lt;p&gt;Check out &lt;a class="reference external" href="http://pydanny.com/beginners-guide-pycon-2013-part-2.html"&gt;Beginner's Guide to PyCon 2013 Part II&lt;/a&gt; where I cover the first day of talks best suited for new Python developers!&lt;/p&gt;
&lt;/div&gt;
</summary><category term="python"></category><category term="django"></category><category term="audrey"></category><category term="pycon"></category><category term="pycon-2013-guide"></category></entry><entry><title>Two Scoops of Django FAQ</title><link href="http://pydanny.com/two-scoops-django-faq-20130121.html" rel="alternate"></link><updated>2013-01-21T16:00:00-08:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2013-01-21:two-scoops-django-faq-20130121.html</id><summary type="html">&lt;a class="reference external image-reference" href="http://django.2scoops.org/"&gt;&lt;img alt="https://s3.amazonaws.com/pydanny/frontispiece.png" class="align-center" id="two-scoops-of-django" src="https://s3.amazonaws.com/pydanny/frontispiece.png" /&gt;&lt;/a&gt;
&lt;p&gt;The launch of the &lt;a class="reference external" href="http://django.2scoops.org"&gt;Two Scoops of Django: Best Practices for Django 1.5&lt;/a&gt; book has gone pretty well. The response has been almost entirely positive and sales have been pretty brisk. We've gotten a ton of great, constructive editorial feedback, which we're sorting through as we race towards the BETA release. Here are answers to the commonly asked questions:&lt;/p&gt;
&lt;div class="section" id="when-can-i-buy-the-book-via-paypal"&gt;
&lt;h2&gt;When can I buy the &lt;a class="reference external" href="http://django.2scoops.org"&gt;book&lt;/a&gt; via PayPal?&lt;/h2&gt;
&lt;p&gt;We will support PayPal in either the BETA or FINAL release of the book.&lt;/p&gt;
&lt;p&gt;In order to handle PayPal we need to find a reputable e-publisher that supports it that gives us similar rates, customer service, and product control (updates at any time, uploads of PDF, no surprise charges, etc) as &lt;a class="reference external" href="http://gumroad.com"&gt;Gumroad&lt;/a&gt;. If you know of an e-publisher who is willing to provide that same level of service, please let me know.&lt;/p&gt;
&lt;p&gt;For the record, we aren't leaving &lt;a class="reference external" href="http://gumroad.com"&gt;Gumroad&lt;/a&gt;. We just want to support developers and students who don't have credit cards.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;note:&lt;/strong&gt; While we could certainly write our own publishing platform, that would delay work on the &lt;a class="reference external" href="http://django.2scoops.org"&gt;book&lt;/a&gt;. ;-)&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="when-can-i-get-a-kindle-mobi-or-epub-version"&gt;
&lt;h2&gt;When can I get a Kindle (mobi) or ePub version?&lt;/h2&gt;
&lt;p&gt;Our plan is to support those formats in either the BETA or FINAL releases. In fact, I really love my &lt;a class="reference external" href="http://www.amazon.com/gp/product/B007HCCNJU/?ie=UTF8&amp;amp;tag=cn-001-20"&gt;Kindle&lt;/a&gt;. I can't wait to proof my own &lt;a class="reference external" href="http://django.2scoops.org"&gt;book&lt;/a&gt; on my favorite reading device.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="when-can-i-get-a-print-version"&gt;
&lt;h2&gt;When can I get a print version?&lt;/h2&gt;
&lt;p&gt;We hope to have a print version in about 30 days. We need to ensure that the cover and layout actually looks nice, and that involves ordering copies from the Lulu, CreateSpace, whatever and reviewing them and making corrections. Then ordering again to make sure the corrections look okay. That simply takes a lot of time.&lt;/p&gt;
&lt;p&gt;We are hoping for a mid-February release. Also, keep in mind we aren't sure yet if we'll do a print version of anything but a FINAL release.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="when-are-the-beta-and-final-releases"&gt;
&lt;h2&gt;When are the BETA and FINAL releases?&lt;/h2&gt;
&lt;p&gt;As soon as possible.&lt;/p&gt;
&lt;p&gt;We can't make promises, but at the latest, the FINAL &lt;em&gt;should&lt;/em&gt; be done by the start of March so people have them in hand at PyCon US.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="is-this-book-going-to-get-updated"&gt;
&lt;h2&gt;Is this book going to get updated?&lt;/h2&gt;
&lt;p&gt;Absolutely!&lt;/p&gt;
&lt;p&gt;In fact, we've already sent out three minor updates for grammar and spelling issues, and some bug fixes.  Even after the FINAL version comes out, we'll continue to update the book. One of the advantages of self-published books is we have control of content.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="how-much-work-went-into-the-book"&gt;
&lt;h2&gt;How much work went into the &lt;a class="reference external" href="http://django.2scoops.org"&gt;book&lt;/a&gt;?&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="http://audreymroy.com"&gt;Audrey&lt;/a&gt; and I put in hundreds of hours writing and testing the content. We worked 12-16 hour days for weeks. It was madness, but a glorious madness. We became like hermits and toiled on the &lt;a class="reference external" href="http://django.2scoops.org"&gt;book&lt;/a&gt; while ignoring distractions like sleep, food and consistent exercise.&lt;/p&gt;
&lt;p&gt;Our amazing technical reviewers also worked very hard to provide us with critical commentary, advice and corrections.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="where-should-i-send-errata"&gt;
&lt;h2&gt;Where should I send errata?&lt;/h2&gt;
&lt;p&gt;Please send errata to &lt;a class="reference external" href="mailto:2scoops&amp;#64;cartwheelweb.com"&gt;2scoops&amp;#64;cartwheelweb.com&lt;/a&gt;. The first person who reports an issue or makes a suggestion that we adopt will receive credit in the book. If not in the changelog, then in the dialogue of the book itself.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="are-you-going-to-pycon-us"&gt;
&lt;h2&gt;Are you going to PyCon US?&lt;/h2&gt;
&lt;p&gt;Absolutely! Wouldn't miss &lt;a class="reference external" href="https://us.pycon.org/2013/"&gt;PyCon US&lt;/a&gt; for the world! &lt;a class="reference external" href="http://audreymroy.com"&gt;Audrey&lt;/a&gt; and I met and fell in love at PyCon US 2010! We'll be there for at least the second day of  tutorials, all the talks, and all the &lt;a class="reference external" href="https://us.pycon.org/2013/community/sprints/"&gt;sprints&lt;/a&gt;. I've even got a blog post coming that should serve as a guide for beginning Python and Django developers attending the event.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Shameless Plug:&lt;/em&gt; We're both speaking and giving a tutorial. Sign up for the tutorial or attend our talks!&lt;/p&gt;
&lt;div class="section" id="wiring-up-django-packages-tutorial"&gt;
&lt;h3&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/11/"&gt;Wiring Up Django Packages&lt;/a&gt; (Tutorial)&lt;/h3&gt;
&lt;p&gt;You just finished the Django tutorial. What do you do now? You wire in Django Packages! Django is part of an ecosphere of over 20,000 packages, which can be leveraged to great effect. This tutorial will teach the evaluation, use, and extension of third party Python and Django applications in your projects. This tutorial will be a lecture with a lot of detailed and annotated code examples. Instructors are &lt;a class="reference external" href="http://audreymroy.com"&gt;Audrey Roy&lt;/a&gt;, Daniel Greenfeld, and &lt;a class="reference external" href="http://brack3t.com/"&gt;Kenneth Love&lt;/a&gt; (of &lt;a class="reference external" href="http://gettingstartedwithdjango.com/"&gt;Getting Started with Django&lt;/a&gt; fame).&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="advanced-django-forms-usage-talk"&gt;
&lt;h3&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/101/"&gt;Advanced Django Forms Usage&lt;/a&gt;  (Talk)&lt;/h3&gt;
&lt;p&gt;Django forms are really powerful but there are edge cases, especially with class based views), that can cause a bit of anguish. This talk will go over how to handle many common solutions not currently described in the core documentation. It will also cover useful third-party libraries. Speaker is Daniel Greenfeld.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="using-python-to-generate-art-and-sound-talk"&gt;
&lt;h3&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/schedule/presentation/58/"&gt;Using Python To Generate Art And Sound&lt;/a&gt; (Talk)&lt;/h3&gt;
&lt;p&gt;The trick to navigating the overwhelming Python audio/imaging landscape is understanding how the fundamentals work, using common data processing/visualization libraries, in-depth code samples, and simple math operations. I use the stdlib, NumPy, SciPy, Matplotlib, PIL, and PyCairo to create building blocks, which I then combine to demonstrate advanced sound and image generation techniques. Speaker is &lt;a class="reference external" href="http://audreymroy.com"&gt;Audrey Roy&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="are-you-going-to-django-circus"&gt;
&lt;h2&gt;Are you going to Django Circus?&lt;/h2&gt;
&lt;p&gt;We hope so. &lt;a class="reference external" href="http://2013.djangocon.eu/"&gt;Django Circus&lt;/a&gt;, a.k.a. DjangoCon Europe, is one of the important industry events for us and we're trying to figure out logistics.&lt;/p&gt;
&lt;p&gt;Our problem is that 2012 was a very hard year - the majority of our clients have not paid for the work that we did. Collecting is turning out to be extremely difficult, time consuming, and unpleasant. This is impacting everything we want to do in 2013.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="how-does-the-alpha-work"&gt;
&lt;h2&gt;How does the ALPHA work?&lt;/h2&gt;
&lt;p&gt;The ALPHA is a preview version that we are selling at an introductory price of $12. When you purchase the ALPHA, you get access to the BETA and FINAL versions when they are released.&lt;/p&gt;
&lt;p&gt;In case you're wondering, we are planning to increase the price of the &lt;a class="reference external" href="http://django.2scoops.org"&gt;book&lt;/a&gt; when we release the BETA and FINAL versions.&lt;/p&gt;
&lt;/div&gt;
</summary><category term="twoscoops"></category><category term="python"></category><category term="django"></category><category term="audrey"></category><category term="pycon"></category><category term="djangocon"></category></entry><entry><title>Our Django Book Has Launched</title><link href="http://pydanny.com/our-django-book-is-launched.html" rel="alternate"></link><updated>2013-01-17T10:00:00-08:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2013-01-17:our-django-book-is-launched.html</id><summary type="html">&lt;a class="reference external image-reference" href="http://django.2scoops.org/"&gt;&lt;img alt="https://s3.amazonaws.com/twoscoops/img/tsd-cover.png" class="align-center" id="two-scoops-of-django-best-practices-for-django-1-5" src="https://s3.amazonaws.com/twoscoops/img/tsd-cover.png" /&gt;&lt;/a&gt;
&lt;p&gt;We (&lt;a class="reference external" href="http://audreymroy.com"&gt;Audrey Roy&lt;/a&gt; and I) wrote a &lt;a class="reference external" href="http://django.2scoops.org"&gt;book&lt;/a&gt; on Django! It's called &lt;strong&gt;Two Scoops of Django: Best Practices for Django 1.5&lt;/strong&gt;, and you can buy it right now in e-book (PDF) form on the website: &lt;a class="reference external" href="http://django.2scoops.org"&gt;http://django.2scoops.org&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Django, like any framework, has tips, tricks, and pitfalls that aren't documented in one place. Experienced developers know this stuff, but gleaning it off the Internet takes a lot of time. We decided to take everything we know and write it down. This &lt;a class="reference external" href="http://django.2scoops.org"&gt;book&lt;/a&gt; reflects a portion of what we documented, and if it does well we plan to follow it up with other references.&lt;/p&gt;
&lt;p&gt;If you've followed this blog or watched our talks you've know we've explained tons of Django and Python related examples. We enjoy using Django and Python to build stable, fast web applications quickly and efficiently. This is the &lt;a class="reference external" href="http://django.2scoops.org"&gt;book&lt;/a&gt; we would have wanted while learning the intricacies of our tools, and then kept it handy for reference.&lt;/p&gt;
&lt;p&gt;In the &lt;a class="reference external" href="http://django.2scoops.org"&gt;book&lt;/a&gt; we cover everything from customizing the Django 1.5 User model, forms,  views, templates, security, bottleneck analysis and so much more. We tie in third-party packages from the Django and Python community. We discuss the positive patterns that allow for rapid development, and point out the anti-patterns that cause problems.
The result isn't a walk-through or tutorial, but a reference guide for anyone with at least a basic understanding of Django.&lt;/p&gt;
&lt;p&gt;We tried to make the code copy/pastable, but we are constrained by the limits of PDF. While the code examples display nicely, &lt;em&gt;when pasting from Adobe Reader the leading white spaces vanish&lt;/em&gt;. We apologize and ask if anyone knows how to address this issue to let us know at &lt;a class="reference external" href="mailto:2scoops&amp;#64;cartwheelweb.com"&gt;2scoops&amp;#64;cartwheelweb.com&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Even with an amazing cadre of technical reviewers, there is always the possibility of errors. We are going to be actively maintaining the &lt;a class="reference external" href="http://django.2scoops.org"&gt;book&lt;/a&gt;, so if you find a mistake, let us know and we'll update it and send out an updated copy of the PDF to all buyers.&lt;/p&gt;
&lt;p&gt;If you'd like to buy the book (or learn more about it), you can do so here: &lt;a class="reference external" href="http://django.2scoops.org"&gt;http://django.2scoops.org&lt;/a&gt;&lt;/p&gt;
</summary><category term="twoscoops"></category><category term="resolutions"></category><category term="python"></category><category term="django"></category><category term="audrey"></category><category term="heroku"></category><category term="dotcloud"></category><category term="gondor"></category></entry><entry><title>New Year's Resolutions for 2013</title><link href="http://pydanny.com/new-years-resolutions-for-2013.html" rel="alternate"></link><updated>2012-12-31T10:45:00-08:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2012-12-31:new-years-resolutions-for-2013.html</id><summary type="html">&lt;p&gt;I'm one of those people who not only likes to make New Year's Resolutions, I like to blog about them.&lt;/p&gt;
&lt;div class="section" id="resolution"&gt;
&lt;h2&gt;Resolution&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Go to at least one technical conference in North America, South America, Europe, Asia,  Africa, and Australia.&lt;/li&gt;
&lt;li&gt;Visit at least one new nation. It's hard to come up with preferences since the whole world is so exciting.&lt;/li&gt;
&lt;li&gt;Go back to at least one of the nations I've visited before.&lt;/li&gt;
&lt;li&gt;Take a road trip across the USA.&lt;/li&gt;
&lt;li&gt;See the Grand Canyon.&lt;/li&gt;
&lt;li&gt;Keep to a 32 waist for the whole year.&lt;/li&gt;
&lt;li&gt;Visit friends and family back east.&lt;/li&gt;
&lt;li&gt;Blog once a week. That is at least 52 blog entries!&lt;/li&gt;
&lt;li&gt;Visit the beach for more than one day.&lt;/li&gt;
&lt;li&gt;Take a fun class with Audrey.&lt;/li&gt;
&lt;li&gt;Teach some Python or Django.&lt;/li&gt;
&lt;li&gt;Build something real using Twisted as a critical component.&lt;/li&gt;
&lt;li&gt;Take a high level Python class from the likes of Raymond Hettinger or David Beazley.&lt;/li&gt;
&lt;li&gt;Commit to core Python&lt;/li&gt;
&lt;li&gt;Visit my Son.&lt;/li&gt;
&lt;li&gt;Upload all my outstanding pictures to Flickr!&lt;/li&gt;
&lt;li&gt;Pull off an Aú sem Mão (no-handed cartwheel).&lt;/li&gt;
&lt;li&gt;Attend my first Capoeira Batizado (formal gathering).&lt;/li&gt;
&lt;li&gt;Work out at least three times a week.&lt;/li&gt;
&lt;li&gt;Learn how to surf or snowboard.&lt;/li&gt;
&lt;li&gt;Have a beer with Thomas, Andy, Andy, Tony, Garrick, Bernd, and the rest of Ye Aulde Gange.&lt;/li&gt;
&lt;li&gt;See my old DC area friends such as Eric, Chris, Steve, Beth, Sarah, Daye, Renee, Kenneth, Leslie, Whitney, Dave, and many others.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="accomplished"&gt;
&lt;h2&gt;Accomplished&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Publish as least one book. See &lt;a class="reference external" href="http://django.2scoops.org/"&gt;Two Scoops of Django&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Update my blog to Pelican 3.&lt;/li&gt;
&lt;li&gt;Implement a custom theme design so my blog looks more unique. ;-)&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</summary><category term="holidays"></category><category term="resolutions"></category><category term="python"></category><category term="capoeira"></category><category term="family"></category><category term="friends"></category><category term="django"></category></entry><entry><title>New Year's Python Meme 2012</title><link href="http://pydanny.com/new-years-python-meme-2012.html" rel="alternate"></link><updated>2012-12-28T18:00:00-08:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2012-12-28:new-years-python-meme-2012.html</id><summary type="html">&lt;p&gt;Tarek Ziade has a habit of ending the year with a Python-themed meme. I've matched his meme the times he previousstarted it, and as you can tell from the title of this blog post I'm matching him yet again.&lt;/p&gt;
&lt;div class="section" id="whats-the-coolest-python-application-framework-or-library-you-have-discovered-in-2012"&gt;
&lt;h2&gt;1. What’s the coolest Python application, framework or library you have discovered in 2012?&lt;/h2&gt;
&lt;p&gt;This question took some thought. It was a toss-up between these three choices:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Django Class Based Views (CBVs) allow developers do amazing things with Django, but needed some polish (&lt;a class="reference external" href="https://docs.djangoproject.com/en/1.5/topics/class-based-views/"&gt;improved documentation&lt;/a&gt;, &lt;a class="reference external" href="http://django-braces.readthedocs.org/"&gt;missing functionality&lt;/a&gt;) to be able to shine.&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://reportlab.org"&gt;ReportLab&lt;/a&gt; for generating PDF allowed me to create some &lt;a class="reference external" href="http://www.petcheatsheets.com/"&gt;impressive results&lt;/a&gt;, but the API needed updating. The other Python PDF libraries might be better, but getting images to work trivially in them&lt;/li&gt;
&lt;li&gt;If I didn't completely agree with &lt;a class="reference external" href="http://lucumr.pocoo.org/2012/12/29/sql-is-agile/"&gt;Armin Ronacher on the subject&lt;/a&gt;, I might have gone with a combination of &lt;a class="reference external" href="http://api.mongodb.org/python/"&gt;PyMongo&lt;/a&gt;, &lt;a class="reference external" href="http://mongoengine.org/"&gt;MongoEngine&lt;/a&gt;, and &lt;a class="reference external" href="http://namlook.github.com/mongokit/"&gt;MongoKit&lt;/a&gt;. Just like Armin, I've learned through working with schemaless databases to know that schemas are awesome.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The winner?&lt;/p&gt;
&lt;blockquote&gt;
&lt;strong&gt;Django Class Based Views&lt;/strong&gt;&lt;/blockquote&gt;
&lt;p&gt;In 2012 what I managed to accomplish with Django CBVs was incredible. From early self-instructional work I did for &lt;a class="reference external" href="https://github.com/pydanny/django-mongonaut/blob/master/mongonaut/views.py"&gt;django-mongonaut&lt;/a&gt;, to client efforts and personal projects where I honed my craft, plus examples &lt;a class="reference external" href="http://pydanny.com/tag/class-based-views.html"&gt;I blogged about&lt;/a&gt; or helped get into Django core, it made for a great year. Also I wasn't just productive personally, I helped increased the productivity of others around the world.&lt;/p&gt;
&lt;p&gt;And you ain't seen nothing yet!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="what-new-programming-technique-did-you-learn-in-2012"&gt;
&lt;h2&gt;2. What new programming technique did you learn in 2012?&lt;/h2&gt;
&lt;p&gt;I thought I understood multiple inheritance.&lt;/p&gt;
&lt;p&gt;I really did.&lt;/p&gt;
&lt;p&gt;However, since the start of this year I've delved really deep into it, only to discover just how much I didn't know. While that didn't do my ego any favors, it was a nice refreshing reminder not to get arrogant about one's skills.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="which-open-source-project-did-you-contribute-to-the-most-in-2012-what-did-you-do"&gt;
&lt;h2&gt;3. Which open source project did you contribute to the most in 2012? What did you do?&lt;/h2&gt;
&lt;p&gt;The answer to this is &lt;strong&gt;Django&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;After using Django professionally for 2.5 years, I finally began contributing to the core framework at the DjangoCon Eu 2012 sprints. I joined a group of other dedicated people who decided to improve the &lt;a class="reference external" href="https://docs.djangoproject.com/en/1.5/topics/class-based-views/"&gt;Django CBV documentation&lt;/a&gt;, our goal being setting a new standard for documentation. I'm not sure if we set a new bar in documentation, but we did improve on the existing material.&lt;/p&gt;
&lt;p&gt;I branched out into some other areas of core Django development with mixed results, which played out that way because I just didn't have the time to do more.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="which-python-blog-or-website-did-you-read-the-most-in-2012"&gt;
&lt;h2&gt;4. Which Python blog or website did you read the most in 2012?&lt;/h2&gt;
&lt;p&gt;As always, &lt;a class="reference external" href="http://planet.python.org"&gt;http://planet.python.org&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="what-are-the-three-top-things-you-want-to-learn-in-2013"&gt;
&lt;h2&gt;5. What are the three top things you want to learn in 2013?&lt;/h2&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Really advanced Python as taught by Raymond Hettiger or David Beazley.&lt;/li&gt;
&lt;li&gt;I really want to learn &lt;a class="reference external" href="http://twistedmatrix.com/"&gt;Twisted&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;How to do an &lt;a class="reference external" href="http://en.wikipedia.org/wiki/A%C3%BA#A.C3.BA"&gt;Aú sem Mão&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="section" id="what-is-the-top-software-application-or-library-you-wish-someone-would-write-in-2013"&gt;
&lt;h2&gt;6. What is the top software, application or library you wish someone would write in 2013?&lt;/h2&gt;
&lt;p&gt;I've got a couple:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;A Python SDK that produces results that work perfectly for both modern iOS and Android. Think Corona SDK but with Python.&lt;/li&gt;
&lt;li&gt;A modern PyGame release that installs trivially on Mac OS X.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="want-to-do-your-own-list-here-s-how"&gt;
&lt;h2&gt;Want to do your own list? here's how:&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;copy-paste the questions and answer to them in your blog&lt;/li&gt;
&lt;li&gt;tweet it with the &lt;a class="reference external" href="https://twitter.com/search/realtime?q=%232012pythonmeme&amp;amp;src=typd"&gt;#2012pythonmeme&lt;/a&gt; hashtag&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</summary><category term="meme"></category><category term="python"></category><category term="django"></category><category term="holidays"></category></entry><entry><title>Developer Time</title><link href="http://pydanny.com/developer-time.html" rel="alternate"></link><updated>2012-12-04T12:00:00-08:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2012-12-04:developer-time.html</id><summary type="html">&lt;p&gt;This blog post got started with a tweet.&lt;/p&gt;
&lt;p&gt;That tweet got retweeted a lot by developers. And system administrators. And database administrators. And any creative type.&lt;/p&gt;
&lt;p&gt;As of December 7th, 2012, it had been retweeted over 500 times, a personal best. Obviously I struck a chord that resonated with a lot of people.&lt;/p&gt;
&lt;blockquote class="twitter-tweet"&gt;&lt;p&gt;Developers should have 4-6 hours of uninterrupted activity each day. Each 3-5 minute interruption costs more than you can imagine.&lt;/p&gt;&amp;mdash; Daniel Greenfeld (@pydanny) &lt;a href="https://twitter.com/pydanny/status/275680738773463040" data-datetime="2012-12-03T19:19:44+00:00"&gt;December 3, 2012&lt;/a&gt;&lt;/blockquote&gt;
&lt;script src="http://platform.twitter.com/widgets.js" charset="utf-8"&gt;&lt;/script&gt;&lt;div class="section" id="why-did-this-tweet-resonate-with-so-many-people"&gt;
&lt;h2&gt;Why did this tweet resonate with so many people?&lt;/h2&gt;
&lt;p&gt;What I said in that tweet was not new - dozens if not hundreds of others have tweeted similar thoughts before and gotten many retweets. Heck, it's been written about in blogs and articles for years, either as a huge rant or often as an effort to politely educate others on how to set up a developer/operations/creative shop.&lt;/p&gt;
&lt;p&gt;I think this is because developers/engineers/creatives (and good managers) know that even a tiny distraction to someone &amp;quot;in the zone&amp;quot; takes more than just the 3-5 minutes it takes for you to finish a question and get an answer. Plus, because you are trying to remember the pieces in your head, you won't be able to give this issue your full attention. Which causes a whole other set of issues.&lt;/p&gt;
&lt;p&gt;We know this. Good managers know this. Good companies live off of it.&lt;/p&gt;
&lt;p&gt;And yet this remains a huge problem for many of us because the distractions keep happening. Maybe it's because your manager doesn't understand this issue, or you have a team mate who can switch in-and-out of the zone with impunity. Or because you foolishly leave the chat/IRC/phone on and you get pinged.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="how-do-we-fix-it"&gt;
&lt;h2&gt;How do we fix it?&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;We can't.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I know this sounds depressing, but I'm being realistic. Here's some reasons that apply:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Unless you are fortunate enough to be working on a solo effort, you are working with other developers/engineers/creatives. And if they can't ask you questions or inform you about critical stuff then you or they can waste hours.&lt;/li&gt;
&lt;li&gt;Meetings, short or long, online or in person, are a necessary part of any operation. If not with your boss or underlings, then with clients or users.&lt;/li&gt;
&lt;li&gt;Your boss/co-workers/underlings/kids/pets/parents don't get it that you can't be interrupted.&lt;/li&gt;
&lt;li&gt;As a freelancer, you can't be inaccessible to existing or potential clients.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="no-really-how-do-we-fix-it"&gt;
&lt;h2&gt;No really, how do we fix it?&lt;/h2&gt;
&lt;p&gt;Doesn't matter how frequently you ask the the question (or rant about it), I don't believe this problem can be really solved. However, here are some possible mitigations:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Maker's Day&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;My friend, &lt;a class="reference external" href="http://craigkerstiens.com/2011/11/07/how-heroku-works-maker-day/"&gt;Craig Kerstiens&lt;/a&gt; describes how &lt;a class="reference external" href="http://heroku.com"&gt;Heroku&lt;/a&gt; gives engineers a full day each week (Thursday) to focus on getting stuff done. No meetings, no standup, just 100% uninterrupted quiet time to focus on making stuff.&lt;/p&gt;
&lt;p&gt;Suggest this at your company and see how it goes!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Blocks of Time&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As of 2010, &lt;a class="reference external" href="http://eldarion.com"&gt;Eldarion&lt;/a&gt; broke up their work day into at least two sizable chunks of uninterrupted activity. Between the chunks you communicated with co-workers. The advantage of this approach is if you went down the wrong path or someone had a critical question, the period between chunks addressed this issue.&lt;/p&gt;
&lt;p&gt;In theory this is how a lot of places work (lunch being the break). The reality is that the distractions often still pile in. For Eldarion it worked because everyone was remote.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. New Desk Location&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If working at an office, asked to be moved to a place with less foot traffic. The downside to this is you can end up in noisy, cold, dark places.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. New Job&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Switch to a new job that promises less distractions.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="maybe-i-m-wrong"&gt;
&lt;h2&gt;Maybe I'm wrong&lt;/h2&gt;
&lt;p&gt;I'm more than happy to be proven wrong.&lt;/p&gt;
&lt;p&gt;Maybe there is a way to get 4-6 hours a day of uninterrupted maker's time every work day.&lt;/p&gt;
&lt;p&gt;If you've got any ideas, let me know!&lt;/p&gt;
&lt;/div&gt;
</summary><category term="python"></category><category term="django"></category><category term="rant"></category><category term="blog"></category></entry><entry><title>Stay with the Django CBV defaults!</title><link href="http://pydanny.com/stay-with-the-django-cbv-defaults.html" rel="alternate"></link><updated>2012-11-27T16:00:00-08:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2012-11-27:stay-with-the-django-cbv-defaults.html</id><summary type="html">&lt;p&gt;One virtue of Django Class Based Views (CBVs) is that they come with pretty good default settings. The virtue of this is you can really pare your code down in size and complexity.&lt;/p&gt;
&lt;p&gt;For example, here is an implementation of CBVs based on a straight-forward Django model , &lt;tt class="docutils literal"&gt;stuffage.models.Stuff&lt;/tt&gt;, that has a &lt;tt class="docutils literal"&gt;get_absolute_url&lt;/tt&gt; method:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;stuffage/views.py&lt;/strong&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.views&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;generic&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;stuffage.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Stuff&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StuffDetailView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;generic&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DetailView&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Stuff&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StuffListView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;generic&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ListView&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Stuff&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StuffCreateView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;generic&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateView&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Stuff&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StuffUpdateView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;generic&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UpdateView&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Stuff&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;stuffage/urls.py&lt;/strong&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.conf.urls.defaults&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;patterns&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;include&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;stuffage&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;views&lt;/span&gt;

&lt;span class="n"&gt;urlpatterns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;patterns&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;regex&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;r&amp;quot;^create/$&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StuffCreateView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;as_view&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;stuff_create&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;regex&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;r&amp;quot;^update/(?P&amp;lt;pk&amp;gt;\d+)/$&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StuffUpdateView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;as_view&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;stuff_update&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;regex&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;r&amp;quot;^(?P&amp;lt;pk&amp;gt;\d+)/$&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StuffDetailView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;as_view&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;stuff_detail&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;regex&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;r&amp;quot;^$&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StuffListView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;as_view&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;stuff_list&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;These four CBVs will default to the following three templates without any action on my part:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
stuffage/stuff_detail.html (StuffDetailView)
stuffage/stuff_form.html (StuffCreateView, StuffUpdateView)
stuffage/stuff_list.html (StuffListView)
&lt;/pre&gt;
&lt;p&gt;So easy I use a simple script to render all this code!&lt;/p&gt;
&lt;div class="section" id="what-about-doing-this-all-in-the-urls-py"&gt;
&lt;h2&gt;What about doing this all in the urls.py?&lt;/h2&gt;
&lt;p&gt;Yes, I could do this all in the &lt;cite&gt;urls.py&lt;/cite&gt;, but real Django code involves doing some logic in views, no matter how skinny you try to make said views. While I'm a huge proponent of logic in fat models, invariably I'm adding to the view context, or doing something else that requires tweaking of CBV settings.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="the-problem"&gt;
&lt;h2&gt;The problem&lt;/h2&gt;
&lt;p&gt;One trait of developers is we like to &lt;strong&gt;tinker&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Unfortunately, I keep seeing developers tinkering on the settings for Django CBVs without any reason besides tinkeringWhich means you get things like:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;unfortunately tinkered stuffage/views.py&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# 1. Using template_name means extra code and extra developer lookup time.&lt;/span&gt;
&lt;span class="c"&gt;# 2. Changing the context_object_name means extra code  and extra developer&lt;/span&gt;
&lt;span class="c"&gt;#       lookup time.&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StuffDetailView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;generic&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DetailView&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Stuff&lt;/span&gt;
    &lt;span class="n"&gt;template_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;stuffage/stuffs.html&amp;quot;&lt;/span&gt;
    &lt;span class="n"&gt;context_object_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;stuff&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;unfortunately tinkered stuffage/urls.py&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# 1. Logic into your URLConf should be kept to a minimum&lt;/span&gt;
&lt;span class="c"&gt;# 2. Unless you are using the same view more than once, specifying the&lt;/span&gt;
&lt;span class="c"&gt;#       template_name here is a waste of code. And makes it harder to&lt;/span&gt;
&lt;span class="c"&gt;#       understand the view.&lt;/span&gt;
&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;regex&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;r&amp;quot;^$&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StuffListView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;as_view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;template_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;stuffage/stuffs.html&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;stuff_list&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;),&lt;/span&gt;

&lt;span class="c"&gt;# No matter how fat your models get, you always end up extending all views,&lt;/span&gt;
&lt;span class="c"&gt;#   so this will have to be moved into the formal views.py at some point. So&lt;/span&gt;
&lt;span class="c"&gt;#   why not start with it in the views.py in the first place.&lt;/span&gt;
&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;regex&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;r&amp;quot;^$&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ListView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;as_view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Stuff&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;template_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;stuffage/stuffs.html&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;stuff_list&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Don't forget you can also tinker/tweak formats and slug/pk identifier defaults, and a ton of other things that are part of Django CBVs. While this gives you great power, if misused that power can cause grief in terms of code obfuscation and the need for additional testing.&lt;/p&gt;
&lt;p&gt;My opinion is that these defaults were meant as a standard for the CBV to operate, upon which developers familiar with the Django CBV API could extend and expand their code for minimal effort. Yes, you can tweak them to match your preferred patterns, but that's extra work. Work you shouldn't be doing if you can avoid it.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="my-advice"&gt;
&lt;h2&gt;My Advice&lt;/h2&gt;
&lt;p&gt;Stick with the defaults and only modify behavior that actually needs to be modified. For example, if you want to show multiple versions of a ListView you might do something like:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;stuffage/urls.py with a pydanny approved use of template_name&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;regex&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;r&amp;quot;^$&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StuffListView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;as_view&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;stuff_list&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;),&lt;/span&gt;

&lt;span class="c"&gt;# Same view but with a template designed to show larger list items.&lt;/span&gt;
&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;regex&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;r&amp;quot;^large/$&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StuffListView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;as_view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;template_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;stuffage/stuff_list_large.html&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;stuff_list_large&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="summary"&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;This is the pattern I follow when I build projects. I stick to the framework standard as much as possible. Since many systems rely on convention over configuration, this makes it easier and faster to develop projects, be it Django, Twisted, or some other tool.&lt;/p&gt;
&lt;p&gt;It's the work you can see in my &lt;a class="reference external" href="http://petcheatsheets.com"&gt;recent&lt;/a&gt; &lt;a class="reference external" href="http://movehero.io"&gt;public&lt;/a&gt; &lt;a class="reference external" href="http://lacurrents.com"&gt;projects&lt;/a&gt;, and what I want to port to long existing sites like &lt;a class="reference external" href="http://djangopackages.com"&gt;Django Packages&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
</summary><category term="python"></category><category term="rant"></category><category term="django"></category><category term="python"></category><category term="howto"></category><category term="class-based-views"></category></entry><entry><title>Case Study: URL Design for petcheatsheets.com</title><link href="http://pydanny.com/case-study-url-design-for-petcheatsheetscom.html" rel="alternate"></link><updated>2012-11-21T22:00:00-08:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2012-11-21:case-study-url-design-for-petcheatsheetscom.html</id><summary type="html">&lt;p&gt;&lt;strong&gt;Backstory:&lt;/strong&gt; On Saturday, November 17, 2012 &lt;a class="reference external" href="http://audreymroy.com"&gt;Audrey Roy&lt;/a&gt; and I decided to participate in the &lt;a class="reference external" href="https://twitter.com/petcentric"&gt;Petcentric&lt;/a&gt; hackathon, a Los Angeles area Pet-themed product/coding contest held at &lt;a class="reference external" href="http://www.amplify.la/"&gt;Amplify&lt;/a&gt;. We arrived a bit late, but armed with Audrey's idea of creating a pet based reference sheet for owners, pet sitters, vets, and anyone else needing a card with data on pets, we got to work. About eight hours later we toggled a DNS switch and &lt;a class="reference external" href="https://www.petcheatsheets.com"&gt;petcheatsheets.com&lt;/a&gt; was live.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Pet Cheatsheet's owner's pet information is private, because it includes emergency contact information that often includes phone numbers, email addresses, and even physical addresses of family members and friends. Maintaining the privacy of pets and their owners was also a consideration in implementation.&lt;/p&gt;
&lt;div class="section" id="url-design-thoughts"&gt;
&lt;h2&gt;URL Design Thoughts&lt;/h2&gt;
&lt;p&gt;During development, one of the things I considered carefully was URL design of the primary feature, which was pets. The obvious choice was to go with a design that identified owners with pets:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
/&amp;lt;owner_username&amp;gt;/&amp;lt;pet_name&amp;gt;/
&lt;/pre&gt;
&lt;p&gt;However, upon reflection, this didn't sit well with me. What if a pet changed owners? Identifying a pet with a particular owner in the URL meant that if we ever added a 'transfer ownership' feature, there would be extra work. Also, if we ever implemented a sharing feature, changing URLs on a pet going to the same veterinarian their whole life might make the veterinarian's list of pets and their URLs invalid.&lt;/p&gt;
&lt;p&gt;With that in mind, I decided to go with an identifier and pet name, where the pet name was actually not used in the lookup:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
/&amp;lt;pet_id&amp;gt;/&amp;lt;pet_name:not_required&amp;gt;/
&lt;/pre&gt;
&lt;p&gt;One more thing, rather than just use the &lt;strong&gt;pet&lt;/strong&gt; table's primary key as &lt;tt class="docutils literal"&gt;&amp;lt;pet_id&amp;gt;&lt;/tt&gt; I decided to go with base36 (0-9 and a-z) encoding. It's not unlike what URL shortening services do, and if we gained any traction, it makes recitation of a pet's URL easier. So the final result was actually:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
/&amp;lt;pet_id:base_36_encoded&amp;gt;/&amp;lt;pet_name:not_required&amp;gt;/
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;Here's a simplified view of the final implementation, starting with the model:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# pets/models.py&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.utils.translation&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ugettext_lazy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Pet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Pet&amp;#39;s name&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;identifier&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;identifier&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;db_index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c"&gt;# More fields...&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then the form:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# pets/forms.py&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;pets.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Pet&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PetForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ModelForm&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Pet&lt;/span&gt;
        &lt;span class="n"&gt;fields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;# more fields&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;With model and form, we build the views:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# pets/views.py&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.shortcuts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;get_object_or_404&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.utils.baseconv&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;base36&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.views.generic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;CreateView&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DetailView&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;UpdateView&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;braces.views&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;LoginRequiredMixin&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;pets.forms&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PetForm&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PetCreateView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LoginRequiredMixin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CreateView&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Pet&lt;/span&gt;
    &lt;span class="n"&gt;form_class&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PetForm&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;form_valid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;pet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;pet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;identifier&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;base36&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pk&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;pet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;owner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;
        &lt;span class="c"&gt;# Save again - it&amp;#39;s not taking THAT many server cycles AND we needed&lt;/span&gt;
        &lt;span class="c"&gt;#    the pet.pk in advance to generate the pet.identifier&lt;/span&gt;
        &lt;span class="n"&gt;pet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PetCreateView&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;form_valid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GetPetMixin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot; Any view that needs to get a Pet object can use this Mixin&lt;/span&gt;

&lt;span class="sd"&gt;        Pet Cheatsheet&amp;#39;s owner&amp;#39;s pet information is private, because it&lt;/span&gt;
&lt;span class="sd"&gt;            includes emergency contact information that often includes phone&lt;/span&gt;
&lt;span class="sd"&gt;            numbers, email addresses, and even physical addresses of family&lt;/span&gt;
&lt;span class="sd"&gt;            members and friends.&lt;/span&gt;
&lt;span class="sd"&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;pet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_object_or_404&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;identifier&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;identifier&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;pet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;owner&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="c"&gt;# Rather than a &amp;#39;forbidden&amp;#39; result, we want to show a &amp;#39;Pet Not&lt;/span&gt;
            &lt;span class="c"&gt;#    Found&amp;#39; page so we can educate site users.&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;Http404&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;pet&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PetDetailView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LoginRequiredMixin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GetPetMixin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DetailView&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PetUpdateView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LoginRequiredMixin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GetPetMixin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;UpdateView&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Pet&lt;/span&gt;
    &lt;span class="n"&gt;form_class&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PetForm&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PetPDFView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LoginRequiredMixin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GetPetMixin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DetailView&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Pet&lt;/span&gt;

    &lt;span class="c"&gt;# snip: lots of code for rendering the PDFs.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then we wire up the views into the urls:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.conf.urls.defaults&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;patterns&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;pets&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;views&lt;/span&gt;

&lt;span class="n"&gt;urlpatterns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;patterns&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;regex&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;r&amp;quot;^build-cheatsheet/$&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PetCreateView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;as_view&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;pet_create&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;regex&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;r&amp;quot;^update/(?P&amp;lt;identifier&amp;gt;[\w\d]+)/(?P&amp;lt;slug&amp;gt;[\w\d\-\_]+)/$&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PetUpdateView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;as_view&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;pet_update&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;regex&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;r&amp;quot;^(?P&amp;lt;identifier&amp;gt;[\w\d]+)/(?P&amp;lt;slug&amp;gt;[\w\d\-\_]+)/$&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PetDetailView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;as_view&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;pet_detail&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="c"&gt;# snip: a lot of other views&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="result"&gt;
&lt;h2&gt;Result&lt;/h2&gt;
&lt;p&gt;In the image below you can see how Marko's URL has his own unique identifier, along with his name. I can change the name in the URL or even in the database, but so long as I don't modify the identifying part of the URL (&lt;tt class="docutils literal"&gt;1m&lt;/tt&gt;), his information always shows up.&lt;/p&gt;
&lt;a class="reference external image-reference" href="http://petcheatsheets.com"&gt;&lt;img alt="petcheatsheets-url-example.png" class="img-polaroid align-center" id="pet-cheatsheets-url-example" src="petcheatsheets-url-example.png" /&gt;&lt;/a&gt;
&lt;/div&gt;
</summary><category term="python"></category><category term="django"></category><category term="howto"></category><category term="casestudy"></category><category term="hackathon"></category><category term="class-based-views"></category></entry><entry><title>Django GetOrCreateView</title><link href="http://pydanny.com/django-getorcreateview.html" rel="alternate"></link><updated>2012-10-16T22:00:00-07:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2012-10-16:django-getorcreateview.html</id><summary type="html">&lt;p&gt;Today I decided to use the Django class based view (CBV) CreateView, but I wanted to avoid duplications and submit to the view from the front page of a site. The reason was I needed a simple newsletter signup form.  This is what I cooked up and should work for Django 1.3, 1.4, and the forthcoming 1.5 release. Here is what I did:&lt;/p&gt;
&lt;div class="section" id="installed-dependencies"&gt;
&lt;h2&gt;1. Installed dependencies&lt;/h2&gt;
&lt;p&gt;This version requires the following package to be &lt;cite&gt;pip&lt;/cite&gt; installed into your &lt;cite&gt;virtualenv&lt;/cite&gt;.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/django-extensions/django-extensions"&gt;django-extensions&lt;/a&gt; so we can have easy timestamps on models.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This also needs to be added to your list of INSTALLED_APPS:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;INSTALLED_APPS&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;django_extensions&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="defined-the-model"&gt;
&lt;h2&gt;2. Defined the model&lt;/h2&gt;
&lt;p&gt;The model is really simple, and inherits from &lt;cite&gt;TimeStampedModel&lt;/cite&gt; so we know when people signed up:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django_extensions.db.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;TimeStampedModel&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NewsLetterSignup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TimeStampedModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EmailField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Email&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__unicode__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="wrote-the-view"&gt;
&lt;h2&gt;3. Wrote the view&lt;/h2&gt;
&lt;p&gt;Here's the somewhat challenging part that forced me to dive into Django's source code. Even with the documentation work we've done over the past few months, it's clear we've got a long way to go.&lt;/p&gt;
&lt;p&gt;Because of that source code diving, for this blog post I really did my best to document why I did things in the &lt;cite&gt;NewsLetterSignupView.form_valid()&lt;/cite&gt; method.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.http&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;HttpResponseRedirect&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.views.generic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;CreateView&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;NewsLetterSignup&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NewsLetterSignupView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CreateView&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot; Signs up users to a newsletter &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

    &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;NewsLetterSignup&lt;/span&gt;
    &lt;span class="n"&gt;success_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;/newsletter-signed-up/&amp;#39;&lt;/span&gt;  &lt;span class="c"&gt;# replace with reverse&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;form_valid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class="sd"&gt;        If the form is valid, save the associated model.&lt;/span&gt;
&lt;span class="sd"&gt;            (django.views.generic.edit.ModelFormMixin)&lt;/span&gt;
&lt;span class="sd"&gt;        If the form is valid, redirect to the supplied URL.&lt;/span&gt;
&lt;span class="sd"&gt;            (django.views.generic.edit.FormMixin)&lt;/span&gt;
&lt;span class="sd"&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

        &lt;span class="c"&gt;# Get the email from the form.cleaned_data dictionary&lt;/span&gt;
        &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cleaned_data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;email&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c"&gt;# Get or create the signup. We don&amp;#39;t need to do anything with the&lt;/span&gt;
        &lt;span class="c"&gt;#   model instance or created boolean so we don&amp;#39;t set them.&lt;/span&gt;
        &lt;span class="n"&gt;NewsLetterSignup&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_or_create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c"&gt;# Don&amp;#39;t use super() to inherit as it will do a form.save()&lt;/span&gt;
        &lt;span class="c"&gt;# You could call the FormMixin&amp;#39;s form_valid() method but I think&lt;/span&gt;
        &lt;span class="c"&gt;#   using a HttpResponseRedirect() much more explicit.&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;HttpResponseRedirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;success_url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="wired-it-together"&gt;
&lt;h2&gt;4. Wired it together&lt;/h2&gt;
&lt;p&gt;In urls.py:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.conf.urls&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;patterns&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.views.generic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;TemplateView&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;.views&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;NewsLetterSignupView&lt;/span&gt;

&lt;span class="n"&gt;urlpatterns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;patterns&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;regex&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;r&amp;#39;^newsletter-signed-up/$&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;TemplateView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;as_view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;template_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;pages/newsletter_signed_up.html&amp;quot;&lt;/span&gt;
        &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;newsletter_signedup&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;regex&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;r&amp;#39;^newsletter-signup/$&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;NewsLetterSignupView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;as_view&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;news_letter_signup&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="closing-thoughts"&gt;
&lt;h2&gt;Closing thoughts&lt;/h2&gt;
&lt;p&gt;First off, you'll notice I didn't include the &lt;cite&gt;pages/newsletter_signed_up.html&lt;/cite&gt; because for this case it's too trivial.&lt;/p&gt;
&lt;p&gt;Second, this is one of those very clear cases where a functional view would have been so much easier compared to the effort I spent writing this as a class based view. The line count would have been about the same, but the mental bandwidth involved in figuring this would have been a fraction of the effort I spent.&lt;/p&gt;
&lt;p&gt;Third, this is probably better served with an implementation &lt;cite&gt;django.views.generic.FormView&lt;/cite&gt;. Oh well...&lt;/p&gt;
&lt;p&gt;Fourth, I want to see a configurable version of this in the next release of &lt;a class="reference external" href="https://github.com/brack3t/django-braces/"&gt;django-braces&lt;/a&gt;. ;-)&lt;/p&gt;
&lt;/div&gt;
</summary><category term="python"></category><category term="django"></category><category term="howto"></category><category term="class-based-views"></category></entry><entry><title>Los Angeles Open Source Sprint on Nov 4th!</title><link href="http://pydanny.com/los-angeles-open-source-sprint-on-nov-4th.html" rel="alternate"></link><updated>2012-10-14T14:00:00-07:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2012-10-14:los-angeles-open-source-sprint-on-nov-4th.html</id><summary type="html">&lt;a class="reference external image-reference" href="http://www.meetup.com/LA-Hackathons/events/85658952/"&gt;&lt;img alt="https://s3.amazonaws.com/pydanny/la_hackathons.jpeg" class="align-left" id="la-open-source-sprint-5" src="https://s3.amazonaws.com/pydanny/la_hackathons.jpeg" /&gt;&lt;/a&gt;
&lt;p&gt;Yet again, myself, Audrey Roy, and a small but elite cadre of volunteers are feverishly at work putting together another Los Angeles open source event. Our &lt;a class="reference external" href="http://pydanny.com/july-15th-2012-la-open-source-recap.html"&gt;last effort went smashingly well&lt;/a&gt;, and like any good engineer, we're ready to scale up - this time to 150 attendees!&lt;/p&gt;
&lt;p&gt;LA Open Source #5 is a day long coding event for Open Source developers of all languages and skill levels to come and code like fiends. They'll be joined by dozens of either really smart coders or nice people like me. Sponsors are providing food, drinks, venue, and more!&lt;/p&gt;
&lt;p&gt;RSVP at &lt;a class="reference external" href="http://www.meetup.com/LA-Hackathons/events/85658952/"&gt;http://www.meetup.com/LA-Hackathons/events/85658952/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I'll be there to:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Co-lead the event with the assistance of the awesome Los Angeles technical community!&lt;/li&gt;
&lt;li&gt;Code like a fiend. I plan to work on core &lt;a class="reference external" href="http://djangoproject.com"&gt;Django&lt;/a&gt;. Maybe some ember.js stuff too.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And now to open the floor to questions...&lt;/p&gt;
&lt;div class="section" id="when-and-where"&gt;
&lt;h2&gt;When and where?&lt;/h2&gt;
&lt;p&gt;Where:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
Cross Campus (crosscamp.us)
820 Broadway
Santa Monica, CA
&lt;/pre&gt;
&lt;p&gt;When:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
November 4th, 2012
10 AM to 9 PM
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="is-this-like-a-hackathon"&gt;
&lt;h2&gt;Is this like a Hackathon?&lt;/h2&gt;
&lt;p&gt;Yup. See &lt;a class="reference external" href="http://en.wikipedia.org/wiki/Hackathon#Sprints"&gt;http://en.wikipedia.org/wiki/Hackathon#Sprints&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="what-if-i-don-t-have-a-project-of-my-own-to-bring-should-i-come"&gt;
&lt;h2&gt;What if I don't have a project of my own to bring? Should I come?&lt;/h2&gt;
&lt;p&gt;Heck yeah! There will be a number of projects around that you can join and contribute to in order to make the world a better place. The current list of projects include things like:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Django - in fact, this time we've got at least one core Django developer!&lt;/li&gt;
&lt;li&gt;Node.js&lt;/li&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;Rails&lt;/li&gt;
&lt;li&gt;Ruby&lt;/li&gt;
&lt;li&gt;Pyramid&lt;/li&gt;
&lt;li&gt;Salt Stack&lt;/li&gt;
&lt;li&gt;Clojure&lt;/li&gt;
&lt;li&gt;PHP&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="i-m-just-starting-as-a-developer-should-i-come"&gt;
&lt;h2&gt;I'm just starting as a developer, should I come?&lt;/h2&gt;
&lt;p&gt;It depends.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;If you've never coded before&lt;/strong&gt;, this isn't the right place. Instead, you might consider one of the local coding workshops or classes. In fact, here's a good &lt;a class="reference external" href="http://www.meetup.com/Los-Angeles-Hack-Night/"&gt;bi-weekly hack night / study group&lt;/a&gt; for you.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;If you've done a tutorial or two&lt;/strong&gt;, sprints can be a great way to learn new skills or hone your technique by sitting alongside experienced developers who actually need your help. A lot of projects have what are called 'low hanging fruit', which are 'simpler' tasks saved for beginner developers to wet their teeth on. Things I've learned at events like these include Git, Mercurial, JQuery, and a hundred other things that have made me a better coder.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="can-i-come-and-do-one-of-the-following"&gt;
&lt;h2&gt;Can I come and do one of the following:&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Recruit.&lt;/li&gt;
&lt;li&gt;Get people to work on my private project.&lt;/li&gt;
&lt;li&gt;Get people to work on my start-up idea.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;No.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This is not a job fair or way to get free developers services, and we don't want unnecessary distractions.&lt;/p&gt;
&lt;p&gt;On the other hand, if you want to help sponsor we mention you on the official event description, in social media and many other perks. Please contact us at &lt;a class="reference external" href="mailto:sponsors&amp;#64;laopensource.org"&gt;sponsors&amp;#64;laopensource.org&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In addition, we're considering future events that mix in business into our efforts. If you're interested in that sort of thing then stay tuned for more announcements.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="what-about-sponsorship"&gt;
&lt;h2&gt;What about sponsorship?&lt;/h2&gt;
&lt;p&gt;In return for sponsorship we mention your organization or person on the official event description, and provide many other perks including mention in social media.&lt;/p&gt;
&lt;p&gt;In fact, our attendees are well-noted for their feverish support of sponsors. Developer-only open source events are rare in Los Angeles, so attendees are incredibly grateful to those who make the event possible.&lt;/p&gt;
&lt;p&gt;If interested, please contact us at &lt;a class="reference external" href="mailto:sponsors&amp;#64;laopensource.org"&gt;sponsors&amp;#64;laopensource.org&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="what-do-i-need-to-bring"&gt;
&lt;h2&gt;What do I need to bring?&lt;/h2&gt;
&lt;p&gt;Your own functioning laptop with power cord. Neither event organizers, the venue, or sponsors are providing equipment. We also encourage you to bring a power strip labeled with your name.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="i-m-sold-how-much-does-it-cost-and-where-do-i-register"&gt;
&lt;h2&gt;I'm sold! How much does it cost and where do I register?&lt;/h2&gt;
&lt;p&gt;The event is $10, covers food and drink for the day, and you can RSVP by clicking on the image below&lt;/p&gt;
&lt;a class="reference external image-reference" href="http://www.meetup.com/LA-Hackathons/events/85658952/"&gt;&lt;img alt="https://s3.amazonaws.com/pydanny/open_source_sprint.png" class="align-left" id="la-open-source-sprints-logo" src="https://s3.amazonaws.com/pydanny/open_source_sprint.png" /&gt;&lt;/a&gt;
&lt;/div&gt;
</summary><category term="python"></category><category term="django"></category><category term="LA"></category><category term="sprint"></category><category term="hackathon"></category><category term="nodejs"></category><category term="ruby"></category><category term="rails"></category><category term="clojure"></category><category term="php"></category></entry><entry><title>We need more PyCon US 2013 submissions!</title><link href="http://pydanny.com/we-need-more-pycon-us-2013-submissions.html" rel="alternate"></link><updated>2012-09-27T18:00:00-07:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2012-09-27:we-need-more-pycon-us-2013-submissions.html</id><summary type="html">&lt;p&gt;The PyCon US 2013 &lt;a class="reference external" href="https://us.pycon.org/2013/speaking/cfp/"&gt;call for papers (CFP)&lt;/a&gt; ends tomorrow, September 28th, 2012. We need more talk and tutorial submissions. Talks are 30 or 45 minute efforts in front of the PyCon audience and are recorded for posterity. Tutorials are three hours long and are given to attendees who have paid an additional fee in order to slurp in knowledge from the masters.&lt;/p&gt;
&lt;p&gt;On the 3 hour tutorial side of things, &lt;strong&gt;we especially need more Intro to Python level submission&lt;/strong&gt;. That means getting beginners up to speed on basic Python techniques, so they can then exploit the other tutorials, conference, and sprints to their full advantage.&lt;/p&gt;
&lt;div class="section" id="now-onto-some-questions"&gt;
&lt;h2&gt;Now onto some questions...&lt;/h2&gt;
&lt;div class="section" id="i-would-like-to-give-a-tutorial-but-it-s-so-much-work-to-put-together-3-hours-of-quality-content"&gt;
&lt;h3&gt;1. I would like to give a tutorial but it's so much work to put together 3 hours of quality content.&lt;/h3&gt;
&lt;p&gt;The organizers of PyCon recognize that putting together a quality tutorial is an amazing amount of work. Which is why tutorial presenters are compensated for their effort.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="what-is-the-most-likely-length-talk-to-be-accepted-30-minutes-or-45-minutes"&gt;
&lt;h3&gt;2. What is the most likely length talk to be accepted? 30 minutes or 45 minutes?&lt;/h3&gt;
&lt;p&gt;The vast majority of PyCon sessions are 30 minutes long, so 45 minute slots are rare and valuable commodities. So if your talk needs to be 45 minutes long your  proposal has to really speak to the PyCon talk reviewers.&lt;/p&gt;
&lt;p&gt;Not only that, if reviewers send you information requests for any duration talk or tutorial, &lt;strong&gt;you dramatically increase your odds of talk acceptance with timely responses&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;And, as said before, PyCon really needs more &lt;strong&gt;introductory level Python tutorial&lt;/strong&gt; submissions.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="i-would-like-to-present-a-talk-or-tutorial-but-i-can-t-afford-to-come-to-pycon"&gt;
&lt;h3&gt;3. I would like to present a talk or tutorial but I can't afford to come to PyCon.&lt;/h3&gt;
&lt;p&gt;PyCon's &lt;a class="reference external" href="https://docs.google.com/spreadsheet/viewform?fromEmail=true&amp;amp;formkey=dGt4Z0dsY052VERJem4xUUFVQW9uQVE6MQ"&gt;financial aid program&lt;/a&gt; is said to favor accepted speakers to PyCon. They really want you to come!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="i-would-like-to-present-but-i-can-t-come-up-with-a-good-idea"&gt;
&lt;h3&gt;4. I would like to present but I can't come up with a good idea!&lt;/h3&gt;
&lt;p&gt;I had this problem as well! Then I looked at the &lt;a class="reference external" href="https://us.pycon.org/2013/tutorials/suggested_topics_2012/"&gt;Suggested Tutorial Topics&lt;/a&gt; and got some ideas.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="ack-i-ve-got-a-talk-idea-but-it-s-going-to-take-me-too-much-time-to-put-it-together"&gt;
&lt;h3&gt;5. Ack! I've got a talk idea but it's going to take me too much time to put it together!&lt;/h3&gt;
&lt;p&gt;Submit the talk anyway before the talk and in fields you aren't ready to fill in, simply put '&lt;strong&gt;TBD&lt;/strong&gt;'. Then over the course of the next few days replace TBD with real material. Don't wait too long though to fix those TBDs, no more than a week!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="i-m-a-beginner-nobody-in-the-community-is-there-any-chance-my-proposal-will-get-accepted"&gt;
&lt;h3&gt;6. I'm a beginner/nobody in the community, is there any chance my proposal will get accepted?&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Absolutely!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The PyCon talk/tutorial reviewers love to see new people present. While experienced/proven speakers have an edge, good talk/tutorial proposals from promising candidates &lt;strong&gt;can&lt;/strong&gt; make it into the conference. Carefully double-check your submission, be responsive to reviewers, and stay positive. I'm not saying you will get in, but I am saying it's worth the effort.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="good-luck"&gt;
&lt;h2&gt;Good luck!&lt;/h2&gt;
&lt;p&gt;PyCon 2013 is going to be bigger and better than any previous year. That's because we pull together as a community to run an amazing event that is known to jumpstart careers and cause amazing life changes. We can't do this without you, so hurry up on your &lt;a class="reference external" href="https://us.pycon.org/2013/speaking/cfp/"&gt;PyCon US 2013 submissions&lt;/a&gt;!&lt;/p&gt;
&lt;/div&gt;
</summary><category term="python"></category><category term="pycon"></category><category term="django"></category></entry><entry><title>Thoughts on my stack</title><link href="http://pydanny.com/thoughts-on-my-stack.html" rel="alternate"></link><updated>2012-09-04T10:30:00-07:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2012-09-04:thoughts-on-my-stack.html</id><summary type="html">&lt;p&gt;I'm an open source developer. I use Python, Django, PostgreSQL, JQuery, MongoDB, Memcached, and Redis. I push production code to Linux servers.&lt;/p&gt;
&lt;p&gt;And yet:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;My laptop runs Apple's Mac OS X.&lt;/li&gt;
&lt;li&gt;My primary editor is Sublime Text.&lt;/li&gt;
&lt;li&gt;My production servers are provided mostly by Heroku.&lt;/li&gt;
&lt;li&gt;All my sites are hosted on Amazon EC2.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I've got nothing against Apple, Heroku, or Amazon, but their tools are not open source.&lt;/p&gt;
&lt;p&gt;And that's food for thought.&lt;/p&gt;
</summary><category term="python"></category><category term="django"></category><category term="tools"></category></entry><entry><title>A Public Service Message to the Python Community</title><link href="http://pydanny.com/a-public-service-message-to-the-python-community.html" rel="alternate"></link><updated>2012-08-20T14:00:00-07:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2012-08-20:a-public-service-message-to-the-python-community.html</id><summary type="html">&lt;p&gt;Hi, I'm Daniel Greenfeld. You might know me from my &lt;a class="reference external" href="http://pydanny.com"&gt;blog&lt;/a&gt;. I'm here to talk to you about a very import subject: &lt;strong&gt;Submitting your talk early to PyCon US.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Last year there were hundreds of talks were submitted for just a very few speaking slots. &lt;strong&gt;Unpaid volunteers&lt;/strong&gt; labored for hours before and after their normal jobs reviewing and debating which talks were to get in. The volume of talks combined with simple reviewer fatigue means that earlier submitted talks got more attention.&lt;/p&gt;
&lt;p&gt;This year, following the pattern of previous years, we're going to have 25% more talk submissions.&lt;/p&gt;
&lt;div class="section" id="please-don-t-leave-your-poor-talk-or-tutorial-out-in-the-cold"&gt;
&lt;h2&gt;Please don't leave your poor talk or tutorial out in the cold.&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Submit early.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Help us fix the problem in one of two ways:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2013/speaking/cfp"&gt;Submit your talk as early as possible&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://pycon.blogspot.com/2012/07/i-want-you-for-pycon-program-commitee.html"&gt;Help review PyCon US talks&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="section" id="production-notes-for-this-service-message"&gt;
&lt;h2&gt;Production notes for this service message&lt;/h2&gt;
&lt;p&gt;I've always wanted to do one of those TV public service messages done by B or C grade actors. As a D-grade blogger I thought I might be a pretty good match for the role. :-)&lt;/p&gt;
&lt;/div&gt;
</summary><category term="python"></category><category term="pycon"></category><category term="django"></category></entry><entry><title>Django Requirements 2012-08-15</title><link href="http://pydanny.com/django-requirements-2012-08-15.html" rel="alternate"></link><updated>2012-08-15T18:00:00-07:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2012-08-15:django-requirements-2012-08-15.html</id><summary type="html">&lt;p&gt;A little over three months ago &lt;a class="reference external" href="http://pydanny.com/django-requirements-for-a-project.html"&gt;I blogged about my preferred requirements&lt;/a&gt; list.
It's now nearly the eve of &lt;a class="reference external" href="http://djangodash.com"&gt;Django Dash&lt;/a&gt;, and I feel it's time to update the list.
I'm going to bump the versions on some of the existing packages and add some new ones to the list.&lt;/p&gt;
&lt;div class="section" id="new-packages"&gt;
&lt;h2&gt;New Packages&lt;/h2&gt;
&lt;div class="section" id="django-braces-0-1-3"&gt;
&lt;h3&gt;&lt;a class="reference external" href="http://pypi.python.org/pypi/django-braces/"&gt;django-braces==0.1.3&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Want to use Django Class Based Views but unhappy with the missing components like &lt;tt class="docutils literal"&gt;LoginRequiredMixin&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;SelectRelatedMixin&lt;/tt&gt;, and even &lt;tt class="docutils literal"&gt;StaffuserRequiredMixin&lt;/tt&gt;? Not to worry, as this library will make Django CBVs &lt;strong&gt;134% easier to use&lt;/strong&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="django-secure-0-1-2"&gt;
&lt;h3&gt;&lt;a class="reference external" href="http://pypi.python.org/pypi/django-secure/"&gt;django-secure==0.1.2&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Django is rather secure, but there is a checklist of things that the security experts want you to do.
Save yourself forgetting something and use this library to do all those little things.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="django-profiletools-0-1-3"&gt;
&lt;h3&gt;&lt;a class="reference external" href="http://pypi.python.org/pypi/django-profiletools/"&gt;django-profiletools==0.1.3&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Have you ever used the django-debug-toolbar and noticed that you did that same &lt;tt class="docutils literal"&gt;request.user.get_profile()&lt;/tt&gt; call
a dozen times? Ever want to just call that once? This library, by yours truly, resolves the issue. It loads the user's
profile object once, and then passes it down the request chain.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr class="docutils" /&gt;
&lt;div class="section" id="existing-packages"&gt;
&lt;h2&gt;Existing Packages&lt;/h2&gt;
&lt;div class="section" id="django-1-4-1"&gt;
&lt;h3&gt;&lt;a class="reference external" href="http://pypi.python.org/pypi/Django/1.4.1"&gt;Django==1.4.1&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If you need sessions, forms, templates, and relational database models, then I can argue you've got the ideal &lt;a class="reference external" href="http://djangoproject.com"&gt;Django&lt;/a&gt; project.
Make certain you are running the latest Django version (1.4.1). If you have any reason to stick to the Django 1.3 series, I advise
bumping it up to Django 1.3.2.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="psycopg2-2-4-5"&gt;
&lt;h3&gt;&lt;a class="reference external" href="http://pypi.python.org/pypi/psycopg2"&gt;psycopg2==2.4.5&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This is the database connector to PostgreSQL, which is what you should be using. Django is known for playing 'nicer'
with PostgreSQL than say... MySQL.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="django-debug-toolbar-0-9-4"&gt;
&lt;h3&gt;&lt;a class="reference external" href="http://pypi.python.org/pypi/django-debug-toolbar"&gt;django-debug-toolbar==0.9.4&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Because not using this tool is insane.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="django-extensions-0-8"&gt;
&lt;h3&gt;&lt;a class="reference external" href="http://pypi.python.org/pypi/django-extensions"&gt;django-extensions==0.8&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Because amongst other things this library gives you, I never want to write my own &lt;tt class="docutils literal"&gt;TimeStampedModel&lt;/tt&gt; ever again. :-)&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="south-0-7-6"&gt;
&lt;h3&gt;&lt;a class="reference external" href="http://pypi.python.org/pypi/South"&gt;South==0.7.6&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Django gives you the freedom to migrate data in the way you want. The way I want to do it is via South.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="django-registration-0-8-0"&gt;
&lt;h3&gt;&lt;a class="reference external" href="http://pypi.python.org/pypi/django-registration"&gt;django-registration==0.8.0&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The common go-to tool for non-Social registration.&lt;/p&gt;
&lt;p&gt;This is a very solid tool, but you do have to make your own templates or find someone's fork that has a copy of templates that match.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="django-social-auth-0-7-4"&gt;
&lt;h3&gt;django-social-auth== 0.7.4&lt;/h3&gt;
&lt;p&gt;Want to authenticate via Twitter, Facebook, or GitHub? Then use this very useful package.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="django-floppyforms-1-0"&gt;
&lt;h3&gt;&lt;a class="reference external" href="http://pypi.python.org/pypi/django-floppyforms"&gt;django-floppyforms==1.0&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;An excellent tool for making your forms HTML5-ish out of the box. It allows full control of form rendering in the templates.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="django-crispy-forms-1-1-4"&gt;
&lt;h3&gt;&lt;a class="reference external" href="http://pypi.python.org/pypi/django-crispy-forms"&gt;django-crispy-forms==1.1.4&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The child of my own django-uni-forms, this will let me create forms using div-based controls super fast, and do layout customizations if I need them.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="django-heroku-postgresify-0-2"&gt;
&lt;h3&gt;&lt;a class="reference external" href="http://pypi.python.org/pypi/django-heroku-postgresify"&gt;django-heroku-postgresify==0.2&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This tool makes getting the PostGreSQL settings out of Heroku trivial.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="django-heroku-memcacheify-0-3"&gt;
&lt;h3&gt;&lt;a class="reference external" href="http://pypi.python.org/pypi/django-heroku-memcacheify"&gt;django-heroku-memcacheify==0.3&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This tool makes getting the memcache settings for Heroku trivial.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="gunicorn-0-14-6"&gt;
&lt;h3&gt;&lt;a class="reference external" href="http://pypi.python.org/pypi/gunicorn"&gt;gunicorn==0.14.6&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;All the cool kids who play in devops swear by Gunicorn.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr class="docutils" /&gt;
&lt;div class="section" id="installing-the-above-packages"&gt;
&lt;h2&gt;Installing the above packages&lt;/h2&gt;
&lt;p&gt;Never copy/paste these libraries directly into your projects. Do it the right way: &lt;strong&gt;use proper Python dependency management&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Create a &lt;tt class="docutils literal"&gt;requirements.txt&lt;/tt&gt; file and install them as proper dependencies. The file should contain the following text:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
Django==1.4.1
South==0.7.5
django-braces==0.1.3
django-crispy-forms==1.1.4
django-debug-toolbar==0.9.4
django-extensions==0.8
django-floppyforms==1.0
django-social-auth==0.7.4
django-heroku-memcacheify==0.3
django-heroku-postgresify==0.2
django-profiletools==0.1.3
django-registration==0.8.0
django-secure==0.1.2
gunicorn==0.14.2
psycopg2==2.4.5
&lt;/pre&gt;
&lt;p&gt;Once you have that, you install them thus in your &lt;a class="reference external" href="http://pypi.python.org/pypi/virtualenv"&gt;virtualenv&lt;/a&gt;:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
pip install -r requirements.txt
&lt;/pre&gt;
&lt;p&gt;Now that I have all this, it's time to code!&lt;/p&gt;
&lt;/div&gt;
</summary><category term="python"></category><category term="django"></category><category term="djangodash"></category><category term="setup"></category></entry><entry><title>Curiosity has landed!</title><link href="http://pydanny.com/curiosity-has-landed.html" rel="alternate"></link><updated>2012-08-06T08:00:00-07:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2012-08-06:curiosity-has-landed.html</id><summary type="html">&lt;p&gt;I'm terribly proud of what was accomplished last night: A car-sized robot weighing a whopping 8,580 pounds (3,893 kg) was landed on Mars. It is packed with scientific packages that will expand our knowledge of Mars, and has the power to use them for at least 14 years.&lt;/p&gt;
&lt;p&gt;Simply put, this is an incredible step forward.&lt;/p&gt;
&lt;a class="reference external image-reference" href="http://en.wikipedia.org/wiki/File:Mars_Science_Laboratory_Curiosity_rover.jpg"&gt;&lt;img alt="http://upload.wikimedia.org/wikipedia/commons/thumb/a/a9/Mars_Science_Laboratory_Curiosity_rover.jpg/800px-Mars_Science_Laboratory_Curiosity_rover.jpg" class="align-center" id="artist-impression-of-curiosity-on-mars" src="http://upload.wikimedia.org/wikipedia/commons/thumb/a/a9/Mars_Science_Laboratory_Curiosity_rover.jpg/800px-Mars_Science_Laboratory_Curiosity_rover.jpg" /&gt;&lt;/a&gt;
&lt;p&gt;As an American, I'm proud that our nation is capable of putting together such amazing feats of engineering and science. People from a diverse arrangement of backgrounds and origins came together to make something incredible happen.&lt;/p&gt;
&lt;p&gt;As a human being, I'm proud that we have yet again proven that we are still capable of working together to make amazing things happen.&lt;/p&gt;
&lt;p&gt;As someone who grew up in the 1970s, and someone who is proud to have worked at &lt;a class="reference external" href="http://www.nasa.gov"&gt;NASA&lt;/a&gt; for over 5 years, this is my American dream.&lt;/p&gt;
&lt;div class="section" id="going-forward"&gt;
&lt;h2&gt;Going Forward&lt;/h2&gt;
&lt;p&gt;Curiosity is about to do amazing things and will tell a story to us that we'll never forget.&lt;/p&gt;
&lt;p&gt;Alas, NASA is a terribly easy target for politicians. It's budget has shrank to a small fraction of the it's early 1970s high, and it remains a target to this day. While the politicians congratulate the JPL team on one hand, they are also cutting the JPL budget in a short-sighted attempt to make themselves look good. History will not be kind to such politicians.&lt;/p&gt;
&lt;p&gt;The answers to our questions and our problems will be found in the heavens. Let's increase NASA funding and populate the world with miracles of science.&lt;/p&gt;
&lt;/div&gt;
</summary><category term="nasa"></category><category term="science"></category><category term="python"></category><category term="django"></category></entry><entry><title>Deadline for DjangoCon Financial Aid requests is tomorrow!</title><link href="http://pydanny.com/deadline-for-djangocon-financial-aid-requests-is-tomorrow.html" rel="alternate"></link><updated>2012-08-02T21:30:00-07:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2012-08-02:deadline-for-djangocon-financial-aid-requests-is-tomorrow.html</id><summary type="html">&lt;p&gt;For 2012, &lt;a class="reference external" href="http://www.djangocon.us/"&gt;DjangoCon US&lt;/a&gt; has moved to Washington, DC, and everyone is invited! If you need financial support to get there, the &lt;a class="reference external" href="https://www.djangoproject.com/foundation/"&gt;Django Software Foundation&lt;/a&gt; and &lt;a class="reference external" href="http://pyladies.com/"&gt;PyLadies&lt;/a&gt; have paired with a number of forward thinking sponsors to help get you there. All genders are eligible for assistance, so don't hesitate to submit your application.&lt;/p&gt;
&lt;p&gt;The deadline for financial aid requests is tomorrow, Friday, August 3rd by 11:59pm Eastern Time.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.google.com/spreadsheet/viewform?formkey=dDc1X2hrUGJVRGdEWnRjTklxR2tSNFE6MQ#gid=0"&gt;Apply while you still have time!&lt;/a&gt;&lt;/p&gt;
</summary><category term="django"></category><category term="djangocon"></category><category term="pyladies"></category><category term="dsf"></category></entry><entry><title>Attaching custom exceptions to functions and classes</title><link href="http://pydanny.com/attaching-custom-exceptions-to-functions-and-classes.html" rel="alternate"></link><updated>2012-08-02T09:30:00-07:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2012-08-02:attaching-custom-exceptions-to-functions-and-classes.html</id><summary type="html">&lt;p&gt;Having too many custom exceptions on a project can be a pain, but a few choices ones are really nice. The problem is that in complex libraries having to import both functions and exceptions becomes a drag. To mitigate having to remember to import custom exceptions, this is a handy pattern you can use in a project and can be done on both functions and classes.&lt;/p&gt;
&lt;div class="section" id="attaching-a-custom-exception-to-a-function"&gt;
&lt;h2&gt;Attaching a custom exception to a function&lt;/h2&gt;
&lt;p&gt;This works because &lt;a class="reference external" href="http://python.org"&gt;Python&lt;/a&gt; functions are first-class objects. They can be passed around as things, and in this case, have things assigned to them.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# logic.py&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DoesNotCompute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ne"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot; Easy to understand naming conventions work best! &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;this_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot; This function only works on numbers.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="ne"&gt;TypeError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;DoesNotCompute&lt;/span&gt;

&lt;span class="c"&gt;# Assign DoesNotCompute exception to this_function&lt;/span&gt;
&lt;span class="n"&gt;this_function&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DoesNotCompute&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DoesNotCompute&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now I can import the function, and it won't just through &lt;tt class="docutils literal"&gt;DoesNotCompute&lt;/tt&gt; exceptions, it will also carry the function along with the import:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;logic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;this_function&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;this_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mi"&gt;3125&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;this_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;4.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mf"&gt;869.8739233809259&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;this_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;will throw an error.&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Traceback&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;most&lt;/span&gt; &lt;span class="n"&gt;recent&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;&amp;lt;input&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;module&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;logic.py&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;this_function&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;DoesNotCompute&lt;/span&gt;
&lt;span class="n"&gt;DoesNotCompute&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Alright, that doesn't seem like much, but let's add in some exception handling:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;     &lt;span class="n"&gt;this_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;is an example&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;this_function&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DoesNotCompute&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;     &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;See what attaching custom exceptions to functions can do?&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;See&lt;/span&gt; &lt;span class="n"&gt;what&lt;/span&gt; &lt;span class="n"&gt;attaching&lt;/span&gt; &lt;span class="n"&gt;custom&lt;/span&gt; &lt;span class="n"&gt;exceptions&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;functions&lt;/span&gt; &lt;span class="n"&gt;can&lt;/span&gt; &lt;span class="n"&gt;do&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="attaching-the-custom-exception-to-a-class"&gt;
&lt;h2&gt;Attaching the custom exception to a class&lt;/h2&gt;
&lt;p&gt;All we have to do is enhance our existing &lt;cite&gt;logic.py&lt;/cite&gt; file by adding &lt;tt class="docutils literal"&gt;ThisClass&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# logic.py&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DoesNotCompute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ne"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot; Easy to understand naming conventions work best! &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="c"&gt;# removed the function example for clarity&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ThisClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c"&gt;# Since the DoesNotCompute exception exists, let&amp;#39;s just assign it&lt;/span&gt;
    &lt;span class="c"&gt;# as an attribute of ThisClass&lt;/span&gt;
    &lt;span class="n"&gt;DoesNotCompute&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DoesNotCompute&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;this_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot; This method only works on numbers.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
        &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="ne"&gt;TypeError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;DoesNotCompute&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now to demonstrate in the shell (Python REPL for the semantic purists):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;t&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ThisClass&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;this_class&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ThisClass&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;this_class&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;this_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;3.3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mf"&gt;51.415729444066585&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;this_class&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;this_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;Jack Diederich warned against custom exceptions&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Traceback&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;most&lt;/span&gt; &lt;span class="n"&gt;recent&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;&amp;lt;input&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;module&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;logic.py&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;this_method&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;DoesNotCompute&lt;/span&gt;
&lt;span class="n"&gt;DoesNotCompute&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;     &lt;span class="n"&gt;this_class&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;this_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;I need to write a follow-up on my OAuth post&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;ThisClass&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DoesNotCompute&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;     &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;Waiting to see how the OAuth stuff pans out&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;Waiting&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;see&lt;/span&gt; &lt;span class="n"&gt;how&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;OAuth&lt;/span&gt; &lt;span class="n"&gt;stuff&lt;/span&gt; &lt;span class="n"&gt;pans&lt;/span&gt; &lt;span class="n"&gt;out&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="admonition-don-t-go-crazy"&gt;
&lt;h2&gt;Admonition: Don't go crazy&lt;/h2&gt;
&lt;p&gt;Rather than use this trick all over the place, considering using it in a few places to powerful effect. For example, &lt;a class="reference external" href="http://djangoproject.com"&gt;Django&lt;/a&gt; uses it only in a few places, and publicly only on &lt;tt class="docutils literal"&gt;MyModelClass.DoesNotExist&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;MyModelClass.MultipleObjectsReturned&lt;/tt&gt;. By limiting Django's use of this technique, Django libraries are that much easier to comprehend. In this case, less complexity means more.&lt;/p&gt;
&lt;p&gt;I say this because this pattern lends itself to creating custom exceptions to the point of effectively replacing Python's stock exceptions with your own. This  makes for harder-to-maintain and harder-to-learn projects.&lt;/p&gt;
&lt;p&gt;Not that I've ever done that. Ahem.&lt;/p&gt;
&lt;/div&gt;
</summary><category term="python"></category><category term="functions"></category><category term="howto"></category><category term="django"></category></entry><entry><title>Django Update View without slug in the url</title><link href="http://pydanny.com/django-update-view-without-slug-in-the-url.html" rel="alternate"></link><updated>2012-07-28T09:30:00-07:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2012-07-28:django-update-view-without-slug-in-the-url.html</id><summary type="html">&lt;p&gt;Today I wanted to use the Django Class Based View (CBV) UpdateView but without a slug identifier in the URL. For example, instead of &lt;tt class="docutils literal"&gt;/profiles/pydanny/&lt;/tt&gt; I would go to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/my-crazy-profile/&lt;/span&gt;&lt;/tt&gt;. Also, I needed to force authentication.&lt;/p&gt;
&lt;p&gt;I've done this with Django functional views a few times times, but today I did it in Django. This is what I did:&lt;/p&gt;
&lt;div class="section" id="added-django-braces-to-my-project"&gt;
&lt;h2&gt;1. Added django-braces to my project&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://twitter.com/kennethlove"&gt;Kenneth Love&lt;/a&gt; and &lt;a class="reference external" href="https://twitter.com/tehjones"&gt;Chris Jones&lt;/a&gt;' awesome &lt;a class="reference external" href="https://github.com/brack3t/django-braces/"&gt;django-braces&lt;/a&gt; package has some very handy mixins for working with Django CBVs. Kenneth and Chris really understand CBVs, specifically on how to extend them, and have provided a bunch of really useful utility methods in the django-braces library. Yeah, I could figure this stuff out on my own, but since those guys already did the hard work I might as well just lean on them.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;pip install django-braces&lt;span class="o"&gt;==&lt;/span&gt;0.1.3
&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# settings.py&lt;/span&gt;
&lt;span class="n"&gt;INSTALLED_APPS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="s"&gt;&amp;#39;braces&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="wrote-the-view"&gt;
&lt;h2&gt;2. Wrote the view&lt;/h2&gt;
&lt;p&gt;Assuming a very simple profile Model and Form (which they weren't - but that's not what this post is about), this is how I implemented the view:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# profiles/views.py&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.views.generic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;UpdateView&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;braces.views&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;LoginRequiredMixin&lt;/span&gt;  &lt;span class="c"&gt;# handles authentication&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;profiles.forms&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ProfileForm&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;profiles.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Profile&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProfileUpdateView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LoginRequiredMixin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;UpdateView&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;form_class&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ProfileForm&lt;/span&gt;
    &lt;span class="n"&gt;success_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;/my-crazy-profile/&amp;quot;&lt;/span&gt;  &lt;span class="c"&gt;# You should be using reverse here&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Profile&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="wrote-the-urlconf"&gt;
&lt;h2&gt;3. Wrote the URLconf&lt;/h2&gt;
&lt;p&gt;The URL pretty much wrote itself:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.conf.urls.defaults&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;patterns&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;profiles&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;views&lt;/span&gt;

&lt;span class="n"&gt;urlpatterns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;patterns&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;regex&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;r&amp;#39;^my-crazy-profile/$&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ProfileUpdateView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;as_view&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;profile_update&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="closing-thoughts"&gt;
&lt;h2&gt;Closing Thoughts&lt;/h2&gt;
&lt;p&gt;For a while, I've used django-braces for anything that involves CBVs. I can't imagine working on projects using CBVs without them. In fact, some of the mixins such as &lt;tt class="docutils literal"&gt;LoginRequiredMixin&lt;/tt&gt; are things that I could argue ought to be in core Django.&lt;/p&gt;
&lt;p&gt;This pattern really nails the sweet spot of Django CBVs. Thanks to the use of mixins and model forms, I get an amazing amount of stuff done in a 5 line CBV.&lt;/p&gt;
&lt;/div&gt;
</summary><category term="python"></category><category term="django"></category><category term="howto"></category><category term="class-based-views"></category></entry><entry><title>July 15th, 2012 LA Open Source Recap</title><link href="http://pydanny.com/july-15th-2012-la-open-source-recap.html" rel="alternate"></link><updated>2012-07-16T18:00:00-07:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2012-07-16:july-15th-2012-la-open-source-recap.html</id><summary type="html">&lt;p&gt;On July 15th, 2012, at the &lt;a class="reference external" href="http://www.meetup.com/LA-Hackathons/events/64542582/"&gt;July LA Hackathons Open Source event&lt;/a&gt;, over 60 &lt;a class="reference external" href="http://python.org"&gt;Python&lt;/a&gt;, &lt;a class="reference external" href="http://djangoproject.com"&gt;Django&lt;/a&gt;, &lt;a class="reference external" href="http://www.ruby-lang.org/"&gt;Ruby&lt;/a&gt;, &lt;a class="reference external" href="http://rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt;, &lt;a class="reference external" href="http://www.php.net/"&gt;PHP&lt;/a&gt;, &lt;a class="reference external" href="http://en.wikipedia.org/wiki/JavaScript"&gt;JavaScript&lt;/a&gt;, &lt;a class="reference external" href="http://nodejs.org/"&gt;Node.js&lt;/a&gt;, &lt;a class="reference external" href="http://www.perl.org/"&gt;Perl&lt;/a&gt;, and &lt;a class="reference external" href="http://clojure.org"&gt;Clojure&lt;/a&gt; developers arrived to work on a variety of projects. We went from 10 AM to 10 PM, and there was much coding and learning done by all. There was a very powerful vibe shared by nearly everyone there, and it was great to see so many people from different personal and open source backgrounds working together and having a great time as a group.&lt;/p&gt;
&lt;div class="section" id="filtering-out-distractions"&gt;
&lt;h2&gt;Filtering out distractions&lt;/h2&gt;
&lt;p&gt;We made some changes to our proceedings for this event, entirely because last time with 'distractions' that caused some issues. In a nutshell, here is 50% of what we did:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;A clear statement in the event description and follow up emails that this event was for developers and designers only.&lt;/li&gt;
&lt;li&gt;Laptops were an absolute requirement for entry into the event.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;We also rolled in a couple other tricks I'm not going to write down. If you see me in person, ask away. The results were near perfect, and we won't hesitate to use these techniques again.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="sponsors"&gt;
&lt;h2&gt;Sponsors&lt;/h2&gt;
&lt;p&gt;We let attendees know which sponsors were interested in potential new hires, in this case, &lt;a class="reference external" href="http://originatelabs.com"&gt;Originate&lt;/a&gt; and &lt;a class="reference external" href="http://cars.com"&gt;Cars.com&lt;/a&gt;. This sort of low-key technique helps us land sponsors but doesn't annoy attendees. Speaking of sponsors, here they are in alphabetical order:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://cars.com"&gt;Cars.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://cartwheelweb.com"&gt;Cartwheel Web&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://heroku.com"&gt;Heroku&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://originatelabs.com"&gt;Originate&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="code-projects-worked-on"&gt;
&lt;h2&gt;Code/Projects worked on&lt;/h2&gt;
&lt;p&gt;Next time I'm going to be a lot more careful about getting down the details of what people did. Maybe a signup sheet or an online form? Heck, sounds like a great quick project for next time!&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://djangoproject.com"&gt;Django&lt;/a&gt; (see below for details)&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://tglines.github.com/dynasaur/"&gt;Dynasaur&lt;/a&gt; (Node.js/DynamoDB ORM)&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/saltstack/salt"&gt;Salt Stack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/philfree/meteordraw"&gt;meteordraw&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/harph/pyit"&gt;pyit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/symkat/DBIx-Config"&gt;DBIx::Config&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Clojure Tutorials&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/andrewvc/engulf"&gt;engulf&lt;/a&gt; (Clojure load testing tool that got 2 more tests)&lt;/li&gt;
&lt;li&gt;HTML5&lt;/li&gt;
&lt;li&gt;PHP&lt;/li&gt;
&lt;li&gt;Lots more!&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="django-sprints"&gt;
&lt;h2&gt;Django Sprints&lt;/h2&gt;
&lt;p&gt;My conservative estimate is that we had 12 people working on Django or Django related projects. That's at least 20% of attendees. Unfortunately, because I'm not a Django core developer, I wasn't reviewing commits; so I am not entirely sure what was being worked on. I do know that I wasn't the only person to commit to core Django.&lt;/p&gt;
&lt;p&gt;As for me, I continued my efforts started at DjangoCon Europe to refactor the &lt;a class="reference external" href="https://docs.djangoproject.com/en/dev/topics/class-based-views/"&gt;Class&lt;/a&gt; &lt;a class="reference external" href="https://docs.djangoproject.com/en/dev/ref/class-based-views/"&gt;Based&lt;/a&gt; &lt;a class="reference external" href="https://docs.djangoproject.com/en/dev/ref/class-based-views/mixins/"&gt;Views&lt;/a&gt; documentation. I got in two pull requests and finally managed to badly teach myself how to use git rebase.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;note&lt;/strong&gt;: I want to make it exceedingly clear that I'm not the only one working the CBV doc refactor. I'm just one of the fold.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="socializing"&gt;
&lt;h2&gt;Socializing&lt;/h2&gt;
&lt;p&gt;During meals we tried to keep people's hands off the keyboard. Specifically everyone got a chance to state their name, toolset they were working with, and something interesting/embarrassing about themselves. Three of the more memorable ones:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;An 8 year old attendee wrote his first 4 PHP programs!&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://twitter.com/sym_kat"&gt;sym_kat&lt;/a&gt; is invited to speak at the next London Perl Workshop.&lt;/li&gt;
&lt;li&gt;Someone employed at SpaceX took Zed Shaw's &lt;a class="reference external" href="http://learnpythonthehardway.org/"&gt;LPTHW&lt;/a&gt; class taught by the man himself at &lt;a class="reference external" href="http://cartwheelweb.com"&gt;Cartwheel Web&lt;/a&gt; HQ in 2011 got himself moved from the C# to the Python team. Go open source!&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="closing-thoughts"&gt;
&lt;h2&gt;Closing thoughts&lt;/h2&gt;
&lt;p&gt;There were a few glitches, but nothing major. Most of those glitches stem from us coming off two months of helping organize multiple events while traveling literally around the world. I think things would have been better if I had delegated more to the right people.&lt;/p&gt;
&lt;p&gt;For the most part, there was this electrifying energy that had people focused and working on what they wanted all day. Yet it wasn't all heads-down-coding, their was some good coder-to-coder discussion and fun. The result is at the end of the day people seemed refreshed and empowered, wanting another day as soon as possible. We hope to be able to catch this feeling at future events.&lt;/p&gt;
&lt;p&gt;Which means we're plotting the next event now. If you are interested in providing a venue or sponsoring the event, let me know at &lt;a class="reference external" href="mailto:pydanny&amp;#64;cartwheelweb.com"&gt;pydanny&amp;#64;cartwheelweb.com&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: Corrected the details about the SpaceX guy.&lt;/p&gt;
&lt;/div&gt;
</summary><category term="python"></category><category term="django"></category><category term="php"></category><category term="la"></category><category term="clojure"></category><category term="perl"></category><category term="ruby"></category><category term="nodejs"></category><category term="meteor"></category></entry><entry><title>Simple HTTP Basic Auth Wall</title><link href="http://pydanny.com/simple-http-basic-auth-wall.html" rel="alternate"></link><updated>2012-07-09T12:00:00-07:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2012-07-09:simple-http-basic-auth-wall.html</id><summary type="html">&lt;p&gt;I have a client who wanted their entire unlaunched public content site quickly but temporarily blocked for a short period of time. He wanted a universal password so he could send the site to reviewers, done quickly, and nothing else. In a few days the site will launch, and even if someone got through the authentication, nothing bad will happen except for an early visitor. So we determined this was a job for a very simple &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Basic_access_authentication"&gt;Basic access authentication&lt;/a&gt; implementation.&lt;/p&gt;
&lt;p&gt;I asked around and &lt;a class="reference external" href="http://jacobian.org/"&gt;Jacob Kaplan-Moss&lt;/a&gt; gave me this awesome snippet using &lt;a class="reference external" href="http://pypi.python.org/pypi/barrel"&gt;barrel&lt;/a&gt; that I pasted right into the bottom of the &lt;a class="reference external" href="http://djangoproject.com"&gt;Django&lt;/a&gt; 1.4-style application's &lt;tt class="docutils literal"&gt;wsgi.py&lt;/tt&gt; file.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# Add to the bottom of your wsgi.py file&lt;/span&gt;
&lt;span class="c"&gt;# Don&amp;#39;t forget to add barrel to your requirements!&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;barrel&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;cooper&lt;/span&gt;

&lt;span class="n"&gt;REALM&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;PRIVATE&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;USERS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;spam&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;eggs&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;

&lt;span class="n"&gt;application&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cooper&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;basicauth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;USERS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;realm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;REALM&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;get_wsgi_application&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This took all of 5 minutes to implement and launch. The result is that the first time you visit the site the login prompt appears. If you enter 'spam' and 'eggs' then you can see the site fine.&lt;/p&gt;
&lt;p&gt;It worked and the customer was happy.&lt;/p&gt;
&lt;p&gt;Will this block a concerted penetration attempt? Of course not. If the site has/had critical or identifying information it would be implemented with &lt;a class="reference external" href="https://en.wikipedia.org/wiki/HTTPS"&gt;HTTPS&lt;/a&gt;. Implementing a Django site with HTTPS is something I've done many times now, but this use case was 'do it fast, easy, and make it temporary'.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Moral of the story:&lt;/strong&gt; Pay attention to your requirements.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note :&lt;/strong&gt; As this is just adding in some WSGI middleware, this should work without much modification in Flask, Pyramid, and other WSGI compliant web frameworks.&lt;/p&gt;
</summary><category term="python"></category><category term="django"></category><category term="wsgi"></category><category term="howto"></category></entry><entry><title>PyCon Philippines 2012 Day 2</title><link href="http://pydanny.com/pycon-philippines-2012-day-2.html" rel="alternate"></link><updated>2012-07-05T12:00:00-07:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2012-07-05:pycon-philippines-2012-day-2.html</id><summary type="html">&lt;p&gt;The second day of &lt;a class="reference external" href="http://ph.pycon.org"&gt;PyCon Philippines 2012&lt;/a&gt; had a really good turnout. My unofficial estimate is that we had about 90% of the attendees from the first day attend (with the unfortunate exception of most of the faculty and students of &lt;a class="reference external" href="http://www.13hq.com/"&gt;Agoo Computer College&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;The day started with...&lt;/p&gt;
&lt;div class="section" id="lightning-talks"&gt;
&lt;h2&gt;Lightning Talks&lt;/h2&gt;
&lt;p&gt;Unfortunately I don't normally take notes on lightning talks. I'm kicking myself now. &lt;strong&gt;Really hard.&lt;/strong&gt; I'll try and relate some of the talks:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Import this and &lt;a class="reference external" href="http://pypi.python.org/pypi/that"&gt;that&lt;/a&gt;, a parody talk by Daniel Greenfeld (me). &lt;a class="reference external" href="https://twitter.com/malcolmt/status/219244338029412352"&gt;Malcolm comment on it.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Getting into space using weather balloons by Frank Pohlmann&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/audreyr/ponystrap"&gt;Ponystrap&lt;/a&gt; by &lt;a class="reference external" href="http://audreymroy.com"&gt;Audrey Roy&lt;/a&gt; (&lt;a class="reference external" href="http://klewel.com/conferences/djangocon-2012/index.php?talkID=31"&gt;video from DjangoCon Europe&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Call for &lt;a class="reference external" href="http://en.wikipedia.org/wiki/Tagalog"&gt;Tagalog&lt;/a&gt; and other &lt;a class="reference external" href="http://en.wikipedia.org/wiki/Philippine_languages"&gt;Philippine languages&lt;/a&gt; translation of &lt;a class="reference external" href="http://djangoproject.com"&gt;Django&lt;/a&gt; by Malcolm Tredinnick&lt;/li&gt;
&lt;li&gt;The obligatory PyCon lighting talk on Vim by &lt;a class="reference external" href="https://twitter.com/bry_bibat"&gt;Bryan Bibat&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://openerp.com/"&gt;OpenERP&lt;/a&gt; by &lt;a class="reference external" href="https://twitter.com/PliniusSecundus"&gt;Frank&lt;/a&gt; &lt;a class="reference external" href="http://www.auberonsolutions.com/"&gt;Pohlmann&lt;/a&gt; and &lt;a class="reference external" href="http://www.linkedin.com/pub/ann-tan-pohlmann/4/a30/233"&gt;Ann Tan-Pohlmann&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;A parody talk by &lt;a class="reference external" href="https://twitter.com/mrvaldez"&gt;Sony Valdez&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then it was on to...&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="sprints-and-tutorials"&gt;
&lt;h2&gt;Sprints and Tutorials&lt;/h2&gt;
&lt;blockquote class="epigraph"&gt;
&lt;p&gt;Encouraged at #pyconph seeing so many people declaring themselves beginners and then diving in. Enthusiasm was a bit contagious.&lt;/p&gt;
&lt;p class="attribution"&gt;&amp;mdash;&lt;a class="reference external" href="https://twitter.com/malcolmt"&gt;Malcolm Tredinnick&lt;/a&gt; on &lt;a class="reference external" href="https://twitter.com/malcolmt/status/219425413301157889"&gt;twitter&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Primary funding for the sprints came from the &lt;a class="reference external" href="https://www.djangoproject.com/foundation"&gt;Django Software Foundation&lt;/a&gt; and &lt;a class="reference external" href="http://pythonsprints.com/"&gt;Python Sprints&lt;/a&gt;. That funding went towards food, drinks, and various logistics for handling the estimated 200+ attendee turnout.  Things sprinted on:&lt;/p&gt;
&lt;div class="section" id="id1"&gt;
&lt;h3&gt;Django&lt;/h3&gt;
&lt;p&gt;Django had it's own dedicated and very full room (no more chairs could fit so I sat on the floor), with Malcolm Tredinnick leading the effort, with &lt;a class="reference external" href="http://marconijr.com/"&gt;Marconi&lt;/a&gt; &lt;a class="reference external" href="https://twitter.com/marconimjr"&gt;Moreto&lt;/a&gt; helping out. It turned into mostly an effort to get a lot of people kick-started in Django. What was very heartening was watching people race through the tutorials on their own, and then work on projects using the framework.&lt;/p&gt;
&lt;p&gt;I suspect next year the sprints will see a lot of submissions to Django core.&lt;/p&gt;
&lt;p&gt;I had hoped to continue my work on Class Based View documentation, but it was wisely pointed out that I should focus more on helping others get moving in Django and other projects.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="ansible"&gt;
&lt;h3&gt;Ansible&lt;/h3&gt;
&lt;p&gt;&lt;a class="reference external" href="http://capsunlock.net"&gt;Rodney&lt;/a&gt; &lt;a class="reference external" href="https://github.com/cocoy"&gt;Quillo&lt;/a&gt; led the sprint on the &lt;a class="reference external" href="http://ansible.github.com/"&gt;Ansible&lt;/a&gt; tool of which he is so fond. About seven people fond of engineering joined him. They seemed very productive and happy by day's end.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="pymongo"&gt;
&lt;h3&gt;pymongo&lt;/h3&gt;
&lt;p&gt;A number of developers working on embedded devices gathered to work out an edge case issue with pymongo. I wish I knew more about their efforts, but I can tell you that this sort of very serious engineering effort is very common amongst professional Filipino developers. Because of geography, telecommunications and embedded devices are much more prevalent in the island nation.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="other-efforts"&gt;
&lt;h3&gt;Other efforts&lt;/h3&gt;
&lt;p&gt;Again I'm kicking myself. There were a ton of other development going on and I didn't document any of it. Certainly I was busy here and there helping out, but this is the sort of thing you need to document at the moment. Next time I assure you I will be very diligent about recording the efforts of so many.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="tutorial-room"&gt;
&lt;h3&gt;Tutorial Room&lt;/h3&gt;
&lt;p&gt;About half the people stayed in what I dubbed the tutorial room. This is where speakers took turns going over material we had brought to the conference. Attendees followed along, and the diligence and focus in the room was very impressive. The tutorials/talks included:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Intro to Python using Turtle by Sony Valdez&lt;/li&gt;
&lt;li&gt;Introduction to git and github by Bryan Bibat&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.slideshare.net/pydanny/intro-to-python-11186202"&gt;21 Cool Things You Can Do With Python&lt;/a&gt; by Daniel Greenfeld (me)&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="food-and-drinks"&gt;
&lt;h2&gt;Food and drinks&lt;/h2&gt;
&lt;p&gt;I mean to mention that the breakfast, lunch, and snacks at PyCon Philippines 2012 were pretty good. The logistic chairs had decided rather than gamble on the usual sort of over-priced and not-so-good professional catering service that most conferences rely on to the dismay of... well... everyone, to go with local restaurants.&lt;/p&gt;
&lt;p&gt;For dinner people went out on their own. We were lucky enough to go to Pino in Quezon City both times. The Kare-Kareng Bagnet was really tasty.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="conference-end"&gt;
&lt;h2&gt;Conference End&lt;/h2&gt;
&lt;p&gt;The conference chair, Frank Pohlmann, gave us a few well spoken words about how wonderful the event was to run and host. How gratifying it was to see the enthusiasm and dedication of the attendees, and how inspired he felt.&lt;/p&gt;
&lt;p&gt;Then we cheered him.&lt;/p&gt;
&lt;p&gt;After that it was a lot of pictures and goodbyes to many new friends. Which meant a lot of sad feelings about a great event coming to an end. I felt inspired and changed. I wasn't the same person going in as I was coming out. I'm more grateful for what I have, and deeply honored that I had this chance to bring PyCon to so many wonderful people.&lt;/p&gt;
&lt;p&gt;More thoughts on PyCon Philippines in a forthcoming blog post.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="coming-soon"&gt;
&lt;h2&gt;Coming soon&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;The Story of PyCon Philippines&lt;/li&gt;
&lt;/ul&gt;
&lt;a class="reference external image-reference" href="http://www.flickr.com/photos/pydanny/7516869028/"&gt;&lt;img alt="http://farm8.staticflickr.com/7135/7516869028_ff24aaa027_z.jpg" class="align-left" id="standing-room-only" src="http://farm8.staticflickr.com/7135/7516869028_ff24aaa027_z.jpg" /&gt;&lt;/a&gt;
&lt;/div&gt;
</summary><category term="python"></category><category term="django"></category><category term="philippines"></category><category term="pycon"></category></entry><entry><title>PyCon Philippines 2012 Day 1</title><link href="http://pydanny.com/pycon-philippines-2012-day-1.html" rel="alternate"></link><updated>2012-07-03T12:00:00-07:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2012-07-03:pycon-philippines-2012-day-1.html</id><summary type="html">&lt;p&gt;&lt;a class="reference external" href="http://ph.pycon.org"&gt;PyCon Philippines 2012&lt;/a&gt; (PyCon PH) happened just this past weekend at the &lt;a class="reference external" href="http://www.upd.edu.ph/"&gt;University of the Philippines Diliman&lt;/a&gt; (UP Diliman) campus in &lt;a class="reference external" href="http://en.wikipedia.org/wiki/Quezon_City"&gt;Quezon City&lt;/a&gt;, which is part of &lt;a class="reference external" href="http://en.wikipedia.org/wiki/Metro_Manila"&gt;Metro Manila&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I can assure you that PyCon PH was an wonderful, amazing, humbling experience. I'm hoping that this post and others will get across to you why.&lt;/p&gt;
&lt;div class="section" id="arrival"&gt;
&lt;h2&gt;Arrival&lt;/h2&gt;
&lt;p&gt;Frank Pohlmann, chairman of PyCon Philippines picked us up and drove us to the event. He had worked day and night getting the event ready, all the while running his company, working a job, and being a father to his lovely 21 month old daughter.&lt;/p&gt;
&lt;p&gt;As we arrived at the venue, Audrey and I were met by our good friend, Filipino-American Bryan Veloso of Github, who was to provide the closing keynote. As soon as Bryan heard that there was going to be a PyCon in the Philippines he gave up his trip to Europython to be a speaker at PyCon PH.&lt;/p&gt;
&lt;p&gt;Inside the Institute of Electrical and Electronics Engineering, we were greeted Ann Tan-Pohlman, logistics co-chair and volunteer organizer. She had over a dozen volunteers getting ready for the oncoming flood of registrants.&lt;/p&gt;
&lt;p&gt;More on the herculean efforts of the organizers and volunteers of this event in a forthcoming blog post.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="inspiration"&gt;
&lt;h2&gt;Inspiration&lt;/h2&gt;
&lt;p&gt;We noticed a large group gather by a side corridor and went to say hello. There we met &lt;a class="reference external" href="https://twitter.com/mrvaldez"&gt;Sony Valdez&lt;/a&gt;, President of &lt;a class="reference external" href="http://www.13hq.com/"&gt;Agoo Computer College&lt;/a&gt;, and forty of his faculty and students. They were buzzing with energy and excitement, belying the fact that they had left at midnight the night before in order to arrive on time (they traveled many hours by bus). Audrey, Bryan, and I were floored by their effort to educate themselves, and were determined in our speeches not to disappoint.&lt;/p&gt;
&lt;p&gt;Unfortunately, the majority of the Agoo Computer Science had to go in the middle of the afternoon. &lt;strong&gt;We didn't know they had to go until it was time to leave&lt;/strong&gt;. Next year I plan to do whatever is possible to help them come for the duration of the conference.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="pycon-begins"&gt;
&lt;h2&gt;PyCon Begins&lt;/h2&gt;
&lt;p&gt;After the national anthem, the Dean of Computer Science, Adrian Roy Valdez, started the event with a few words. Frank Pohlmann, PyCon PH chair thanked everyone involved including the sponsors, speakers, and especially the attendees. I gave a keynote speech I'll blog about shortly, and then it was time for the talks.&lt;/p&gt;
&lt;div class="section" id="intro-to-python-1"&gt;
&lt;h3&gt;Intro to Python &lt;a class="footnote-reference" href="#id10" id="id1"&gt;[1]&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;by &lt;a class="reference external" href="http://twitter.com/titopao"&gt;Paolo Barazon&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Paulo gave the Intro to Python talk. He was burdened by some equipment issues, but kept going undeterred. It reminded me of the first time I spoke at PyCon 2010, when for the first 10 minutes of my talk they couldn't get the projector to work. In any case, Paolo did a great job under very trying conditions.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="python-tricks-you-can-t-live-without-2"&gt;
&lt;h3&gt;Python Tricks you can't live without &lt;a class="footnote-reference" href="#id11" id="id2"&gt;[2]&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;By &lt;a class="reference external" href="http://audreymroy.com"&gt;Audrey Roy&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Audrey summarized a lot of the really important things you need to know in Python but aren't part of an introductory talk. Things like pip and virtualenv, how to construct packages, basic use of PyPI, and hammered home the need for good documentation. I may be partial, but I think this was the best version of this kind of talk ever given. :-)&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="django-quickstart-3"&gt;
&lt;h3&gt;Django Quickstart &lt;a class="footnote-reference" href="#id12" id="id3"&gt;[3]&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;By &lt;a class="reference external" href="http://marconijr.com/"&gt;Marconi&lt;/a&gt; &lt;a class="reference external" href="https://twitter.com/marconimjr"&gt;Moreto&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Marconi built off what Audrey provided, and added to it by giving a good introduction to Django. He also contributed a lot during the sprints the next day by pitching in with beginners. His talk featured code for a simple TODO app, and you can see the working example at &lt;a class="reference external" href="http://quickstart.marconijr.com/"&gt;http://quickstart.marconijr.com/&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="game-programming-with-python-4"&gt;
&lt;h3&gt;Game Programming with Python  &lt;a class="footnote-reference" href="#id13" id="id4"&gt;[4]&lt;/a&gt;&lt;/h3&gt;
&lt;blockquote class="epigraph"&gt;
&lt;p&gt;Are you afraid of math? Too bad! In this tutorial you will learn how to math! Scary, isn't it?&lt;/p&gt;
&lt;p class="attribution"&gt;&amp;mdash;Sony Valdez&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Sony Valdez, who I mentioned earlier, gave a talk on pygame and math while wearing the Barong Talalog. Not just any talk on pygame, but the best one I've ever seen. He's a natural speaker and educator, and extremely funny. And while giving this amazing talk on no sleep (remember - he was on a bus with 40 of his students and faculty), he broke many classic presenter rules:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Live code demo&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;He wrote a functioning game while giving this talk. He made his mistakes part of the talk.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Used notepad&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;That's right. He didn't use Vim, Emacs, Sublime Text, or PyCharm. He used notepad.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. Someone else's laptop&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;He used an unfamiliar computer for his talk. Ever try and type on a keyboard you aren't familiar with? This is what he was dealing with while after a 5+ hour bus journey with probably no sleep the night before.&lt;/p&gt;
&lt;p&gt;I'm in awe.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="functional-programming-in-python-5"&gt;
&lt;h3&gt;Functional Programming in Python  &lt;a class="footnote-reference" href="#id14" id="id5"&gt;[5]&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;by &lt;a class="reference external" href="https://twitter.com/malcolmt"&gt;Malcolm Tredinnick&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Sony was a hard act to follow, but Malcolm gave an amazing rendition of his classic talk on functional programming. I've seen Malcolm give this talk before, but this instance was clearly the best.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="ansible-6"&gt;
&lt;h3&gt;Ansible &lt;a class="footnote-reference" href="#id15" id="id6"&gt;[6]&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;by &lt;a class="reference external" href="http://capsunlock.net"&gt;Rodney&lt;/a&gt; &lt;a class="reference external" href="https://github.com/cocoy"&gt;Quillo&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;What's a python conference without one talk about system engineering? Fortunately for us, Rodney gave a talk on &lt;a class="reference external" href="http://ansible.github.com/"&gt;Ansible&lt;/a&gt;, a pretty new Python based deployment tool. What makes Ansible different is it's range of options, and simplicity of use.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="i-didn-t-know-it-s-python-python-advocacy-7"&gt;
&lt;h3&gt;I didn't know it's Python: Python Advocacy &lt;a class="footnote-reference" href="#id16" id="id7"&gt;[7]&lt;/a&gt;&lt;/h3&gt;
&lt;blockquote class="epigraph"&gt;
&lt;p&gt;&amp;quot;PyCon: More fun in the Philippines&amp;quot;&lt;/p&gt;
&lt;p class="attribution"&gt;&amp;mdash;Variant of the &lt;a class="reference external" href="http://www.itsmorefuninthephilippines.com/"&gt;Philippines Department of Tourism slogan&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Paulo Barazon returned to talk about the big users of Python, how to promote it's use, and why it's so awesome for... well.. lots of things.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="maps-of-imaginary-lands-8"&gt;
&lt;h3&gt;Maps of Imaginary Lands &lt;a class="footnote-reference" href="#id17" id="id8"&gt;[8]&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Malcom came back to give us a talk on how to assemble the components necessary to do a mashup of an imaginary place he cooked up.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="closing-keynote-design-your-open-source-project-9"&gt;
&lt;h3&gt;Closing Keynote: Design your open source project &lt;a class="footnote-reference" href="#id18" id="id9"&gt;[9]&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;by &lt;a class="reference external" href="https://twitter.com/bryanveloso"&gt;Bryan&lt;/a&gt; &lt;a class="reference external" href="http://avalonstar.com/"&gt;Veloso&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Bryan closed out the day with an inspirational and funny keynote speech instructing beginners on how to make your project used and loved by developers. His slides were incredible, &lt;a class="reference external" href="https://speakerdeck.com/u/bryan/p/design-your-own-open-source-project"&gt;as you should see for yourself&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr class="docutils" /&gt;
&lt;div class="section" id="coming-soon"&gt;
&lt;h2&gt;Coming soon&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Day 2 of PyCon Philippines&lt;/li&gt;
&lt;li&gt;The Story of PyCon Philippines&lt;/li&gt;
&lt;li&gt;More...&lt;/li&gt;
&lt;/ul&gt;
&lt;a class="reference external image-reference" href="http://ph.pycon.org"&gt;&lt;img alt="http://ph.pycon.org/images/phpug.png" class="align-left" id="pycon-philippines-logo" src="http://ph.pycon.org/images/phpug.png" /&gt;&lt;/a&gt;
&lt;table class="docutils footnote" frame="void" id="id10" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id1"&gt;[1]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="http://pydanny-event-notes.readthedocs.org/en/latest/PyconPH2012/basic_python.html"&gt;http://pydanny-event-notes.readthedocs.org/en/latest/PyconPH2012/basic_python.html&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id11" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id2"&gt;[2]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="http://pydanny-event-notes.readthedocs.org/en/latest/PyconPH2012/python_tricks.html"&gt;http://pydanny-event-notes.readthedocs.org/en/latest/PyconPH2012/python_tricks.html&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id12" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id3"&gt;[3]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="http://pydanny-event-notes.readthedocs.org/en/latest/PyconPH2012/django_quickstart.html"&gt;http://pydanny-event-notes.readthedocs.org/en/latest/PyconPH2012/django_quickstart.html&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id13" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id4"&gt;[4]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="http://pydanny-event-notes.readthedocs.org/en/latest/PyconPH2012/game_programming.html"&gt;http://pydanny-event-notes.readthedocs.org/en/latest/PyconPH2012/game_programming.html&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id14" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id5"&gt;[5]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="http://pydanny-event-notes.readthedocs.org/en/latest/PyconPH2012/functional_programming.html"&gt;http://pydanny-event-notes.readthedocs.org/en/latest/PyconPH2012/functional_programming.html&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id15" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id6"&gt;[6]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="http://pydanny-event-notes.readthedocs.org/en/latest/PyconPH2012/ansible.html"&gt;http://pydanny-event-notes.readthedocs.org/en/latest/PyconPH2012/ansible.html&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id16" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id7"&gt;[7]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="http://pydanny-event-notes.readthedocs.org/en/latest/PyconPH2012/python_advocacy.html"&gt;http://pydanny-event-notes.readthedocs.org/en/latest/PyconPH2012/python_advocacy.html&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id17" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id8"&gt;[8]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="http://pydanny-event-notes.readthedocs.org/en/latest/PyconPH2012/closing-keynote.html"&gt;http://pydanny-event-notes.readthedocs.org/en/latest/PyconPH2012/closing-keynote.html&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id18" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id9"&gt;[9]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a class="reference external" href="http://pydanny-event-notes.readthedocs.org/en/latest/PyconPH2012/closing-keynote.html"&gt;http://pydanny-event-notes.readthedocs.org/en/latest/PyconPH2012/closing-keynote.html&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
</summary><category term="python"></category><category term="django"></category><category term="philippines"></category><category term="pycon"></category></entry><entry><title>Announcing PyCon Philippines!</title><link href="http://pydanny.com/announcing-pycon-philippines.html" rel="alternate"></link><updated>2012-06-09T12:00:00-07:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2012-06-09:announcing-pycon-philippines.html</id><summary type="html">&lt;p&gt;&lt;a class="reference external" href="http://ph.pycon.org"&gt;PyCon Philippines 2012&lt;/a&gt;, set to occur on &lt;strong&gt;June 30&lt;/strong&gt; and &lt;strong&gt;July 1&lt;/strong&gt;, is the first Python programming conference held in the Philippines. PyCon is a volunteer run effort that brings together Python developers from a variety of backgrounds and skill levels into a friendly, cooperative environment in order to educate, inspire, and work together - building relationships that transcend the event and can turn into lifelong friendships or even very impressive business alliances.&lt;/p&gt;
&lt;p&gt;This event is possible due to the hard work and contributions of members of the Manila Python users group, the support of the Python Software Foundation, various members of the Python community, our gracious sponsors, and many others.&lt;/p&gt;
&lt;p&gt;I'll be there, along with &lt;a class="reference external" href="http://audreymroy.com"&gt;Audrey Roy&lt;/a&gt; and Django core developer &lt;a class="reference external" href="https://twitter.com/malcolmt"&gt;Malcolm Tredinnick&lt;/a&gt;. Hope to see you there!&lt;/p&gt;
&lt;div class="section" id="what-is-python"&gt;
&lt;h2&gt;What is Python?&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="http://python.org"&gt;Python&lt;/a&gt; is an open source programming language used for science, engineering, robotics, entertainment, web development, and more. It is used by organizations such as Google, NASA, Instagram, Pinterest, Mozilla, Walt Disney Animation Studios, WETA Digital, and many more.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="interested-in-attending"&gt;
&lt;h2&gt;Interested in attending?&lt;/h2&gt;
&lt;p&gt;Then head to the &lt;a class="reference external" href="http://ph.pycon.org/register.html"&gt;registration page&lt;/a&gt;. The early bird discount ends on June 15th, so buy your tickets now!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="interested-in-sponsoring"&gt;
&lt;h2&gt;Interested in sponsoring?&lt;/h2&gt;
&lt;p&gt;Please go to the &lt;a class="reference external" href="http://ph.pycon.org/sponsor.html"&gt;sponsorship page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Your sponsorship would go a long way towards making PyCon Philippines 2012 a memorable event. As this is an entirely volunteer-run event, 100% of funds go toward actual event costs: food, drinks, chairs, tables, signage, nametags, flyers, advertising, etc. Per custom with PyCons around the world, the organizers receive no payment for their efforts, and any funds left over will be either placed in a Philippine based non-profit corporation or donated back to the Python Software Foundation.&lt;/p&gt;
&lt;a class="reference external image-reference" href="http://ph.pycon.org"&gt;&lt;img alt="http://ph.pycon.org/images/phpug.png" class="align-center" id="pycon-philippines-logo" src="http://ph.pycon.org/images/phpug.png" /&gt;&lt;/a&gt;
&lt;/div&gt;
</summary><category term="python"></category><category term="django"></category><category term="philippines"></category><category term="pycon"></category></entry><entry><title>Django Class Based View: email form with CAPTCHA</title><link href="http://pydanny.com/django-class-based-view-email-form-with-captcha.html" rel="alternate"></link><updated>2012-05-23T09:30:00-07:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2012-05-23:django-class-based-view-email-form-with-captcha.html</id><summary type="html">&lt;p&gt;&lt;a class="reference external" href="http://pydanny.com/simple-django-email-form-using-cbv.html"&gt;Yesterday I showed how to implement a simple email form&lt;/a&gt; for &lt;a class="reference external" href="http://djangoproject.com"&gt;Django&lt;/a&gt; using Class Based Views. Today I'm going to extend yesterday's work to use the excellent &lt;a class="reference external" href="http://www.google.com/recaptcha"&gt;RECAPTCHA&lt;/a&gt; service to help reduce spam content.&lt;/p&gt;
&lt;p&gt;This version requires &lt;tt class="docutils literal"&gt;pip&lt;/tt&gt; installing the following into your &lt;tt class="docutils literal"&gt;virtualenv&lt;/tt&gt;.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;pip install &lt;span class="pre"&gt;django-crispy-forms&lt;/span&gt;&lt;/tt&gt; so we can do Python driven layouts.&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;pip install &lt;span class="pre"&gt;django-floppyforms&lt;/span&gt;&lt;/tt&gt; so we get HTML5 elements for free.&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;pip install &lt;span class="pre"&gt;django-recaptcha&lt;/span&gt;&lt;/tt&gt; to do the RECAPTCHA work.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Don't forget to add the app to your INSTALLED_APPS in settings.py:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;INSTALLED_APPS&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;crispy_forms&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;floppyforms&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;captcha&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Generate your KEYs from the RECAPTCHA site and add them in settings.py:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;RECAPTCHA_PUBLIC_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;6LcVu9ESAAAAANVWwbM5-PLuLES94GQ2bIYmSNTG&amp;#39;&lt;/span&gt;
&lt;span class="n"&gt;RECAPTCHA_PRIVATE_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;6LcVu9ESAAAAAGxz7aEIACWRa3CVnXN3mFd-cajP&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In myapp.forms.py:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;captcha.fields&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ReCaptchaField&lt;/span&gt;  &lt;span class="c"&gt;# Only import different from yesterday&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;crispy_forms.helper&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FormHelper&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;crispy_forms.layout&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Submit&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;floppyforms&lt;/span&gt; &lt;span class="kn"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;forms&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ContactForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EmailField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;subject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Textarea&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;captcha&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ReCaptchaField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c"&gt;# Only field different from yesterday&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;helper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FormHelper&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;helper&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Submit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;submit&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Submit&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ContactForm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In myapp.views.py:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# Unchanged from yesterday. :-)&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.conf&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.core.mail&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;send_mail&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.views.generic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FormView&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;myapp.forms&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ContactForm&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ContactFormView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FormView&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;form_class&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ContactForm&lt;/span&gt;
    &lt;span class="n"&gt;template_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;myapp/email_form.html&amp;quot;&lt;/span&gt;
    &lt;span class="n"&gt;success_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;/email-sent/&amp;#39;&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;form_valid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;{name} / {email} said: &amp;quot;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cleaned_data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cleaned_data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;email&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s"&gt;{0}&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cleaned_data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;message&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="n"&gt;send_mail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cleaned_data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;subject&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;from_email&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;contact-form@myapp.com&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;recipient_list&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LIST_OF_EMAIL_RECIPIENTS&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ContactFormView&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;form_valid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In templates/myapp/email_form.html:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;{# Also unchanged from yesterday. :-)  #}
{% extends &amp;#39;base.html&amp;#39; %}
{% load crispy_forms_tags %}

{% block title %}Send an email{% endblock %}

{% block content %}
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;row&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;span6&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Send an email&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
            {% crispy form form.helper %}
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
{% endblock %}

{% block extrajs %}
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;{{ STATIC_URL }}js/jquery-1.7.1.min.js&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;#id_name&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;focus&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
{% endblock %}
&lt;/pre&gt;&lt;/div&gt;
&lt;div class="section" id="what-i-did"&gt;
&lt;h2&gt;What I did&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Using &lt;tt class="docutils literal"&gt;pip&lt;/tt&gt; I installed three packages into my Python environment.&lt;/li&gt;
&lt;li&gt;Added those three packages into the INSTALLED_APPS setting.&lt;/li&gt;
&lt;li&gt;Set the RECAPTCHA keys for my site.&lt;/li&gt;
&lt;li&gt;Modified the &lt;tt class="docutils literal"&gt;forms.py&lt;/tt&gt; file from yesterday to include the RECAPTCHA field.&lt;/li&gt;
&lt;li&gt;Reduced spam content.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="what-i-could-do"&gt;
&lt;h2&gt;What I could do&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Pin the app versions for a particular release. This is what you should be doing in normal development and in production, but for a blog entry I'm avoiding it because release numbers become quickly dated.&lt;/li&gt;
&lt;li&gt;Rather than change the &lt;tt class="docutils literal"&gt;ContactForm&lt;/tt&gt; from yesterday, I could have extended it via inheritance.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="want-to-learn-more"&gt;
&lt;h2&gt;Want to learn more?&lt;/h2&gt;
&lt;p&gt;If you live in the Los Angeles area and want to learn more about Django, everything from the basics to setting up a Content Management System or E-Commerce system, check out our Django (and &lt;a class="reference external" href="http://python.org"&gt;Python&lt;/a&gt;) training at &lt;a class="reference external" href="https://academy.cartwheelweb.com"&gt;Cartwheel Academy&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
</summary><category term="python"></category><category term="django"></category><category term="howto"></category><category term="class-based-views"></category></entry><entry><title>Simple Django email form using CBV</title><link href="http://pydanny.com/simple-django-email-form-using-cbv.html" rel="alternate"></link><updated>2012-05-22T09:30:00-07:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2012-05-22:simple-django-email-form-using-cbv.html</id><summary type="html">&lt;p&gt;Here's a simple &lt;tt class="docutils literal"&gt;FormView&lt;/tt&gt; Class Based Views for &lt;a class="reference external" href="http://djangoproject.com"&gt;Django&lt;/a&gt;. Here is a sample of how to do one as a simple email form. There is no CAPTCHA in this example, that's the topic of a future blog post.&lt;/p&gt;
&lt;p&gt;This version requires the following packages &lt;tt class="docutils literal"&gt;pip&lt;/tt&gt; installed into your &lt;tt class="docutils literal"&gt;virtualenv&lt;/tt&gt;.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;django-crispy-forms&lt;/span&gt;&lt;/tt&gt; so we can do Python driven layouts.&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;django-floppyforms&lt;/span&gt;&lt;/tt&gt; so we get HTML5 elements for free.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;They also need to be added to your list of INSTALLED_APPS:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;INSTALLED_APPS&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;crispy_forms&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;&amp;#39;floppyforms&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In myapp.forms.py:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;crispy_forms.helper&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FormHelper&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;crispy_forms.layout&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Submit&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;floppyforms&lt;/span&gt; &lt;span class="kn"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;forms&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ContactForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EmailField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;subject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;widget&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;forms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Textarea&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;helper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FormHelper&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;helper&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Submit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;submit&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Submit&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ContactForm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In myapp.views.py:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.conf&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.core.mail&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;send_mail&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.views.generic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FormView&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;myapp.forms&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ContactForm&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ContactFormView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FormView&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;form_class&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ContactForm&lt;/span&gt;
    &lt;span class="n"&gt;template_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;myapp/email_form.html&amp;quot;&lt;/span&gt;
    &lt;span class="n"&gt;success_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;/email-sent/&amp;#39;&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;form_valid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;{name} / {email} said: &amp;quot;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cleaned_data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cleaned_data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;email&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s"&gt;{0}&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cleaned_data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;message&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="n"&gt;send_mail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cleaned_data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;subject&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;from_email&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;contact-form@myapp.com&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;recipient_list&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LIST_OF_EMAIL_RECIPIENTS&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ContactFormView&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;form_valid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In templates/myapp/email_form.html:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;{% extends &amp;#39;base.html&amp;#39; %}
{% load crispy_forms_tags %}

{% block title %}Send an email{% endblock %}

{% block content %}
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;row&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;span6&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Send an email&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
            {% crispy form form.helper %}
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
{% endblock %}

{% block extrajs %}
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;{{ STATIC_URL }}js/jquery-1.7.1.min.js&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;#id_name&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;focus&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
{% endblock %}
&lt;/pre&gt;&lt;/div&gt;
&lt;div class="section" id="tomorrow-s-blog-post"&gt;
&lt;h2&gt;Tomorrow's blog post&lt;/h2&gt;
&lt;p&gt;In tomorrow's post I'll show how to add CAPTCHA into your project to help reduce spam messages.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="want-to-learn-more"&gt;
&lt;h2&gt;Want to learn more?&lt;/h2&gt;
&lt;p&gt;If you live in the Los Angeles area and want to learn more about Django, everything from the basics to setting up a Content Management System or E-Commerce system, check out our Django (and &lt;a class="reference external" href="http://python.org"&gt;Python&lt;/a&gt;) training at &lt;a class="reference external" href="https://academy.cartwheelweb.com"&gt;Cartwheel Academy&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
</summary><category term="python"></category><category term="django"></category><category term="howto"></category><category term="class-based-views"></category></entry><entry><title>May 12th, 2012 LA Open Source Recap</title><link href="http://pydanny.com/may-12th-2012-la-open-source-recap.html" rel="alternate"></link><updated>2012-05-21T09:30:00-07:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2012-05-21:may-12th-2012-la-open-source-recap.html</id><summary type="html">&lt;p&gt;On May 12th, 2012, over 50 &lt;a class="reference external" href="http://python.org"&gt;Python&lt;/a&gt;, &lt;a class="reference external" href="http://en.wikipedia.org/wiki/C%2B%2B"&gt;C++&lt;/a&gt;, &lt;a class="reference external" href="http://www.ruby-lang.org/"&gt;Ruby&lt;/a&gt;, &lt;a class="reference external" href="http://www.php.net/"&gt;PHP&lt;/a&gt;, &lt;a class="reference external" href="http://en.wikipedia.org/wiki/JavaScript"&gt;JavaScript&lt;/a&gt;, and &lt;a class="reference external" href="http://nodejs.org/"&gt;Node.js&lt;/a&gt; developers arrived to code on a variety of projects. It was awesome! Tons of open source projects saw contributions, and people across languages and frameworks worked together.&lt;/p&gt;
&lt;a class="reference external image-reference" href="http://www.flickr.com/photos/59834630&amp;#64;N07/7193954598/"&gt;&lt;img alt="http://farm9.staticflickr.com/8007/7193954598_1b071cb5e4.jpg" class="align-center" id="may-12-open-source-sprint" src="http://farm9.staticflickr.com/8007/7193954598_1b071cb5e4.jpg" /&gt;&lt;/a&gt;
&lt;div class="section" id="event-background"&gt;
&lt;h2&gt;Event Background&lt;/h2&gt;
&lt;p&gt;Less then two weeks before May 12, a bunch of us Los Angeles area Python developers were hanging out and wishing we had a local sprint to attend that was just about developers working on open source projects. It was then that &lt;a class="reference external" href="http://audreymroy.com"&gt;Audrey Roy&lt;/a&gt; and I, along with an army of hardworking volunteers, decided to stop wishing and make it happen on May 12th.&lt;/p&gt;
&lt;p&gt;We lined up a venue, contacted awesome sponsors &lt;a class="reference external" href="http://spire.io"&gt;Spire.io&lt;/a&gt;, &lt;a class="reference external" href="http://heroku.com"&gt;Heroku&lt;/a&gt;, &lt;a class="reference external" href="https://github.com"&gt;Github&lt;/a&gt;, &lt;a class="reference external" href="http://cars.com"&gt;Cars.com&lt;/a&gt;, and &lt;a class="reference external" href="https://academy.cartwheelweb.com"&gt;Cartwheel Academy&lt;/a&gt;. As we did that, we also invited people from the many Los Angeles programming communities in Los Angeles to join us. The result of everyone's hard work? &lt;strong&gt;We filled up all sixty spots in less than 96 hours!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Some of the projects worked on included:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Salt Stack: &lt;a class="reference external" href="https://github.com/saltstack/salt"&gt;https://github.com/saltstack/salt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;A node.js-powered streaming terminal, allowing for shared input at a terminal among several participants.&lt;/li&gt;
&lt;li&gt;A JavaScript powered astrolabe.&lt;/li&gt;
&lt;li&gt;Settlers of Catan analytics in JavaScript.&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.openframeworks.cc/"&gt;OpenFrameworks&lt;/a&gt;, a cross-platform toolkit for creative coding in C++.&lt;/li&gt;
&lt;li&gt;My own time at the sprint was spent with Audrey Roy and &lt;a class="reference external" href="http://rdegges.com"&gt;Randall Degges&lt;/a&gt; on engineering cleanup and fixing bugs on &lt;a class="reference external" href="https://github.com/opencomparison/opencomparison"&gt;OpenComparison&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="more-open-source-sprinting-on-july-15"&gt;
&lt;h2&gt;More open source sprinting on July 15&lt;/h2&gt;
&lt;p&gt;There's going to be another Los Angeles open source event on July 15 at &lt;a class="reference external" href="http://originate.com/"&gt;Originate&lt;/a&gt;. Instead of less then two weeks to plan, we have nearly two months - so it's going to be better!&lt;/p&gt;
&lt;p&gt;RSVP here: &lt;a class="reference external" href="http://www.meetup.com/LA-Hackathons/events/64542582/"&gt;http://www.meetup.com/LA-Hackathons/events/64542582/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you want to sponsor or volunteer, email me at pydanny (at) cartwheelweb.com or audreyr (at) cartwheelweb.com. We go out of our way to ensure that sponsors and volunteers feel appreciated.&lt;/p&gt;
&lt;a class="reference external image-reference" href="http://www.flickr.com/photos/59834630&amp;#64;N07/7193961164/"&gt;&lt;img alt="http://farm9.staticflickr.com/8003/7193961164_b26d27093d.jpg" class="align-center" id="me-and-audrey-at-the-open-source-sprint" src="http://farm9.staticflickr.com/8003/7193961164_b26d27093d.jpg" /&gt;&lt;/a&gt;
&lt;/div&gt;
</summary><category term="python"></category><category term="django"></category><category term="los-angeles"></category><category term="lahackathons"></category></entry><entry><title>10 reasons to go to DjangoCon Europe</title><link href="http://pydanny.com/10-reasons-to-go-to-djangocon-europe.html" rel="alternate"></link><updated>2012-05-14T19:30:00-07:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2012-05-14:10-reasons-to-go-to-djangocon-europe.html</id><summary type="html">&lt;p&gt;You should go to &lt;a class="reference external" href="http://djangocon.eu"&gt;DjangoCon Europe&lt;/a&gt; in lovely &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Zurich"&gt;Zurich&lt;/a&gt;, &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Switzerland"&gt;Switzerland&lt;/a&gt;. Here are 10 reasons why:&lt;/p&gt;
&lt;div class="section" id="chocolate"&gt;
&lt;h2&gt;1. &lt;strong&gt;Chocolate&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;So much of what we like about chocolate comes from Switzerland. For example, Milk Chocolate was invented in Switzerland.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="keynote-speaker-jacob-kaplan-moss"&gt;
&lt;h2&gt;2. &lt;strong&gt;Keynote speaker: Jacob Kaplan-Moss&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Always a great speaker and fun to be around, he's one of the BDFL's of &lt;a class="reference external" href="http://djangoproject.com"&gt;Django&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="cheese"&gt;
&lt;h2&gt;3. &lt;strong&gt;Cheese&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;I grew up thinking that Swiss Cheese was just about holes. It's so much more. I can't wait to try fresh European cheese made by master craftsmen from the freshest ingredients.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="keynote-speaker-jessica-mckellar"&gt;
&lt;h2&gt;4. &lt;strong&gt;Keynote speaker: Jessica McKellar&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;In a word, Jessica is &lt;strong&gt;incredible&lt;/strong&gt;. She's a Twisted core developer, PSF board member, part of the trio responsible for the gigantic Boston Python User Group's massive size explosion, and a talented speaker. She's used her incredible talents and skills to increase diversity in the community and generally help other people.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="breakfast"&gt;
&lt;h2&gt;5. &lt;strong&gt;Breakfast&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Muesli was invented in Switzerland. I love Muesli. I was floored by how much better it was in New Zealand. I can't wait to try it in it's homeland.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="web-site"&gt;
&lt;h2&gt;6. &lt;strong&gt;Web Site&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;The DjangoCon Europe site is crazy. I mean, look at all those animations!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="talks"&gt;
&lt;h2&gt;7. &lt;strong&gt;Talks&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;This is a single track event with proven speakers like Zachary Voase and Andrew Godwin, yet balances that with bringing in new blood to spice things up. And dare I say &lt;a class="reference external" href="http://2012.djangocon.eu/schedule/round-pegs-and-square-holes/"&gt;I'm giving a technical talk&lt;/a&gt; with &lt;a class="reference external" href="http://audreymroy.com/"&gt;Audrey Roy&lt;/a&gt;? ;-)&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="mountains"&gt;
&lt;h2&gt;8. &lt;strong&gt;Mountains&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;With all the incredible food, you would think you would gain umpteen kilograms. Fortunately there are mountains all around to climb and hike.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="sprints"&gt;
&lt;h2&gt;9. &lt;strong&gt;Sprints&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Want to sprint on Django itself? Look no further because there will be Django core developers around! There will also be notable &lt;a class="reference external" href="http://python.org"&gt;Python&lt;/a&gt; developers like &lt;a class="reference external" href="http://kennethreitz.com/"&gt;Kenneth Reitz&lt;/a&gt; and others around working hard on a lot of different projects. It's going to intense and fun!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="castles"&gt;
&lt;h2&gt;10. &lt;strong&gt;Castles&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Living in the USA, we just don't have anything like castles. DjangoCon Europe will be near a &lt;a class="reference external" href="https://en.wikipedia.org/wiki/List_of_castles_and_fortresses_in_Switzerland#Zurich"&gt;small horde of stone fortifications&lt;/a&gt;. Which means if the Zombie Apocalypse happens during the conference, we'll have many secure places to go. They also make lovely tourist destinations. :-)&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="what-are-you-waiting-for"&gt;
&lt;h2&gt;What are you waiting for?&lt;/h2&gt;
&lt;p&gt;DjangoCon Europe has a cap on attendance. Tickets for Python events have been selling out, not just for PyCon US. Don't miss out!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="it-s-all-about-me"&gt;
&lt;h2&gt;It's all about me&lt;/h2&gt;
&lt;p&gt;Yup.&lt;/p&gt;
&lt;p&gt;Call me selfish but I want you there because I haven't haven't met all our European friends yet in person. Hope to see you next month in Zurich!&lt;/p&gt;
&lt;/div&gt;
</summary><category term="python"></category><category term="django"></category><category term="europe"></category><category term="djangocon"></category></entry><entry><title>CSS Hacking to make my code samples legible</title><link href="http://pydanny.com/css-hacking-to-make-my-code-samples-legible.html" rel="alternate"></link><updated>2012-05-11T08:30:00-07:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2012-05-11:css-hacking-to-make-my-code-samples-legible.html</id><summary type="html">&lt;p&gt;I've been very happy with &lt;a class="reference external" href="http://pelican.readthedocs.org/"&gt;Pelican&lt;/a&gt; as a blog engine so far, and haven't even moved off the sample theme. There's just been one problem: Myself and others have had a lot of trouble reading the code snippets.&lt;/p&gt;
&lt;p&gt;I didn't have time to cook up a full Pelican theme, so instead I just hacked the local CSS files. The problem with this hack is that every time I regenerate the blog I have to copy the right CSS files into place. So next week when I have time I'll do a proper Pelican theme.&lt;/p&gt;
&lt;p&gt;In the meantime, enjoy!&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;random&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;shuffle&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Meal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;food_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;Beef&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Fish&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Vegetarian&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Chicken&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;shuffle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;food_type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
</summary><category term="python"></category><category term="django"></category><category term="css"></category><category term="usability"></category></entry><entry><title>Choosing an API framework for Django</title><link href="http://pydanny.com/choosing-an-api-framework-for-django.html" rel="alternate"></link><updated>2012-05-10T08:00:00-07:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2012-05-10:choosing-an-api-framework-for-django.html</id><summary type="html">&lt;p&gt;First off, out of the box, &lt;a class="reference external" href="http://djangoproject.com"&gt;Django&lt;/a&gt; lets you construct API responses with a little work. All you need to do is something like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# Copied from https://docs.djangoproject.com/en/1.4/topics/class-based-views/#more-than-just-html&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.utils&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;simplejson&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;JSONResponseMixin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;render_to_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="s"&gt;&amp;quot;Returns a JSON response containing &amp;#39;context&amp;#39; as payload&amp;quot;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_json_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convert_context_to_json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_json_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;httpresponse_kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="s"&gt;&amp;quot;Construct an `HttpResponse` object.&amp;quot;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HttpResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                 &lt;span class="n"&gt;content_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;application/json&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                 &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;httpresponse_kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;convert_context_to_json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="s"&gt;&amp;quot;Convert the context dictionary into a JSON object&amp;quot;&lt;/span&gt;
        &lt;span class="c"&gt;# Note: This is *EXTREMELY* naive; in reality, you&amp;#39;ll need&lt;/span&gt;
        &lt;span class="c"&gt;# to do much more complex handling to ensure that arbitrary&lt;/span&gt;
        &lt;span class="c"&gt;# objects -- such as Django model instances or querysets&lt;/span&gt;
        &lt;span class="c"&gt;# -- can be serialized as JSON.&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Once you get that &lt;cite&gt;mixin&lt;/cite&gt;, use it in your views like so:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# modified from djangoproject.com sample code&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.utils&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;simplejson&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;JSONDetailView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;JSONResponseMixin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MyCustomUserView&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;convert_context_to_json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

        &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;objects&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;first_name&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;last_name&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;is_active&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This works pretty well in a number of simple cases, but doing things like pagination, posting of data, metadata, API discovery, and other important things ends up being a bit more work. This is where the resource oriented API frameworks come in.&lt;/p&gt;
&lt;div class="section" id="what-makes-a-decent-api-framework"&gt;
&lt;h2&gt;What makes a decent API Framework?&lt;/h2&gt;
&lt;p&gt;These features:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;pagination&lt;/li&gt;
&lt;li&gt;posting of data with validation&lt;/li&gt;
&lt;li&gt;Publishing of metadata along with querysets&lt;/li&gt;
&lt;li&gt;API discovery&lt;/li&gt;
&lt;li&gt;proper HTTP response handling&lt;/li&gt;
&lt;li&gt;caching&lt;/li&gt;
&lt;li&gt;serialization&lt;/li&gt;
&lt;li&gt;throttling&lt;/li&gt;
&lt;li&gt;permissions&lt;/li&gt;
&lt;li&gt;authentication&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Proper API frameworks also need:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Really good test coverage of their code&lt;/li&gt;
&lt;li&gt;Decent performance&lt;/li&gt;
&lt;li&gt;Documentation&lt;/li&gt;
&lt;li&gt;An active community to advance and support the framework&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you take these factors, at this time there are only two API frameworks worth using, &lt;a class="reference external" href="http://django-tastypie.readthedocs.org/"&gt;django-tastypie&lt;/a&gt; and &lt;a class="reference external" href="http://django-rest-framework.org/"&gt;django-rest-framework&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="which-one-is-better-django-tastypie-or-django-rest-framework"&gt;
&lt;h2&gt;Which one is better? django-tastypie or django-rest-framework?&lt;/h2&gt;
&lt;p&gt;I say they are equal.&lt;/p&gt;
&lt;p&gt;You simply can't go wrong with either one. The authors and communities behind both of them are active, the code is solid and tested. And here are my specific thoughts about both of them:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="id1"&gt;
&lt;h2&gt;django-tastypie&lt;/h2&gt;
&lt;p&gt;Using django-tastypie is like playing with pure Python while using the Django ORM. I find it very comfortable. Seems really fast too. The documentation is incredible, and I rarely have any problems figuring anything out. It also supports OAuth 1.0a out of the box, which is mighty awesome these days.&lt;/p&gt;
&lt;p&gt;In fact, I wrote a custom OAuth2 handler for django-tastypie for &lt;a class="reference external" href="http://consumer.io"&gt;consumer.io&lt;/a&gt; that I'm working to extract for publication.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="id2"&gt;
&lt;h2&gt;django-rest-framework&lt;/h2&gt;
&lt;p&gt;As it's based off Django 1.3 style Class Based Views (CBVs), it has a very familiar pattern. Actually, because of the quality of the documentation, I really prefer using django-rest-framework CBVs more than using Django's actual CBVs.&lt;/p&gt;
&lt;p&gt;Maybe I should make an HTML renderer for django-rest-framework? :-)&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="but-what-about-django-piston"&gt;
&lt;h2&gt;But what about django-piston?&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Don't use django-piston&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;I don't want to say anything negative, but let's face it: &lt;strong&gt;django-piston is dead&lt;/strong&gt;. Besides a critical security release last year, nothing has been done for it in about 3 years. The documentation is weak, the code mostly untested, and the original author left. He has gone on to do some amazing things. Django-piston was amazing in its time, but its time has passed and so should you.&lt;/p&gt;
&lt;p&gt;The only reason for using django-piston for years has been that it supported OAuth, but django-tastypie now addresses that use case. I've used django-tastypie's basic OAuth class and rolled custom Authentication modules to support some extra OAuth flavors and found it wonderful.&lt;/p&gt;
&lt;p&gt;Use django-tastypie or django-rest-framework instead. You'll be much, much happier for it.&lt;/p&gt;
&lt;hr class="docutils" /&gt;
&lt;p&gt;&lt;a class="reference external" href="http://news.ycombinator.com/item?id=3954314"&gt;Discuss this on Hacker News&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
</summary><category term="python"></category><category term="django"></category><category term="api"></category><category term="review"></category></entry><entry><title>Django Requirements for a project</title><link href="http://pydanny.com/django-requirements-for-a-project.html" rel="alternate"></link><updated>2012-05-09T08:00:00-07:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2012-05-09:django-requirements-for-a-project.html</id><summary type="html">&lt;p&gt;Today I'm starting a new project. I'm working as fast as I can and hope to launch on Friday. What are my package dependencies?&lt;/p&gt;
&lt;div class="section" id="django-1-4"&gt;
&lt;h2&gt;&lt;a class="reference external" href="http://pypi.python.org/pypi/Django/1.4"&gt;Django==1.4&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Unlike my last quick project which was &lt;a class="reference external" href="http://flask.pocoo.org/"&gt;Flask&lt;/a&gt;, this effort really falls into &lt;a class="reference external" href="http://djangoproject.com"&gt;Django&lt;/a&gt;'s sweet spot. I need sessions, forms, templates, and models to do things in an ideal Django pattern.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="psycopg2-2-4-5"&gt;
&lt;h2&gt;&lt;a class="reference external" href="http://pypi.python.org/pypi/psycopg2"&gt;psycopg2==2.4.5&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I need transactions and hard-type validation in the database, which means PostgreSQL. If I didn't need transactions or the hard-type validation I would consider MongoDB instead.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="django-debug-toolbar-0-9-4"&gt;
&lt;h2&gt;&lt;a class="reference external" href="http://pypi.python.org/pypi/django-debug-toolbar"&gt;django-debug-toolbar==0.9.4&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Because not using this tool is insane.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="django-extensions-0-8"&gt;
&lt;h2&gt;&lt;a class="reference external" href="http://pypi.python.org/pypi/django-extensions"&gt;django-extensions==0.8&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Because amongst other things this library gives you, I never want to write my own &lt;tt class="docutils literal"&gt;TimeStampedModel&lt;/tt&gt; ever again. :-)&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="south-0-7-5"&gt;
&lt;h2&gt;&lt;a class="reference external" href="http://pypi.python.org/pypi/South"&gt;South==0.7.5&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Django gives you the freedom to migrate data in the way you want. The way I want to do it is via South.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="django-registration-0-8-0"&gt;
&lt;h2&gt;&lt;a class="reference external" href="http://pypi.python.org/pypi/django-registration"&gt;django-registration==0.8.0&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Normally &lt;a class="reference external" href="http://pypi.python.org/pypi/django-social-auth"&gt;django-social-auth&lt;/a&gt; is my go-to tool for registration, but in this case I need simple username/password registration. This is a very solid tool, but you do have to make your own templates or find someone's fork that has a copy of templates that match.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="django-floppyforms-0-4-7"&gt;
&lt;h2&gt;&lt;a class="reference external" href="http://pypi.python.org/pypi/django-floppyforms"&gt;django-floppyforms==0.4.7&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;An excellent tool for making your forms HTML5-ish out of the box.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="django-crispy-forms-1-1-3"&gt;
&lt;h2&gt;&lt;a class="reference external" href="http://pypi.python.org/pypi/django-crispy-forms"&gt;django-crispy-forms==1.1.3&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The child of my own django-uni-forms, this will let me create forms using div-based controls super fast, and do layout customizations if I need them.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="django-heroku-postgresify-0-2"&gt;
&lt;h2&gt;&lt;a class="reference external" href="http://pypi.python.org/pypi/django-heroku-postgresify"&gt;django-heroku-postgresify==0.2&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This tool makes getting the PostGreSQL settings out of Heroku trivial.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="django-heroku-memcacheify-0-1"&gt;
&lt;h2&gt;&lt;a class="reference external" href="http://pypi.python.org/pypi/django-heroku-memcacheify"&gt;django-heroku-memcacheify==0.1&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This tool makes getting the memcache settings for Heroku trivial.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="gunicorn-0-14-2"&gt;
&lt;h2&gt;&lt;a class="reference external" href="http://pypi.python.org/pypi/gunicorn"&gt;gunicorn==0.14.2&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;All the cool kids who play in devops swear by Gunicorn. I use it because Heroku seems to recommend it for Django deployments.&lt;/p&gt;
&lt;/div&gt;
&lt;hr class="docutils" /&gt;
&lt;div class="section" id="installing-the-above-packages"&gt;
&lt;h2&gt;Installing the above packages&lt;/h2&gt;
&lt;p&gt;Never copy/paste these libraries directly into your projects. If you do that, you'll end up hating yourself later as your local instances become unmaintained forks of the real project. Also, unless you are really careful in your copy/pasting, you'll be in violation of various open source licenses. Odds are the FOSS police aren't going to find you, but I can assure you that when you bring in one of the authors of these packages to help you fix a problem he/she is going to be mighty annoyed at the lack of attribution.&lt;/p&gt;
&lt;p&gt;Do it the right way: do proper Python dependency management.&lt;/p&gt;
&lt;p&gt;Create a &lt;tt class="docutils literal"&gt;requirements.txt&lt;/tt&gt; file and install them as proper dependencies. The file should contain the following text:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
Django==1.4
South==0.7.5
django-crispy-forms==1.1.3
django-debug-toolbar==0.9.4
django-extensions==0.8
django-floppyforms==0.4.7
django-heroku-memcacheify==0.1
django-heroku-postgresify==0.2
django-registration==0.8.0
gunicorn==0.14.2
psycopg2==2.4.5
&lt;/pre&gt;
&lt;p&gt;Once you have that, you install them thus in your &lt;a class="reference external" href="http://pypi.python.org/pypi/virtualenv"&gt;virtualenv&lt;/a&gt;:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
pip install -r requirements.txt
&lt;/pre&gt;
&lt;p&gt;Now that I have all this, it's time to code!&lt;/p&gt;
&lt;hr class="docutils" /&gt;
&lt;a class="reference external image-reference" href="http://www.flickr.com/photos/pydanny/4358842735/"&gt;&lt;img alt="http://farm5.staticflickr.com/4027/4358842735_38991c0944.jpg" class="align-center" id="blizzard-of-2010" src="http://farm5.staticflickr.com/4027/4358842735_38991c0944.jpg" /&gt;&lt;/a&gt;
&lt;/div&gt;
</summary><category term="python"></category><category term="django"></category><category term="setup"></category></entry><entry><title>Los Angeles Open Source Sprint on May 12th!</title><link href="http://pydanny.com/los-angeles-open-source-sprint-on-may-12th.html" rel="alternate"></link><updated>2012-05-01T09:20:00-07:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2012-05-01:los-angeles-open-source-sprint-on-may-12th.html</id><summary type="html">&lt;a class="reference external image-reference" href="http://www.flickr.com/photos/pydanny/7132778527/"&gt;&lt;img alt="http://farm9.staticflickr.com/8022/7132778527_6e3b49b313_o.png" class="align-center" id="la-open-source-sprint-hosted-on-flickr" src="http://farm9.staticflickr.com/8022/7132778527_6e3b49b313_o.png" /&gt;&lt;/a&gt;
&lt;p&gt;This is a day long coding event in Los Angeles for Open Source developers of all languages and skill levels to come and code like fiends. They'll be joined by dozens of either really smart coders or nice people like me. Sponsors are providing food, drinks, venue, and more!&lt;/p&gt;
&lt;p&gt;RSVP at &lt;a class="reference external" href="http://www.meetup.com/LA-Hackathons/events/62796642/"&gt;http://www.meetup.com/LA-Hackathons/events/62796642/&lt;/a&gt; before it fills up! It's free.&lt;/p&gt;
&lt;p&gt;I'll be there to:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Organize the event with the assistance of the awesome Los Angeles technical community!&lt;/li&gt;
&lt;li&gt;Code like a fiend. I want to work on django-mongonaut and could use some GraphViz and JavaScript help.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And now to open the floor to questions...&lt;/p&gt;
&lt;div class="section" id="where-and-when"&gt;
&lt;h2&gt;Where and when?&lt;/h2&gt;
&lt;p&gt;Where:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
Spire.io
7257 Beverly Blvd #210
Los Angeles, CA 90036
&lt;/pre&gt;
&lt;p&gt;When:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
May 12, 2012
10 AM to 10 PM
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="is-this-like-a-hackathon"&gt;
&lt;h2&gt;Is this like a Hackathon?&lt;/h2&gt;
&lt;p&gt;Yup. See &lt;a class="reference external" href="http://en.wikipedia.org/wiki/Hackathon#Sprints"&gt;http://en.wikipedia.org/wiki/Hackathon#Sprints&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="will-there-be-wifi"&gt;
&lt;h2&gt;Will there be Wifi?&lt;/h2&gt;
&lt;p&gt;Yes!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="i-m-just-starting-as-a-developer-should-i-come"&gt;
&lt;h2&gt;I'm just starting as a developer, should I come?&lt;/h2&gt;
&lt;p&gt;It depends.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;If you've never coded before&lt;/strong&gt;, this isn't the right place. Instead, you might consider one of the local coding workshops or classes. In fact, here's a good &lt;a class="reference external" href="http://www.meetup.com/Los-Angeles-Hack-Night/"&gt;bi-weekly hack night / study group&lt;/a&gt; for you.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;If you've done a tutorial or two&lt;/strong&gt;, sprints can be a great way to learn new skills or hone your technique by sitting alongside experienced developers who actually need your help. A lot of projects have what are called 'low hanging fruit', which are 'simpler' tasks saved for beginner developers to wet their teeth on. Things I've learned at events like these include Git, Mercurial, JQuery, and a hundred other things that have made me a better coder.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="what-if-i-don-t-have-a-project-of-my-own-to-bring-should-i-come"&gt;
&lt;h2&gt;What if I don't have a project of my own to bring? Should I come?&lt;/h2&gt;
&lt;p&gt;Heck yeah! There will be a number of projects around that you can join and contribute to in order to make the world a better place. There isn't a list up yet, but I'm hoping by Saturday there will be one.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="what-if-i-want-to-come-and-recruit-people"&gt;
&lt;h2&gt;What if I want to come and recruit people?&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Absolutely not&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;This is not a job fair and we don't want unnecessary distractions.&lt;/p&gt;
&lt;p&gt;On the other hand, if you want to help sponsor we'll happily mention you on the &lt;a class="reference external" href="http://www.meetup.com/LA-Hackathons/events/62796642/"&gt;meetup.com&lt;/a&gt; description.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="are-there-going-to-be-any-presentations-or-lightning-talks"&gt;
&lt;h2&gt;Are there going to be any presentations or lightning talks?&lt;/h2&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;p&gt;This is a sprint, not a conference or demonstration. We'll try and limit announcements and interruptions as much as possible, the only exception being for letting you know food has arrived.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="what-should-i-bring"&gt;
&lt;h2&gt;What should I bring?&lt;/h2&gt;
&lt;p&gt;Your own functioning laptop with power cord. Neither event organizers, the venue, or sponsors are providing equipment. We also encourage you to bring a power strip labeled with your name.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="i-m-sold-how-much-does-it-cost-and-where-do-i-register"&gt;
&lt;h2&gt;I'm sold! How much does it cost and where do I register?&lt;/h2&gt;
&lt;p&gt;The event costs you nothing and you RSVP at &lt;a class="reference external" href="http://www.meetup.com/LA-Hackathons/events/62796642/"&gt;http://www.meetup.com/LA-Hackathons/events/62796642/&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
</summary><category term="python"></category><category term="django"></category><category term="LA"></category><category term="sprint"></category><category term="hackathon"></category></entry><entry><title>Join us at DjangoCon Europe!</title><link href="http://pydanny.com/join-us-at-djangocon-europe.html" rel="alternate"></link><updated>2012-04-10T12:00:00-07:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2012-04-10:join-us-at-djangocon-europe.html</id><summary type="html">&lt;p&gt;This year in June, the European edition of &lt;a class="reference external" href="http://djangocon.eu"&gt;DjangoCon&lt;/a&gt; is going to be held in lovely &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Zurich"&gt;Zurich&lt;/a&gt;, &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Switzerland"&gt;Switzerland&lt;/a&gt;. It is my great fortune and delight to announce that &lt;a class="reference external" href="http://audreymroy.com"&gt;Audrey&lt;/a&gt; and I will be attending. Hooray!&lt;/p&gt;
&lt;p&gt;Needless to say, we're extremely excited. My &lt;a class="reference external" href="http://dannygreenfeld.blogspot.com/search/label/ploneconf2007"&gt;trip to Europe in 2007&lt;/a&gt; was an amazingly fun and educational experience, and I can't wait to share a similar experience with Audrey. We can't wait to see all our old European friends, make new ones, and be dazzled by what Europe has to offer.&lt;/p&gt;
&lt;p&gt;Also, let's face it, the conference is going to be &lt;strong&gt;incredible&lt;/strong&gt;. They've lined up some awesome venues, the food (&lt;a class="reference external" href="https://en.wikipedia.org/wiki/Raclette"&gt;cheese&lt;/a&gt;, chocolate, &lt;a class="reference external" href="http://en.wikipedia.org/wiki/Muesli"&gt;muesli&lt;/a&gt;, etc) in Switzerland is world-renowned, the website looks fantastic, and they've got Jacob Kaplan-Moss to keynote. It looks so good I'm surprised there are any &lt;a class="reference external" href="http://2012.djangocon.eu/sponsors/"&gt;sponsor slots left&lt;/a&gt;!&lt;/p&gt;
&lt;div class="section" id="talks"&gt;
&lt;h2&gt;Talks&lt;/h2&gt;
&lt;p&gt;While attending the conference, we submitted and hope to give a presentation on the positives (speed, flexibility, community, etc) and negatives (a few) of using &lt;a class="reference external" href="http://www.mongodb.org/"&gt;MongoDB&lt;/a&gt; as a &lt;a class="reference external" href="http://djangoproject.com"&gt;Django&lt;/a&gt; datastore. I'm also considering giving a second talk. Some ideas for that include:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Zen of Django&lt;/li&gt;
&lt;li&gt;Django isn't for beginners (A Tredennick inspired talk explaining why teaching beginning developers Django isn't a good idea)&lt;/li&gt;
&lt;li&gt;Advanced Django Template Usage&lt;/li&gt;
&lt;li&gt;Advanced Django Models Usage (An intimidating talk to put together)&lt;/li&gt;
&lt;li&gt;Django Packages Thunderdome II&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Any thoughts?&lt;/p&gt;
&lt;p&gt;While I'm at it, I'm going to poke any prospective conference goers to submit their own talks. I love attending conference talks and at PyCon US this year I barely got to see any. Show me what you got!&lt;/p&gt;
&lt;a class="reference external image-reference" href="http://www.flickr.com/photos/pydanny/1614703646/"&gt;&lt;img alt="http://farm3.staticflickr.com/2339/1614703646_2e2610162a.jpg" class="align-center" id="my-last-day-in-italy-back-in-2007-when-i-still-had-hair" src="http://farm3.staticflickr.com/2339/1614703646_2e2610162a.jpg" /&gt;&lt;/a&gt;
&lt;/div&gt;
</summary><category term="python"></category><category term="django"></category><category term="djangocon"></category><category term="mongodb"></category></entry><entry><title>Calendar About Nothing</title><link href="http://pydanny.com/calendar-about-nothing.html" rel="alternate"></link><updated>2012-03-28T11:30:00-07:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2012-03-28:calendar-about-nothing.html</id><summary type="html">&lt;p&gt;On October 16th, 2011, which was one hundred and sixty-four days before I published this post, I resolved to get myself onto the Longest Streak list of &lt;a class="reference external" href="http://calendaraboutnothing.com/"&gt;Calendar About Nothing&lt;/a&gt;. Today, with this blog post, I've managed to do just that - get on the Longest Streaks.&lt;/p&gt;
&lt;p&gt;Calendar About Nothing tracks your open project commits on &lt;a class="reference external" href="http://github.com"&gt;Github&lt;/a&gt;. It tallies your total number of days, records your longest streak, and lets you compare yourself against other committers. The idea comes from an &lt;a class="reference external" href="http://lifehacker.com/281626/jerry-seinfelds-productivity-secret?tag=softwaremotivation"&gt;article&lt;/a&gt; where Jerry Seinfeld says his secret to productivity is to get something done every day, because if you skip one day then skipping another day is easier.&lt;/p&gt;
&lt;div class="section" id="i-feel-a-great-sense-of-accomplishment"&gt;
&lt;h2&gt;I feel a great sense of accomplishment.&lt;/h2&gt;
&lt;p&gt;The majority of those days I would like to think I did real commits. I pledged to myself to do more than just white space tweaks or write a script to do the work for me. I wanted to accomplish things and make a difference. I started projects, wrote code, cleaned up old code, added tests, documented a lot, and moved my blog here. It's been an awesome time, and keeping my fingers constantly in projects has been eye opening.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="i-feel-a-great-sense-of-relief"&gt;
&lt;h2&gt;I feel a great sense of relief.&lt;/h2&gt;
&lt;p&gt;I've really enjoyed this but there were days it was hard to get to the internet or days I was busy on other things. I discovered early on my phone was not a good interface with Github's text editor. Some days I had no desire to code or lacked the creativity to write. Then I remembered that my ability to work openly on Github is a gift, and I should just do it. Now I can relax a bit and if I miss a day, it's not such a big deal. I've made it to the Longest Streak list!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="going-for-a-longer-streak"&gt;
&lt;h2&gt;Going for a longer streak&lt;/h2&gt;
&lt;p&gt;We'll see what happens now. I just feel happy that I've captured the moment and made my mark on the board. I invite you to do the same.&lt;/p&gt;
&lt;a class="reference external image-reference" href="http://www.flickr.com/photos/pydanny/7024690837/in/photostream/"&gt;&lt;img alt="http://farm7.staticflickr.com/6216/7024690837_0974c93f63_o.png" class="align-center" id="my-place-on-calendar-about-nothing" src="http://farm7.staticflickr.com/6216/7024690837_0974c93f63_o.png" /&gt;&lt;/a&gt;
&lt;/div&gt;
</summary><category term="python"></category><category term="django"></category></entry><entry><title>Launching our API at PyCon 2012</title><link href="http://pydanny.com/launching-our-api-at-pycon-2012.html" rel="alternate"></link><updated>2012-03-09T07:30:00-08:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2012-03-09:launching-our-api-at-pycon-2012.html</id><summary type="html">&lt;p&gt;A few months ago me and my fiancee, &lt;a class="reference external" href="http://audreymroy.com"&gt;Audrey Roy&lt;/a&gt;, launched our start up, &lt;a class="reference external" href="http://consumernotebook.com"&gt;Consumer Notebook&lt;/a&gt;. It's a Python powered product comparison site that combines the best features of &lt;a class="reference external" href="http://opencomparison.org"&gt;Open Comparison&lt;/a&gt;, Yelp, Consumer Reports, and Pinterest. We've worked day and night to make it better, with countless members of the Python community using the site and giving us invaluable feedback.&lt;/p&gt;
&lt;p&gt;All of that brings us to &lt;a class="reference external" href="http://us.pycon.org/2012/"&gt;PyCon&lt;/a&gt;. We're not just here as attendees and participants, but also to promote our startup.  It used to be the cool thing to launch your startup at SXSW, but times have changed. Now it's the cool thing to launch at PyCon!&lt;/p&gt;
&lt;p&gt;Like Twilio, Twitter, Facebook, and Google, we've got an &lt;a class="reference external" href="http://api.consumernotebook.com"&gt;API&lt;/a&gt; we want developers to use. And as an upcoming startup, we've got to really be creative in how we gain your attention, so here is what we're doing for PyCon 2012:&lt;/p&gt;
&lt;div class="section" id="demos-at-our-pycon-startup-row-booth"&gt;
&lt;h2&gt;1. Demos at our &lt;a class="reference external" href="https://us.pycon.org/2012/community/openspaces/capoeira/"&gt;PyCon Startup Row&lt;/a&gt; booth.&lt;/h2&gt;
&lt;p&gt;Thanks PyCon!&lt;/p&gt;
&lt;p&gt;We've got a booth on Saturday. We've got banners and bright red track jackets. We're giving out handy API reference cards, as well as 10 different &lt;a class="reference external" href="http://consumernotebook.com/lists/audreyr/list-of-oreo-cookie-flavors/"&gt;flavors of Oreo cookies&lt;/a&gt; (see our site for a complete list of every Oreo cookie flavor, by the way).&lt;/p&gt;
&lt;p&gt;So stop on by, sign up for the BETA, have a cookie, and talk to us about our API. For that matter, feel free to talk to me or Audrey about the API any time you see us. We're wearing bright red jackets with '&lt;strong&gt;Ask me about our API&lt;/strong&gt;' on our back.&lt;/p&gt;
&lt;p&gt;Speaking of the API, the next item on our plan is...&lt;/p&gt;
&lt;/div&gt;
&lt;hr class="docutils" /&gt;
&lt;div class="section" id="a-big-kickoff-api-contest"&gt;
&lt;h2&gt;2. A big kickoff API contest.&lt;/h2&gt;
&lt;p&gt;We've put together the Consumer Notebook &lt;a class="reference external" href="http://api.consumernotebook.com"&gt;API&lt;/a&gt;, which lets you get product list
and comparison data out of our site via a simple REST interface.&lt;/p&gt;
&lt;p&gt;We're kicking off our PyCon 2012 API launch with an &lt;a class="reference external" href="http://developers.consumernotebook.com/contest.html"&gt;API contest&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You have from now until April 22 to find new and exciting ways to use our &lt;a class="reference external" href="http://api.consumernotebook.com"&gt;API&lt;/a&gt;. If you win we'll give you a Kindle Fire or equivalent gift certificate valid in your nation of origin.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://developers.consumernotebook.com/contest.html"&gt;API Contest Details&lt;/a&gt;&lt;/p&gt;
&lt;a class="reference external image-reference" href="http://www.flickr.com/photos/pydanny/6821231296/sizes/m/in/photostream/"&gt;&lt;img alt="http://farm8.staticflickr.com/7189/6821231296_d0670e84b7_m.jpg" class="align-center" id="grid-of-python-books" src="http://farm8.staticflickr.com/7189/6821231296_d0670e84b7_m.jpg" /&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;hr class="docutils" /&gt;
&lt;div class="section" id="we-re-hosting-the-saturday-night-pycon-capoeira-open-space"&gt;
&lt;h2&gt;3. We're hosting the Saturday night &lt;a class="reference external" href="https://us.pycon.org/2012/community/openspaces/capoeira/"&gt;PyCon Capoeira Open Space&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Want to see some awesome Capoeira moves? Want to learn some of the basics? Want to just have fun?&lt;/p&gt;
&lt;p&gt;We've hired professional Hollywood stuntman and Capoeira instructor to the stars, &lt;a class="reference external" href="http://valleycapoeira.com/?page_id=7"&gt;Contra Mestre Xingu&lt;/a&gt;, to come up from Los Angeles to lead this event. In addition to appearing in movies, videos, and commercials, he's got first hand experience with snakes. In his own words:&lt;/p&gt;
&lt;blockquote class="epigraph"&gt;
&lt;p&gt;Capoeira saved my life. What? How? Well it was a sunny afternoon, I was shooting a film in the Hollywood hills off Coldwater Canyon at a house. I was running back to set from the bathroom and out of nowhere a rattlesnake jumped up from the ground and tried to bite me. I quickly jumped out of the way and did a fast negative &lt;a class="reference external" href="http://en.wikipedia.org/wiki/List_of_capoeira_techniques#Rol.C3.AA"&gt;rolé&lt;/a&gt; away from the snake. Then I called the other people on set and we caught it. I really didn't think much of it afterwards until after the shoot. My friend told me the rattlesnake was a young one and I'm lucky I didn't get bitten.  When a younger rattler bites you, it usually unloads all of it's venom in you because it cannot control the amount it releases.&lt;/p&gt;
&lt;p class="attribution"&gt;&amp;mdash;Contra Mestre Xingu&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Over 30 people have signed up up for this event, including Python core developers.&lt;/p&gt;
&lt;p&gt;Details:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
When: Saturday, 8pm - 10pm
What to bring: Camera!
What to bring if you are participating: Workout clothes, water bottle
&lt;/pre&gt;
&lt;a class="reference external image-reference" href="http://www.flickr.com/photos/pydanny/6821195620/sizes/s/in/photostream/"&gt;&lt;img alt="http://farm8.staticflickr.com/7182/6821195620_2b7870a39c_m.jpg" class="align-center" id="location-of-the-pycon-capoeira-open-space-event" src="http://farm8.staticflickr.com/7182/6821195620_2b7870a39c_m.jpg" /&gt;&lt;/a&gt;
&lt;p&gt;&lt;strong&gt;Location: The PyCon upstairs central open space&lt;/strong&gt;&lt;/p&gt;
&lt;hr class="docutils" /&gt;
&lt;p&gt;See you around!&lt;/p&gt;
&lt;/div&gt;
</summary><category term="python"></category><category term="django"></category><category term="OAuth"></category><category term="api"></category><category term="Consumer-Notebook"></category><category term="pycon"></category></entry><entry><title>The sorry state of Python OAuth providers</title><link href="http://pydanny.com/the-sorry-state-of-python-oauth-providers.html" rel="alternate"></link><updated>2012-03-05T07:30:00-08:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2012-03-05:the-sorry-state-of-python-oauth-providers.html</id><summary type="html">&lt;p&gt;This is one of those challenging posts to write. The people whose projects I'm going to describe have put in a lot of dedicated, hard work to overcome a challenging subject. Writing an OAuth consumer is a hard problem and writing an OAuth provider is an even harder problem. The efforts put in by the authors of these projects has been nothing short of incredible. The problem, however, is that the existing projects are not usable as-is, and need the support of the community in order to improve.&lt;/p&gt;
&lt;p&gt;The terrible thing is that this is a solved problem within our community. Python based projects are successfully implementing OAuth providers, and often using internally hacked versions of the efforts I'm about to describe. However, they aren't giving this back to the community. It might be that they want to protect their competitive edge, but I'm going to be nice and say that it's because their too busy to find time to send pull requests back.&lt;/p&gt;
&lt;p&gt;In any case, let me present our use case. For &lt;a class="reference external" href="http://consumernotebook.com"&gt;Consumer Notebook&lt;/a&gt; we want an &lt;a class="reference external" href="http://api.consumernotebook.com"&gt;API&lt;/a&gt;. We want to be able to track usernames, passwords, and the application using our &lt;a class="reference external" href="http://api.consumernotebook.com"&gt;API&lt;/a&gt; - which is the OAuth use case. Much as BasicAuth or DigestAuth is the easier way to go in terms of implementation, OAuth was designed for our use case: allowing third-party developers to build apps using our API without having to store credentials. In fact, it's a critical security issue: Twitter dealt with malicious &amp;quot;Twitter apps&amp;quot; stealing usernames and passwords before they switched to OAuth. As an API provider, being an OAuth provider might be more challenging, but it's the responsible thing to do.&lt;/p&gt;
&lt;div class="section" id="existing-oauth-providers"&gt;
&lt;h2&gt;Existing OAuth Providers&lt;/h2&gt;
&lt;p&gt;Time to get into the meat of the issue. Let's look at the current implementations of OAuth providing within the Python community. Again, I wish I didn't have to be negative, but I'm up against the wall:&lt;/p&gt;
&lt;div class="section" id="oauth2app-django"&gt;
&lt;h3&gt;OAuth2app (Django)&lt;/h3&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/hiidef/OAuth2app"&gt;https://github.com/hiidef/OAuth2app&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;OAuth version: 2.0&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Strange URL construction that might be a security hole.&lt;/li&gt;
&lt;li&gt;Bitwise operators in the logic making it harder to debug. Security is hard. Don't complicate your security code because your mistakes will cost.&lt;/li&gt;
&lt;li&gt;Uncommented code. Security is hard. Comment your code.&lt;/li&gt;
&lt;li&gt;Documentation outdated and insufficient.&lt;/li&gt;
&lt;li&gt;Doesn't work without serious hacking and adding of undocumented parameters. Which means I have to worry if I'm breaking anything.&lt;/li&gt;
&lt;li&gt;We managed to get it working with GET requests.  Then we realized that we were using GET requests, which seems like a bad idea.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="django-piston-django"&gt;
&lt;h3&gt;django-piston (Django)&lt;/h3&gt;
&lt;p&gt;&lt;a class="reference external" href="https://bitbucket.org/jespern/django-piston"&gt;https://bitbucket.org/jespern/django-piston&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;OAuth version: 1.0&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Stalled project.&lt;/li&gt;
&lt;li&gt;Documentation insufficient.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="django-oauth-plus-django"&gt;
&lt;h3&gt;django-oauth-plus (Django)&lt;/h3&gt;
&lt;p&gt;&lt;a class="reference external" href="http://code.larlet.fr/django-oauth-plus"&gt;http://code.larlet.fr/django-oauth-plus&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;OAuth version: 1.0a&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Tutorial doesn't work.&lt;/li&gt;
&lt;li&gt;Documentation insufficient.&lt;/li&gt;
&lt;li&gt;Doesn't work without serious hacking. Which means I have to worry if I'm breaking anything.&lt;/li&gt;
&lt;li&gt;We could not get it to work.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="lastuser-flask"&gt;
&lt;h3&gt;lastuser (Flask)&lt;/h3&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/hasgeek/lastuser"&gt;https://github.com/hasgeek/lastuser&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;OAuth version: 2.0&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;No documentation&lt;/li&gt;
&lt;li&gt;No tests to serve as documentation&lt;/li&gt;
&lt;li&gt;Lack of documentation means I'm not sure if it is actually a OAuth provider.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="python-oauth2-python"&gt;
&lt;h3&gt;python-oauth2 (Python)&lt;/h3&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/dgouldin/python-OAuth2"&gt;https://github.com/dgouldin/python-OAuth2&lt;/a&gt; (best example)&lt;/p&gt;
&lt;p&gt;OAuth version: 1.0&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Called 'OAuth2' but only works with OAuth 1? Really? &lt;strong&gt;WTF?&lt;/strong&gt; This needs to fixed.&lt;/li&gt;
&lt;li&gt;Documentation insufficient.&lt;/li&gt;
&lt;li&gt;Provides only a skeleton of a provider. Not a turnkey solution.&lt;/li&gt;
&lt;li&gt;Doesn't work as a provider without serious hacking. Which means I have to worry if I'm breaking anything.&lt;/li&gt;
&lt;li&gt;Many, many forks of the project, with various blog posts advising people to use various particular forks rather than the main one.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="how-about-a-solution"&gt;
&lt;h2&gt;How about a solution?&lt;/h2&gt;
&lt;p&gt;Alright, I've ranted and laid out out a bunch of bullets identifying a problem. Time to try and fix the problem.&lt;/p&gt;
&lt;p&gt;For starters, a production-usable OAuth provider should meet certain standards:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Near turnkey solution&lt;/li&gt;
&lt;li&gt;Working code (duplicates above bullet but I'm making a point)&lt;/li&gt;
&lt;li&gt;Working tutorials&lt;/li&gt;
&lt;li&gt;Documentation&lt;/li&gt;
&lt;li&gt;Commented code&lt;/li&gt;
&lt;li&gt;Linted code&lt;/li&gt;
&lt;li&gt;Test coverage &amp;gt; 80%&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is my specification. If your project for any Python framework matches it, I'll list it on a forthcoming website that also covers Python based OAuth consumers.&lt;/p&gt;
&lt;p&gt;For what it's worth, Idan Gazit has been working on something to help address the problem, specifically &lt;a class="reference external" href="https://github.com/idan/oauthlib"&gt;https://github.com/idan/oauthlib&lt;/a&gt;. It also is intended to cover the Python OAuth consumption issue I didn't cover in this article.  It and related efforts need a lot of work, so...&lt;/p&gt;
&lt;p&gt;The PyCon US 2012 sprints start on March 12. I think as a community, we Pythonistas should band together and make things right. I think we'll have the brainpower and enough eyes on the problem to make serious headway on the issue, either by fixing existing solutions or creating new ones. Right now I've got interest from people to join in and help, including Idan Gazit, Audrey Roy, George Hickman, and others.&lt;/p&gt;
&lt;p&gt;We're willing to put in the time to make OAuth in Python better, how about you?&lt;/p&gt;
&lt;p&gt;Join us at the PyCon US sprints either in person or on-line. &lt;a class="reference external" href="https://us.pycon.org/2012/community/sprints/projects/"&gt;Details of the sprint are near the bottom of this PyCon Sprint page&lt;/a&gt;.&lt;/p&gt;
&lt;a class="reference external image-reference" href="http://oauth.net/"&gt;&lt;img alt="http://farm8.staticflickr.com/7201/6803475636_f34fb400eb_m.jpg" class="align-center" id="oauth-logo" src="http://farm8.staticflickr.com/7201/6803475636_f34fb400eb_m.jpg" /&gt;&lt;/a&gt;
&lt;hr class="docutils" /&gt;
&lt;div class="section" id="updates"&gt;
&lt;h3&gt;Updates&lt;/h3&gt;
&lt;p&gt;03/05/2012 - Removed Velruse from the list of providers as it's lead, Michael Merickel, clarified that it is not a provider.
03/06/2012 - Added a link to the PyCon OAuth sprints.&lt;/p&gt;
&lt;hr class="docutils" /&gt;
&lt;p&gt;&lt;a class="reference external" href="http://news.ycombinator.com/item?id=3666853"&gt;Discuss this post on Hacker News&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</summary><category term="python"></category><category term="django"></category><category term="OAuth"></category><category term="api"></category><category term="Consumer-Notebook"></category><category term="rant"></category></entry><entry><title>You should Heroku</title><link href="http://pydanny.com/you-should-heroku.html" rel="alternate"></link><updated>2012-02-28T12:45:00-08:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2012-02-28:you-should-heroku.html</id><summary type="html">&lt;p&gt;In mid-November me and my fiancee, &lt;a class="reference external" href="http://audreymroy.com"&gt;Audrey Roy&lt;/a&gt; began our startup. We had been frustrated with trying to do on-line product research and came up with an idea to take the lessons learned from &lt;a class="reference external" href="http://djangopackages.com"&gt;Django Packages&lt;/a&gt; / &lt;a class="reference external" href="http://opencomparison.org"&gt;Open Comparison&lt;/a&gt; and apply them to a commercial effort. The result has been &lt;a class="reference external" href="http://consumernotebook.com"&gt;Consumer Notebook&lt;/a&gt;, and it's been a steadily growing success.&lt;/p&gt;
&lt;p&gt;We've been bootstrapping the project. That means supporting it with consulting and grinding away on it during our free time. That means 12-16 hour days of Python, Django, and Javascript coding, marketing, system administration, graphic design, communicating with users and vendors, and a thousand other tasks. Since we've had to explore new techniques for making things work on the backend and front end, that means we've needed to have a robust system that is trivial to deploy and certain to never go down. Which, of course, requires serious sys admin skills.&lt;/p&gt;
&lt;div class="section" id="the-big-problem"&gt;
&lt;h2&gt;The Big Problem&lt;/h2&gt;
&lt;blockquote class="pull-quote"&gt;
&lt;strong&gt;I hate system administration work.&lt;/strong&gt;&lt;/blockquote&gt;
&lt;p&gt;Sys admin is boring. I find it tedious and dull. Devops doesn't make it easier/faster, it just makes it possible to do it at a large scale.&lt;/p&gt;
&lt;p&gt;Fortunately for me, my fiancee likes the sys admin side of things. However, she's got serious programming skills in Python/Javascript, understands CSS, is an excellent illustrator, and has good business skills to boot. Which means &lt;strong&gt;I needed Audrey not to be doing sys admin&lt;/strong&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="solution-platform-as-a-service"&gt;
&lt;h2&gt;Solution: Platform as a Service&lt;/h2&gt;
&lt;p&gt;Platform as a Service, or &lt;a class="reference external" href="http://en.wikipedia.org/wiki/PaaS"&gt;PaaS&lt;/a&gt;, is where someone else does the majority of work involved in system administration. There are now &lt;a class="reference external" href="http://www.quora.com/What-is-the-Heroku-equivalent-for-Django-applications-Edit-Question-not-relevant-anymore-as-Heroku-now-supports-Django"&gt;dozens of companies edging into the Python capable PaaS space&lt;/a&gt;. We've been leery of using any of them but finally settled on &lt;a class="reference external" href="http://heroku.com"&gt;Heroku&lt;/a&gt; after a long period of evaluation.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="why-heroku"&gt;
&lt;h2&gt;Why Heroku?&lt;/h2&gt;
&lt;p&gt;We choose Heroku for a number of reasons:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;We competed in a Los Angeles area Hacking contest with &lt;a class="reference external" href="http://rdegges.com/"&gt;Randall Degges&lt;/a&gt;. He was responsible for the sys admin and went with Heroku. He got it up and it was out of the way for the competition. He spent his time coding, adding features, and fixing templates instead of tweaking knobs on something in the cloud. We saw other people not deliver products at the contest because of this issue.&lt;/li&gt;
&lt;li&gt;Heroku doesn't lock you in. If I wanted to, I could take all the pieces out in about 10 minutes, then go old school and host it myself on my own closet server.&lt;/li&gt;
&lt;li&gt;Heroku has very good &lt;a class="reference external" href="http://devcenter.heroku.com/categories/heroku-postgres"&gt;PostgreSQL&lt;/a&gt; support. Our web framework is &lt;a class="reference external" href="http://djangoproject.com"&gt;Django&lt;/a&gt;, which has an ORM that works best with PostgreSQL.&lt;/li&gt;
&lt;li&gt;Heroku has staff. At least seventy of them. Odds are they would have people around 24/7 to deal with issues.&lt;/li&gt;
&lt;li&gt;The add-on system means they've got many other people adding great new features. Want &lt;a class="reference external" href="https://addons.heroku.com/mongolab"&gt;MongoDB&lt;/a&gt;? No problem! How about something to &lt;a class="reference external" href="https://addons.heroku.com/pandastream"&gt;handle video&lt;/a&gt;? You got it!&lt;/li&gt;
&lt;li&gt;Heroku scales up trivially. If we get an upswell of users, I just type &lt;tt class="docutils literal"&gt;heroku ps:scale web=50&lt;/tt&gt; and I've got 50 web server things handling the load.&lt;/li&gt;
&lt;li&gt;When I think of Heroku I think of Puffer Fish. Which is awesome because Puffer Fish are awesome.&lt;/li&gt;
&lt;/ol&gt;
&lt;a class="reference external image-reference" href="http://www.flickr.com/photos/saspotato/5776592544/"&gt;&lt;img alt="http://farm6.staticflickr.com/5303/5776592544_fb15a2902a_m.jpg" class="align-center" id="puffer-fish" src="http://farm6.staticflickr.com/5303/5776592544_fb15a2902a_m.jpg" /&gt;&lt;/a&gt;
&lt;p&gt;Creative Commons: Some rights reserved by &lt;a class="reference external" href="http://www.flickr.com/photos/saspotato/5776592544/"&gt;Saspotato&lt;/a&gt;&lt;/p&gt;
&lt;div class="section" id="things-that-we-really-liked-about-using-heroku"&gt;
&lt;h3&gt;Things that we really liked about using Heroku&lt;/h3&gt;
&lt;p&gt;As we progressed down the journey of building our site, we discovered even more nice features about Heroku. Here are some of the things that really make me smile:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://devcenter.heroku.com/articles/releases"&gt;Releases&lt;/a&gt; and especially &lt;a class="reference external" href="http://devcenter.heroku.com/articles/releases#rollback"&gt;rollbacks&lt;/a&gt; means we deploy with a lot more confidence.&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://devcenter.heroku.com/articles/logging"&gt;Logging&lt;/a&gt; and other diagnostic add-ons like &lt;a class="reference external" href="https://addons.heroku.com/sentry"&gt;Sentry&lt;/a&gt; and &lt;a class="reference external" href="https://addons.heroku.com/newrelic"&gt;New Relic&lt;/a&gt; means we know what's going on.&lt;/li&gt;
&lt;li&gt;During one huge data migration effort I scaled up the workers so a 6 hour task became a 5 minute task. Cost was less then 10 cents for workers instead of me losing hours of labor.&lt;/li&gt;
&lt;li&gt;In case we go viral, we don't have to worry about load balancers and all that high performance stuff.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="what-does-that-mean"&gt;
&lt;h2&gt;What does that mean?&lt;/h2&gt;
&lt;p&gt;It means I'm doing the deployments. I'm the sys admin. And I'm happy with my role because it takes minutes out of my day. Me and Audrey team up on everything else and the results so far have been great. If you've ever worked with me, the fact that &lt;a class="reference external" href="http://consumernotebook.com"&gt;Consumer Notebook&lt;/a&gt; is administered and deployed by me is going to be a shock.&lt;/p&gt;
&lt;p&gt;We've been able to really focus on development of the project. And when I mean development, I mean a lot of things. I mean:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;Django&lt;/li&gt;
&lt;li&gt;HTML&lt;/li&gt;
&lt;li&gt;CSS&lt;/li&gt;
&lt;li&gt;JavaScript&lt;/li&gt;
&lt;li&gt;Data Modeling&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://api.consumernotebook.com/"&gt;Documenting the API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Marketing: &lt;a class="reference external" href="http://insidertips.consumernotebook.com/"&gt;blogging on Consumer Notebook&lt;/a&gt;, &lt;a class="reference external" href="https://twitter.com/consumernotebk"&gt;Tweeting&lt;/a&gt;, and working with other groups&lt;/li&gt;
&lt;li&gt;Trying out &lt;a class="reference external" href="https://github.com/consumernotebook/tickets/issues"&gt;public tickets&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Iterating through the user experience by communicating to users&lt;/li&gt;
&lt;li&gt;All the boring legal and business stuff&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What you don't see is anything about sys admin issues. That's because what could have been a huge sink in time and resources is pretty much gone. We deploy staging servers with a bit of code I copy/pasted from a bash history into a Fabric script:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;fabric.api&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;local&lt;/span&gt;

&lt;span class="n"&gt;commands&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class="s"&gt;heroku create --stack cedar&lt;/span&gt;
&lt;span class="s"&gt;heroku addons:add memcache&lt;/span&gt;
&lt;span class="s"&gt;heroku config:add S3_KEY=HAHAHAHAHAHA S3_SECRET=NOTGIVINGITOUT&lt;/span&gt;
&lt;span class="s"&gt;heroku addons:add redistogo&lt;/span&gt;
&lt;span class="s"&gt;heroku addons:add sendgrid:starter&lt;/span&gt;
&lt;span class="s"&gt;heroku addons:add mongolab:starter&lt;/span&gt;
&lt;span class="s"&gt;heroku addons:add sentry:test&lt;/span&gt;
&lt;span class="s"&gt;heroku addons:add pgbackups&lt;/span&gt;
&lt;span class="s"&gt;heroku addons:add custom_domains:basic&lt;/span&gt;
&lt;span class="s"&gt;heroku addons:add zerigo_dns:basic&lt;/span&gt;
&lt;span class="s"&gt;heroku domains:add staging.consumernotebook.com&lt;/span&gt;
&lt;span class="s"&gt;heroku addons:add ssl:piggyback&lt;/span&gt;
&lt;span class="s"&gt;git push heroku master&lt;/span&gt;
&lt;span class="s"&gt;heroku scale web=1&lt;/span&gt;
&lt;span class="s"&gt;heroku addons:add heroku-PostgreSQL:ronin&lt;/span&gt;
&lt;span class="s"&gt;heroku pg:wait&lt;/span&gt;
&lt;span class="s"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;build_staging&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;commands&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;How awesome is that?&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="how-much-does-heroku-really-cost"&gt;
&lt;h2&gt;How much does Heroku really cost?&lt;/h2&gt;
&lt;p&gt;You can do Heroku for free. A lot of people do. More power to them.&lt;/p&gt;
&lt;p&gt;But let's face it, beyond a certain point, every PaaS, including Heroku, is going to be more expensive then getting your own EC2, Rackspace, Dreamhost, or Linode hosted server. For a fraction of the cost, you can provision a server, install all the bits, configure the database, http server, load balancers, and even write Chef/Puppet/Fabric scripts so you can do it repeatedly at scale. Cheap!&lt;/p&gt;
&lt;p&gt;So why pay more for Heroku? Why not just do it ourselves? For example, right now we're on dedicated PostgreSQL hosting which Heroku charges us $200/month. That's a lot, right?&lt;/p&gt;
&lt;blockquote class="pull-quote"&gt;
&lt;strong&gt;Wrong.&lt;/strong&gt;&lt;/blockquote&gt;
&lt;p&gt;Right now we're seeing a 50% increase in visits every day. So if we ran our own servers, Chef/Puppet/Fabric or not, odds are we would be spending at least 10 hours a month doing server work. And I can assure you that when we consult that we make more than $20/hour.&lt;/p&gt;
&lt;blockquote class="pull-quote"&gt;
&lt;strong&gt;$200 &amp;lt; 10 hours of us doing consulting work to bootstrap the project.&lt;/strong&gt;&lt;/blockquote&gt;
&lt;p&gt;Until you hit a certain point, these days the real cost of servers is labor. If you're a developer or small effort, and you think going with a cheap hosting provider is the way to go, think again. Think about the hours you're losing monkeying around with servers and databases instead of getting code done.&lt;/p&gt;
&lt;p&gt;Heroku saves us money.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="the-takeaway"&gt;
&lt;h2&gt;The Takeaway&lt;/h2&gt;
&lt;p&gt;One of the problems Django and other Python web frameworks has had is the difficulty of deployment. I can't tell you how many projects I didn't do because of the thought of handling the sys admin side of things. Let's face it, one of the great ongoing successes for PHP is that deploying the majority of sites is trivial.&lt;/p&gt;
&lt;p&gt;With the rise of devops we've seen a lot of developers across languages and frameworks dive into &lt;strong&gt;Chef&lt;/strong&gt; and &lt;strong&gt;Puppet&lt;/strong&gt;. It's been sadly amusing watching people muck around with these great tools to make the deployment of 1-2 servers 'easier', when the real benefit of those tools has been to do things at scale. Things like deployments of fifty servers at once or deployment abstractions for hundreds of people (my fancy talk for PaaS).&lt;/p&gt;
&lt;p&gt;In any case, things have changed. Deploying Python web apps is as trivial as deploying PHP code.&lt;/p&gt;
&lt;p&gt;For developers I see great times ahead.&lt;/p&gt;
&lt;hr class="docutils" /&gt;
&lt;p&gt;&lt;a class="reference external" href="http://news.ycombinator.com/item?id=3643910"&gt;Discuss this post on Hacker News&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
</summary><category term="python"></category><category term="django"></category><category term="heroku"></category><category term="consumernotebook"></category><category term="mongodb"></category></entry><entry><title>My PyCon 2012 Schedule</title><link href="http://pydanny.com/my-pycon-2012-schedule.html" rel="alternate"></link><updated>2012-02-22T09:00:00-08:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2012-02-22:my-pycon-2012-schedule.html</id><summary type="html">&lt;p&gt;Here I was thinking that this year's PyCon wasn't going to be so busy because I didn't submit a talk or tutorial. Ha! What the heck was I thinking?&lt;/p&gt;
&lt;p&gt;Here's what I've already got in the works.&lt;/p&gt;
&lt;div class="section" id="wednesday-march-7th"&gt;
&lt;h2&gt;Wednesday, March 7th&lt;/h2&gt;
&lt;p&gt;Me and Audrey are driving up from Los Angeles. I've wanted to do this drive for a while, so this is very exciting. We'll arrive in the evening and hopefully tag up with friends old and new.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="thursday-march-8th"&gt;
&lt;h2&gt;Thursday, March 8th&lt;/h2&gt;
&lt;p&gt;I'm moderating the Code Reuse panel of the Python Web Summit. &lt;a class="reference external" href="http://www.google.com/moderator/#15/e=1c9a94&amp;amp;t=1c9a94.43"&gt;Have you submitted a question yet&lt;/a&gt;?&lt;/p&gt;
&lt;p&gt;In the evening we'll be helping assemble bags for the conference. That's always a blast.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="friday-march-9th"&gt;
&lt;h2&gt;Friday, March 9th&lt;/h2&gt;
&lt;p&gt;PyCon really begins! I'll be at the keynotes, and then the talks begin. These are some of the talks I'm really leaning towards watching:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2012/schedule/presentation/64/"&gt;Introduction to Metaclasses&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2012/schedule/presentation/399/"&gt;The Art of Subclassing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2012/schedule/presentation/249/"&gt;Data, Design, Meaning&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2012/schedule/presentation/246/"&gt;Code Generation in Python: Dismantling Jinja&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The problem, of course, is that all the talks look awesome. Missing some of these talks is going to hurt.&lt;/p&gt;
&lt;p&gt;In the evening we're going to the New Relic/Loggly/Skull Candy party and hang out at the (in)famous TIP BOF.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="saturday-march-10th"&gt;
&lt;h2&gt;Saturday, March 10th&lt;/h2&gt;
&lt;p&gt;I'll be at the &lt;a class="reference external" href="http://consumernotebook.com"&gt;Consumer Notebook&lt;/a&gt; &lt;a class="reference external" href="http://pycon.blogspot.com/2012/02/startup-row-winners-for-pycon-2012.html"&gt;Startup Row&lt;/a&gt; booth all day! Come and hang out with us and all the other bright, new companies.&lt;/p&gt;
&lt;p&gt;In the evening I'm hosting the &lt;a class="reference external" href="https://us.pycon.org/2012/community/openspaces/capoeira/"&gt;PyCon Capoeira Open Space&lt;/a&gt;. We've got a seriously large room assigned for the event, and over twenty five people currently signed up to participate (&lt;a class="reference external" href="http://bit.ly/pycon-capoeira"&gt;there's still room for signups&lt;/a&gt;). Even if you don't want to play a musical instrument or learn/play at Capoeira, come anyway to watch. Some of the players there have some seriously amazing skills - I can assure you've seen them in the movies.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="sunday-march-11th"&gt;
&lt;h2&gt;Sunday, March 11th&lt;/h2&gt;
&lt;p&gt;More talks!&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2012/schedule/presentation/482/"&gt;Transifex&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2012/schedule/presentation/301/"&gt;Sketching a better product&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2012/schedule/presentation/66/"&gt;Building A Python-Based Search Engine&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://us.pycon.org/2012/schedule/presentation/168/"&gt;Diversity in practice&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="monday-march-12-thursday-march-15"&gt;
&lt;h2&gt;Monday March 12 - Thursday, March 15&lt;/h2&gt;
&lt;p&gt;Sprints! Nothing set in stone yet, but some ideas I've had include:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Launch python.opencomparison.org for all of Python.&lt;/li&gt;
&lt;li&gt;OpenComparison integration of PyPI OpenID, SourceForge OAUTH, and BitBucket OAUTH.&lt;/li&gt;
&lt;li&gt;Improved OpenComparison integration of the Launchpad API.&lt;/li&gt;
&lt;li&gt;Implement Gitorious API for OpenComparison.&lt;/li&gt;
&lt;li&gt;Implement Text Based search for OpenComparison.&lt;/li&gt;
&lt;li&gt;Hack on Mongo related technologies such as django-mongonaut and some other planned projects.&lt;/li&gt;
&lt;/ul&gt;
&lt;div style="text-align: center;"&gt;&lt;a href="https://us.pycon.org/2012/"&gt;&lt;img border="0" height="102" width="277" src="http://1.bp.blogspot.com/-fa4jnLXs1so/TniyemLkoiI/AAAAAAAAAqo/LjZqklTFBXk/s400/pycon2012.png"&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
</summary><category term="python"></category><category term="pycon"></category><category term="consumernotebook"></category><category term="django"></category></entry><entry><title>Selected for PyCon StartUp Row</title><link href="http://pydanny.com/selected-for-pycon-startup-row.html" rel="alternate"></link><updated>2012-02-21T01:00:00-08:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2012-02-21:selected-for-pycon-startup-row.html</id><summary type="html">&lt;p&gt;Me and Audrey have been working hard on &lt;a class="reference external" href="http://consumernotebook.com"&gt;Consumer Notebook&lt;/a&gt;, a Python/Django based project. We submitted it to PyCon StartUp row and found out this morning we've been accepted. &lt;strong&gt;Hooray!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;From the &lt;a class="reference external" href="http://pycon.blogspot.com/2012/02/startup-row-winners-for-pycon-2012.html"&gt;PyCon StartUp Row winner's post&lt;/a&gt;, here is a little bit of what we're about:&lt;/p&gt;
&lt;blockquote class="highlights"&gt;
Have you tried researching products online recently? Search engines are gamed by scammy marketers. Product review sites overwhelm you with ads, have unreliable reviews, or dryly compare raw product specs. &lt;a class="reference external" href="http://consumernotebook.com"&gt;Consumer Notebook&lt;/a&gt; is working to solve this problem. It is like Yelp for products, with product comparison grids inspired by the founders' open-source work on &lt;a class="reference external" href="http://djangopackages.com"&gt;Django Packages&lt;/a&gt; and &lt;a class="reference external" href="http://opencomparison.org"&gt;Open Comparison&lt;/a&gt;.&lt;/blockquote&gt;
&lt;p&gt;Just so you know, &lt;a class="reference external" href="http://us.pycon.org"&gt;PyCon&lt;/a&gt; in North America is the biggest gathering for the international Python community. The conference this year is in Santa Clara, California, and is sold-out at 1500+ attendees, but could have easily sold out several times that number. The talks, tutorials, and events are going to be incredible, and I'm delighted to be part of the PyCon experience!&lt;/p&gt;
&lt;p&gt;We look forward to sharing the StartUp Row with friends like Transifex, Python Packages, and &lt;a class="reference external" href="http://www.weddinglovely.com/"&gt;Wedding Lovely&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Please check out &lt;a class="reference external" href="http://consumernotebook.com"&gt;Consumer Notebook&lt;/a&gt; right now and also visit our PyCon booth on Saturday, March 10th and we'll show you what we're doing.&lt;/p&gt;
</summary><category term="python"></category><category term="pycon"></category><category term="audrey"></category><category term="consumernotebook"></category><category term="django"></category></entry><entry><title>django-uni-form end of life</title><link href="http://pydanny.com/django-uni-form-end-of-life.html" rel="alternate"></link><updated>2012-02-18T01:00:00-08:00</updated><author><name>Daniel-Greenfeld</name></author><id>tag:pydanny.com,2012-02-18:django-uni-form-end-of-life.html</id><summary type="html">&lt;p&gt;I started on django-uni-form in January 2009. In order to use &lt;a class="reference external" href="http://pinaxproject.com"&gt;Pinax&lt;/a&gt; on an internal social network for &lt;a class="reference external" href="http://www.nasa.gov"&gt;NASA&lt;/a&gt; HQ, we had to render all content, including forms, &lt;a class="reference external" href="http://django-uni-form.readthedocs.org/en/latest/concepts.html#section-508"&gt;Section 508&lt;/a&gt; compliant. Rather than rewrite the html for all 50+ forms that existed in the  Pinax 0.5.x framework at that time, I decided to minimize my work and automate things. &lt;a class="reference external" href="http://jtauber.com"&gt;James Tauber&lt;/a&gt; gave guidance and insight, my co-workers were supportive, and &lt;a class="reference external" href="http://enn.io"&gt;Jannis Leidel&lt;/a&gt; suggested the Uni-form library. The name &lt;strong&gt;Django Uni-Form&lt;/strong&gt; was obvious, and lo the project was named.&lt;/p&gt;
&lt;p&gt;Looking at the old, extremely deprecated &lt;a class="reference external" href="http://code.google.com/p/django-uni-form/"&gt;Google Code site for django-uni-form&lt;/a&gt;, I see that the first commit happened on January 7th, 2009. That was for version 0.1, with some core code that was literally a merger between the Django form example on how to integrate divs into forms and the simplest template tag I could figure out.&lt;/p&gt;
&lt;p&gt;The python code in uni_form/templatetags/uni_form.py:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.template&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Template&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.template.loader&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;get_template&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;template&lt;/span&gt;


&lt;span class="n"&gt;register&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Library&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nd"&gt;@register.filter&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;as_uni_form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;templates/uni_form.html&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;form&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The template tag code was nearly exactly copy/pasted from the starter &lt;a class="reference external" href="https://docs.djangoproject.com/en/1.0/topics/forms/#looping-over-the-form-s-fields"&gt;Django docs on forms&lt;/a&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nv"&gt;field&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;form&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;span class="x"&gt;    &amp;lt;div class=&amp;quot;ctrlHolder &lt;/span&gt;&lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nv"&gt;field.errors&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;&lt;span class="x"&gt;error&lt;/span&gt;&lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;endif&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;&lt;span class="x"&gt;&amp;quot;&amp;gt;&lt;/span&gt;
&lt;span class="x"&gt;        &lt;/span&gt;&lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nv"&gt;error&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;field.errors&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;span class="x"&gt;            &amp;lt;p class=&amp;quot;errorField&amp;quot;&amp;gt;&lt;/span&gt;
&lt;span class="x"&gt;                &amp;lt;strong&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;error&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="x"&gt;&amp;lt;/strong&amp;gt;&lt;/span&gt;
&lt;span class="x"&gt;            &amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="x"&gt;        &lt;/span&gt;&lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;endfor&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;span class="x"&gt;        &lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;field.label_tag&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;span class="x"&gt;        &lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;field&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;span class="x"&gt;        &lt;/span&gt;&lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nv"&gt;field.help_text&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;span class="x"&gt;        &amp;lt;p class=&amp;quot;formHint&amp;quot;&amp;gt;&lt;/span&gt;
&lt;span class="x"&gt;            &lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;field.help_text&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;span class="x"&gt;        &amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="x"&gt;        &lt;/span&gt;&lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;endif&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;

&lt;span class="x"&gt;    &amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;endfor&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Using it was trivial, you just wrote out:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;load&lt;/span&gt; &lt;span class="nv"&gt;uni_form&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;

&lt;span class="x"&gt;&amp;lt;form&amp;gt;&lt;/span&gt;
&lt;span class="x"&gt;    &lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;form&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nf"&gt;as_uni_form&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;span class="x"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;div class="section" id="days-of-django-uni-form"&gt;
&lt;h2&gt;Days of django-uni-form&lt;/h2&gt;
&lt;p&gt;Leading up to &lt;cite&gt;PyCon&lt;/cite&gt; 2009 James Tauber suggested some things that lead to the &lt;a class="reference external" href="http://django-uni-form.readthedocs.org/en/latest/concepts.html#form-helpers"&gt;FormHelpers&lt;/a&gt;, and we hammered out the API on IRC. We knew it crossed the rigid lines between Model-View-Template, but sometimes it's advantageous to break a few rules and abstractions in order to get better things down the road&lt;/p&gt;
&lt;p&gt;At PyCon 2009 with the mentoring of Jannis, James, and &lt;a class="reference external" href="http://twitter.com/brosner"&gt;Brian Rosner&lt;/a&gt;, I moved the project from google code to &lt;a class="reference external" href="https://github.com/pydanny/django-uni-form"&gt;Github&lt;/a&gt;. Jannis released it on &lt;a class="reference external" href="http://pypi.python.org/pypi/"&gt;PyPI&lt;/a&gt; and I followed the pattern he showed me for two years. Yeah, I learned tons under those guys.&lt;/p&gt;
&lt;p&gt;After PyCon 2009 a pull request with the &lt;a class="reference external" href="http://django-uni-form.readthedocs.org/en/latest/helpers.html#layouts"&gt;Layout&lt;/a&gt; helper was provided. It took some work to make it pass all the tests and use cases, but the end result was definition of form layout in the Python. This broke the rigid battle lines of Model-View-Template and left purists screaming in agony, but it certainly made working with forms in Django trivially easy.&lt;/p&gt;
&lt;p&gt;Lots of people started to use the project across projects like Pinax and organizations like NASA, &lt;a class="reference external" href="http://pbs.org"&gt;PBS&lt;/a&gt;, Discovery Channel, various newspapers and many others. Lots of pull requests came in and the features grew.&lt;/p&gt;
&lt;p&gt;In 2010, &lt;a class="reference external" href="http://twitter.com/arowla"&gt;Alice Rowland&lt;/a&gt; submitted the first &lt;a class="reference external" href="http://sphinx.pocoo.org/"&gt;Sphinx&lt;/a&gt; docs, and it was her work that really helped get me started on doing lots of Sphinx work.&lt;/p&gt;
&lt;p&gt;And, all the way into 2011, pull requests for Django Form Sets started to come rolling in, and almost none were of acceptable quality. They never came with documentation, tests, and almost always broke existing tests really hard. Since I'm not a huge fan of Django FormSets, I didn't want to put in a ton of effort making them work. I believe one of them was pretty good, but life was crazy busy at the time and I let it slide. Apologies to whoever it was gave me a working FormSet pull request with documentation, tests, and working code.&lt;/p&gt;
&lt;p&gt;Long periods were going by without new versions. I admit I often slow about accepting pull requests. Life was busy and reviewing the incoming code took a lot of time. Browser cross-checking, running tests, and more was really time consuming. I tried to get others to become co-leads on the project, but invariably they didn't have time to do it. Note: If someone asks you to co-lead something, respond in 24 hours.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="enter-miguel-araujo"&gt;
&lt;h2&gt;Enter Miguel Araujo&lt;/h2&gt;
&lt;p&gt;After PyCon 2011, when there was some unpleasant stress in my life, I woke up cranky one morning and mouthed off on twitter to this guy who asked me to accept a pull request on django-uni-form. This guy tweeted back to me saying I ought to be nicer since I had a library people liked.&lt;/p&gt;
&lt;p&gt;He was right.&lt;/p&gt;
&lt;p&gt;I apologized to the guy (&lt;a class="reference external" href="http://twitter.com/maraujop"&gt;Miguel Araujo&lt;/a&gt;) and remembered my manners. Over the next couple of months we chatted via Twitter and Github's messaging system. He was smart, trustworthy, and passionate about everything he did. I knew I had found my co-lead. He responded promptly and I gave him commit rights.&lt;/p&gt;
&lt;p&gt;Working together (with him doing the vast majority of the work), we moved the project into new releases. The architecture and design changed, driven by discussions we had together. The code was cleaned up, gnarly bits in there to support old versions of Python and Django kicked out, and the documentation revised. The project had new life!&lt;/p&gt;
&lt;p&gt;The only blip I saw with Miguel is my own fault of sometimes being too nice as a project leader when it comes to accepting pull requests. &lt;a class="reference external" href="http://django-uni-form.readthedocs.org/en/latest/contributing.html#how-to-get-your-pull-request-accepted"&gt;I believe pull requests should be really atomic&lt;/a&gt; - for one thing and one thing only with support tests and documentation. Otherwise it becomes nigh impossible to incorporate them and these days I reject multi-purpose pull requests.  One pull request in particular took a huge amount of debate and discussion to work in. I think after that Miguel is much better at being upfront at the beginning about rejecting pull requests with giant scopes.&lt;/p&gt;
&lt;p&gt;During all this I asked Miguel to take over the project, he accepted, and &lt;a class="reference external" href="http://pydanny.blogspot.com/2011/06/announcing-django-uni-form-080-beta.html"&gt;I even blogged my announcement his role as project leader&lt;/a&gt;. Miguel is indeed very nice and after that fact he asked me to remain on board as co-lead.&lt;/p&gt;
&lt;p&gt;We finally met in September of 2011 and co-presented on &lt;a class="reference external" href="http://www.slideshare.net/pydanny/advanced-django-forms-usage"&gt;Advanced Django Form Usage at DjangoCon 2011&lt;/a&gt;. The deepest technical material we presented was authored by Miguel. During our research he uncovered at least one bug in Django and got an ancient bug closed. It was a great experience and I hope he'll co-present with me in the future.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="django-uni-form-is-dead-long-live-django-crispy-forms"&gt;
&lt;h2&gt;django-uni-form is dead, long live django-crispy-forms&lt;/h2&gt;
&lt;p&gt;The upside of django-uni-form is that it grew in features organically thanks to my own needs and general community effort. The downside of django-uni-form is that it grew in features organically thanks to my own needs and general community effort. In any long running project there is cruft and weird patterns that start to hurt after a while. django-uni-form was no different.&lt;/p&gt;
&lt;p&gt;So I'm making this absolutely official as of now. &lt;strong&gt;django-uni-form is at it's end of life&lt;/strong&gt;. It's done and kaput. No more pull requests will be accepted and the issue tracker will be turned off shortly. Just so no one is mistaken:&lt;/p&gt;
&lt;blockquote&gt;
&lt;strong&gt;django-uni-form is deprecated. Use django-crispy-forms&lt;/strong&gt;&lt;/blockquote&gt;
&lt;p&gt;Miguel asked if he could start the project anew, under a different name. We both had been uncomfortable with the name &lt;em&gt;django-uni-form&lt;/em&gt; for some time, especially since it had almost nothing to do with Uni-form anymore. In fact, I often using template overrides to avoid the Uni-form HTML layout - the most common alternative being &lt;a class="reference external" href="http://twitter.github.com/bootstrap/"&gt;Twitter Bootstrap&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We tossed around names for the project, but all of them were stupid, especially mine. We are both huge fans and users of &lt;a class="reference external" href="https://github.com/brutasse/django-floppyforms"&gt;django-floppyforms&lt;/a&gt; (HTML5 form widget app), so my fiancee, &lt;a class="reference external" href="http://audreymroy.com"&gt;Audrey Roy&lt;/a&gt;, suggested django-crispy-forms. And lo, the project was named.&lt;/p&gt;
&lt;p&gt;Right now &lt;a class="reference external" href="https://github.com/maraujop/django-crispy-forms"&gt;django-crispy-forms&lt;/a&gt; has an improved API, better performance, and supports both Twitter bootstrap forms 2.0 and UniForm. Adding new form layouts will be easier, and feature controls will be better.&lt;/p&gt;
&lt;p&gt;What you should be using now is &lt;a class="reference external" href="https://github.com/maraujop/django-crispy-forms"&gt;django-crispy-forms&lt;/a&gt;. Don't worry about changing over as there are &lt;a class="reference external" href="http://django-crispy-forms.readthedocs.org/en/d-0/migration.html"&gt;migration instructions&lt;/a&gt; on the &lt;a class="reference external" href="http://django-crispy-forms.readthedocs.org/"&gt;excellent documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Try it. You'll like it. :-)&lt;/p&gt;
&lt;/div&gt;
</summary><category term="django"></category><category term="python"></category></entry></feed>