<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
     xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
     xmlns:atom="http://www.w3.org/2005/Atom"
     xmlns:dc="http://purl.org/dc/elements/1.1/"
     xmlns:wfw="http://wellformedweb.org/CommentAPI/"
     >
  <channel>
    <title>Death of a Gremmie</title>
    <link>http://deathofagremmie.com</link>
    <description>Brian Neal's blog about programming.</description>
    <pubDate>Sun, 13 May 2012 18:30:33 GMT</pubDate>
    <generator>Blogofile</generator>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Fixed pages for Django</title>
      <link>http://deathofagremmie.com/2012/05/13/fixed-pages-for-django</link>
      <pubDate>Sun, 13 May 2012 13:30:00 CDT</pubDate>
      <category><![CDATA[Django]]></category>
      <guid isPermaLink="true">http://deathofagremmie.com/2012/05/13/fixed-pages-for-django</guid>
      <description>Fixed pages for Django</description>
      <content:encoded><![CDATA[<div class="document">
<p>I have been using Django's <a class="reference external" href="https://docs.djangoproject.com/en/1.4/ref/contrib/flatpages/">flatpages app</a> for some simple, static pages that
were supposed to be temporary. I slapped a Javascript editor on the admin page
and it has worked very well. However some of the pages have long outlived their
&quot;temporary&quot; status, and I find myself needing to update them. It is then that I
get angry at the Javascript editor, and there is no way to keep any kind of
history on the page without having to fish through old database backups. I
started to think it would be nice to write the content in a nice markup
language, for example <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a>, which I could then commit to version
control. I would just need a way to generate HTML from the source text to
produce the flatpage content.</p>
<p>Of course I could use the template filters in <a class="reference external" href="https://docs.djangoproject.com/en/1.4/ref/contrib/markup/">django.contrib.markup</a>. But
turning markup into HTML at page request time can be more expensive than I like.
Yes, I could cache the page, but I'd like the process to be more explicit.</p>
<p>In my first attempt at doing this, I wrote a <a class="reference external" href="https://docs.djangoproject.com/en/1.4/howto/custom-management-commands/">custom management command</a> that
used a dictionary in my <tt class="docutils literal">settings.py</tt> file to map reStructuredText files to
flatpage URLs. My management command would open the input file, convert it to
HTML, then find the <tt class="docutils literal">FlatPage</tt> object associated with the URL. It would then
update the object with the new HTML content and save it.</p>
<p>This worked okay, but in the end I decided that the pages I wanted to update
were not temporary, quick &amp; dirty pages, which is kind of how I view flatpages.
So I decided to stop leaning on the flatpages app for these pages.</p>
<p>I then modified the management command to read a given input file, convert it
to an HTML fragment, then save it in my templates directory. Thus, a file stored
in my project directory as <tt class="docutils literal">fixed/about.rst</tt> would get transformed to
<tt class="docutils literal">templates/fixed/about.html</tt>. Here is the source to the command which I saved
as <tt class="docutils literal">make_fixed_page.py</tt>:</p>
<div class="highlight"><pre><span class="kn">import</span> <span class="nn">os.path</span>
<span class="kn">import</span> <span class="nn">glob</span>

<span class="kn">import</span> <span class="nn">docutils.core</span>
<span class="kn">from</span> <span class="nn">django.core.management.base</span> <span class="kn">import</span> <span class="n">LabelCommand</span><span class="p">,</span> <span class="n">CommandError</span>
<span class="kn">from</span> <span class="nn">django.conf</span> <span class="kn">import</span> <span class="n">settings</span>


<span class="k">class</span> <span class="nc">Command</span><span class="p">(</span><span class="n">LabelCommand</span><span class="p">):</span>
    <span class="n">help</span> <span class="o">=</span> <span class="s">&quot;Generate HTML from restructured text files&quot;</span>
    <span class="n">args</span> <span class="o">=</span> <span class="s">&quot;&lt;inputfile1&gt; &lt;inputfile2&gt; ... | all&quot;</span>

    <span class="k">def</span> <span class="nf">handle_label</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Process input file(s)&quot;&quot;&quot;</span>

        <span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">settings</span><span class="p">,</span> <span class="s">&#39;PROJECT_PATH&#39;</span><span class="p">):</span>
            <span class="k">raise</span> <span class="n">CommandError</span><span class="p">(</span><span class="s">&quot;Please add a PROJECT_PATH setting&quot;</span><span class="p">)</span>

        <span class="bp">self</span><span class="o">.</span><span class="n">src_dir</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">settings</span><span class="o">.</span><span class="n">PROJECT_PATH</span><span class="p">,</span> <span class="s">&#39;fixed&#39;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">dst_dir</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">settings</span><span class="o">.</span><span class="n">PROJECT_PATH</span><span class="p">,</span> <span class="s">&#39;templates&#39;</span><span class="p">,</span> <span class="s">&#39;fixed&#39;</span><span class="p">)</span>

        <span class="k">if</span> <span class="n">filename</span> <span class="o">==</span> <span class="s">&#39;all&#39;</span><span class="p">:</span>
            <span class="n">files</span> <span class="o">=</span> <span class="n">glob</span><span class="o">.</span><span class="n">glob</span><span class="p">(</span><span class="s">&quot;</span><span class="si">%s%s</span><span class="s">*.rst&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">src_dir</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">sep</span><span class="p">))</span>
            <span class="n">files</span> <span class="o">=</span> <span class="p">[</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">basename</span><span class="p">(</span><span class="n">f</span><span class="p">)</span> <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">files</span><span class="p">]</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">files</span> <span class="o">=</span> <span class="p">[</span><span class="n">filename</span><span class="p">]</span>

        <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">files</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">process_page</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">process_page</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">filename</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Processes one fixed page&quot;&quot;&quot;</span>

        <span class="c"># retrieve source text</span>
        <span class="n">src_path</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">src_dir</span><span class="p">,</span> <span class="n">filename</span><span class="p">)</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">src_path</span><span class="p">,</span> <span class="s">&#39;r&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
                <span class="n">src_text</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
        <span class="k">except</span> <span class="ne">IOError</span><span class="p">,</span> <span class="n">ex</span><span class="p">:</span>
            <span class="k">raise</span> <span class="n">CommandError</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">ex</span><span class="p">))</span>

        <span class="c"># transform text</span>
        <span class="n">content</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">transform_input</span><span class="p">(</span><span class="n">src_text</span><span class="p">)</span>

        <span class="c"># write output</span>
        <span class="n">basename</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">splitext</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">basename</span><span class="p">(</span><span class="n">filename</span><span class="p">))[</span><span class="mi">0</span><span class="p">]</span>
        <span class="n">dst_path</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dst_dir</span><span class="p">,</span> <span class="s">&#39;</span><span class="si">%s</span><span class="s">.html&#39;</span> <span class="o">%</span> <span class="n">basename</span><span class="p">)</span>

        <span class="k">try</span><span class="p">:</span>
            <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">dst_path</span><span class="p">,</span> <span class="s">&#39;w&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
                <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">content</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s">&#39;utf-8&#39;</span><span class="p">))</span>
        <span class="k">except</span> <span class="ne">IOError</span><span class="p">,</span> <span class="n">ex</span><span class="p">:</span>
            <span class="k">raise</span> <span class="n">CommandError</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">ex</span><span class="p">))</span>

        <span class="n">prefix</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">commonprefix</span><span class="p">([</span><span class="n">src_path</span><span class="p">,</span> <span class="n">dst_path</span><span class="p">])</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;</span><span class="si">%s</span><span class="s"> -&gt; </span><span class="si">%s</span><span class="se">\n</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">dst_path</span><span class="p">[</span><span class="nb">len</span><span class="p">(</span><span class="n">prefix</span><span class="p">):]))</span>

    <span class="k">def</span> <span class="nf">transform_input</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">src_text</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Transforms input restructured text to HTML&quot;&quot;&quot;</span>

        <span class="k">return</span> <span class="n">docutils</span><span class="o">.</span><span class="n">core</span><span class="o">.</span><span class="n">publish_parts</span><span class="p">(</span><span class="n">src_text</span><span class="p">,</span> <span class="n">writer_name</span><span class="o">=</span><span class="s">&#39;html&#39;</span><span class="p">,</span>
                <span class="n">settings_overrides</span><span class="o">=</span><span class="p">{</span>
                    <span class="s">&#39;doctitle_xform&#39;</span><span class="p">:</span> <span class="bp">False</span><span class="p">,</span>
                    <span class="s">&#39;initial_header_level&#39;</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span>
                    <span class="p">})[</span><span class="s">&#39;html_body&#39;</span><span class="p">]</span>
</pre></div>
<p>Next I would need a template that could render these fragments. I remembered
that the Django <a class="reference external" href="https://docs.djangoproject.com/en/1.4/ref/templates/builtins/#include">include tag</a> could take a variable as an argument. Thus I
could create a single template that could render all of these &quot;fixed&quot; pages.
Here is the template <tt class="docutils literal">templates/fixed/base.html</tt>:</p>
<pre class="literal-block">
{% extends 'base.html' %}
{% block title %}{{ title }}{% endblock %}
{% block content %}
{% include content_template %}
{% endblock %}
</pre>
<p>I just need to pass in <tt class="docutils literal">title</tt> and <tt class="docutils literal">content_template</tt> context variables. The
latter will control which HTML fragment I include.</p>
<p>I then turned to the view function which would render this template. I wanted to
make this as generic and easy to do as possible. Since I was abandoning
flatpages, I would need to wire these up in my <tt class="docutils literal">urls.py</tt>. At first I didn't
think I could use Django's new <a class="reference external" href="https://docs.djangoproject.com/en/1.4/topics/class-based-views/">class-based generic views</a> for this, but after
some fiddling around, I came up with a very nice solution:</p>
<div class="highlight"><pre><span class="kn">from</span> <span class="nn">django.views.generic</span> <span class="kn">import</span> <span class="n">TemplateView</span>

<span class="k">class</span> <span class="nc">FixedView</span><span class="p">(</span><span class="n">TemplateView</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    For displaying our &quot;fixed&quot; views generated with the custom command</span>
<span class="sd">    make_fixed_page.</span>

<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">template_name</span> <span class="o">=</span> <span class="s">&#39;fixed/base.html&#39;</span>
    <span class="n">title</span> <span class="o">=</span> <span class="s">&#39;&#39;</span>
    <span class="n">content_template</span> <span class="o">=</span> <span class="s">&#39;&#39;</span>

    <span class="k">def</span> <span class="nf">get_context_data</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
        <span class="n">context</span> <span class="o">=</span> <span class="nb">super</span><span class="p">(</span><span class="n">FixedView</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">get_context_data</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
        <span class="n">context</span><span class="p">[</span><span class="s">&#39;title&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">title</span>
        <span class="n">context</span><span class="p">[</span><span class="s">&#39;content_template&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">content_template</span>
        <span class="k">return</span> <span class="n">context</span>
</pre></div>
<p>This allowed me to do the following in my <tt class="docutils literal">urls.py</tt> file:</p>
<div class="highlight"><pre><span class="n">urlpatterns</span> <span class="o">=</span> <span class="n">patterns</span><span class="p">(</span><span class="s">&#39;&#39;</span><span class="p">,</span>
   <span class="c"># ...</span>

   <span class="n">url</span><span class="p">(</span><span class="s">r&#39;^about/$&#39;</span><span class="p">,</span>
       <span class="n">FixedView</span><span class="o">.</span><span class="n">as_view</span><span class="p">(</span><span class="n">title</span><span class="o">=</span><span class="s">&#39;About&#39;</span><span class="p">,</span> <span class="n">content_template</span><span class="o">=</span><span class="s">&#39;fixed/about.html&#39;</span><span class="p">),</span>
       <span class="n">name</span><span class="o">=</span><span class="s">&#39;about&#39;</span><span class="p">),</span>
   <span class="n">url</span><span class="p">(</span><span class="s">r&#39;^colophon/$&#39;</span><span class="p">,</span>
       <span class="n">FixedView</span><span class="o">.</span><span class="n">as_view</span><span class="p">(</span><span class="n">title</span><span class="o">=</span><span class="s">&#39;Colophon&#39;</span><span class="p">,</span> <span class="n">content_template</span><span class="o">=</span><span class="s">&#39;fixed/colophon.html&#39;</span><span class="p">),</span>
       <span class="n">name</span><span class="o">=</span><span class="s">&#39;colophon&#39;</span><span class="p">),</span>

   <span class="c"># ...</span>
</pre></div>
<p>Now I have a way to efficiently serve reStructuredText files as &quot;fixed pages&quot;
that I can put under source code control.</p>
</div>
]]></content:encoded>
    </item>
    <item>
      <title>Upgrading to Django 1.4</title>
      <link>http://deathofagremmie.com/2012/04/15/upgrading-to-django-1.4</link>
      <pubDate>Sun, 15 Apr 2012 14:50:00 CDT</pubDate>
      <category><![CDATA[Django]]></category>
      <guid isPermaLink="true">http://deathofagremmie.com/2012/04/15/upgrading-to-django-1.4</guid>
      <description>Upgrading to Django 1.4</description>
      <content:encoded><![CDATA[<div class="document">
<p><a class="reference external" href="https://www.djangoproject.com/weblog/2012/mar/23/14/">Django 1.4</a> came out recently, and I took a few hours to upgrade my first site
yesterday. I thought it would be useful for my own reference to write down what
I did. I hope it will be useful to others. I'd love to read what you had to do,
so if you went through this process and blogged about it, please leave a
comment. Please keep in mind these aren't hard and fast steps or a recipe to
follow, as my sites are probably nothing like yours and may use different
features of Django.</p>
<div class="section" id="preparation">
<h3>Preparation</h3>
<p>The first thing I did was to read very carefully the <a class="reference external" href="https://docs.djangoproject.com/en/1.4/releases/1.4/">Django 1.4 release
notes</a>. The Django team does a great job of documenting what has changed, so it
is well worth your time to read the release notes. It is also a good idea to at
least skim the <a class="reference external" href="https://docs.djangoproject.com/en/1.4/internals/deprecation/">Django Deprecation Timeline</a>. After reading these, you should
make a list of the things you want to change, add, or remove.</p>
</div>
<div class="section" id="tips">
<h3>Tips</h3>
<p>After deciding what areas you want or need to change in your code, these tips
may be useful to help you implement the changes.</p>
<ol class="arabic simple">
<li><strong>Run with warnings turned on</strong>. Use this command to run the development
server: <tt class="docutils literal">$ python <span class="pre">-Wall</span> manage.py runserver</tt>. Django makes use of <a class="reference external" href="http://docs.python.org/library/warnings.html">Python's
warning system</a> to flag features that are deprecated. By running Python with
the <tt class="docutils literal"><span class="pre">-Wall</span></tt> switch, you'll see these warnings in the development server
output.</li>
<li><strong>Use the debugger to track down warnings</strong>. Not sure where a pesky warning
is coming from? Just open the Django source code in your editor and put a
<tt class="docutils literal">import pdb; pdb.set_trace()</tt> line right above or below the warning. You
can then use the debugger's <tt class="docutils literal">w</tt> command to get a stack trace and find out
exactly what code is leading to the warning. In my case I kept getting a few
warnings with no idea where they were coming from. I used this technique to
verify the warnings were coming from third party code and not my own. For
more information on using the debugger (and you really <strong>should</strong> know how to
use this invaluable tool), see the <a class="reference external" href="http://docs.python.org/library/pdb.html">Pdb documentation</a>.</li>
</ol>
</div>
<div class="section" id="my-upgrade-experience">
<h3>My upgrade experience</h3>
<p>Here is a list of things that I did during my port. Again, you may not need to
do these, and the next site I upgrade may have a different list. All of these
changes (except for the first) are described in the <a class="reference external" href="https://docs.djangoproject.com/en/1.4/releases/1.4/">Django 1.4 release notes</a>.</p>
<ol class="arabic simple">
<li><strong>Upgrade my Django debug toolbar</strong>. As of this writing, the Django debug
toolbar I got from PyPI was not compatible with Django 1.4. I simply
uninstalled it and grabbed the development version from GitHub with
<tt class="docutils literal">pip install <span class="pre">git+https://github.com/django-debug-toolbar/django-debug-toolbar.git</span></tt>.</li>
<li><strong>Remove the ADMIN_MEDIA_PREFIX setting</strong>. The admin application in
Django 1.4 now relies on the <tt class="docutils literal">staticfiles</tt> application (introduced in
Django 1.3) to handle the serving of static assets.</li>
<li><strong>Remove use of the {% admin_media_prefix %} template tag</strong>. Related to the
above, this tag is now deprecated. I had a custom admin view that used this
template tag, and I simply replaced it with <tt class="docutils literal">{{ STATIC_URL <span class="pre">}}/admin</span></tt>.</li>
<li><strong>Remove verify_exists on URLFields</strong>. The <tt class="docutils literal">verify_exists</tt> option to
the <tt class="docutils literal">URLField</tt> has been removed for performance and security reasons. I had
always set this to <tt class="docutils literal">False</tt>; now I just had to remove it altogether.</li>
<li><strong>Add the require_debug_false filter to logging settings</strong>. As explained in
the release notes, this change prevents admin error emails from being sent
while in <tt class="docutils literal">DEBUG</tt> mode.</li>
<li><strong>django.conf.urls.defaults is deprecated</strong>. I changed my imports in all
<tt class="docutils literal">urls.py</tt> files to use <tt class="docutils literal">django.conf.urls</tt> instead of
<tt class="docutils literal">django.conf.urls.defaults</tt> to access <tt class="docutils literal">include()</tt>, <tt class="docutils literal">patterns()</tt>, and
<tt class="docutils literal">url()</tt>. The Django team had recently moved these functions and updated the
docs and tutorial to stop using the frowned upon <tt class="docutils literal">from
django.conf.urls.defaults import *</tt>.</li>
<li><strong>Enable the new clickjacking protection</strong>. A nice new feature is some new
middleware that adds the <tt class="docutils literal"><span class="pre">X-Frame-Options</span></tt> header to all response headers.
This provides <a class="reference external" href="http://en.wikipedia.org/wiki/Clickjacking">clickjacking</a> protection in modern browsers.</li>
<li><strong>Add an admin password reset feature</strong>. By adding a few new lines to your
<tt class="docutils literal">urlconf</tt> you get a nifty new password reset feature for your admin.</li>
<li><strong>Update to the new manage.py</strong>. This was the biggest change with the most
impact. The Django team has finally removed a long standing wart with its
<tt class="docutils literal">manage.py</tt> utility. Previously, <tt class="docutils literal">manage.py</tt> used to play games with your
<tt class="docutils literal">PYTHONPATH</tt> which led to confusion when migrating to production. It could
also lead to having your settings imported twice. See the next section in
this blog entry for more on what I did here.</li>
</ol>
</div>
<div class="section" id="reorganizing-for-the-new-manage-py">
<h3>Reorganizing for the new manage.py</h3>
<p>The change with the largest impact for me was reorganizing my directory
structure for the new <tt class="docutils literal">manage.py</tt> command. Before this change, I had organized
my directory structure like this:</p>
<pre class="literal-block">
mysite/
   media/
   static/
   mysite/
      myapp1/
         __init__.py
         models.py
         views.py
         urls.py
      myapp2/
         __init__.py
         models.py
         views.py
         urls.py
      settings/
         __init__.py
         base.py
         local.py
         production.py
         test.py
      apache/
         myproject.wsgi
      logs/
      templates/
      manage.py
      urls.py
   LICENSE
   fabfile.py
   requirements.txt
</pre>
<p>After replacing the contents of my old <tt class="docutils literal">manage.py</tt> with the new content, I
then reorganized my directory structure to this:</p>
<pre class="literal-block">
mysite/
   media/
   static/
   myapp1/
      __init__.py
      models.py
      views.py
      urls.py
   myapp2/
      __init__.py
      models.py
      views.py
      urls.py
   myproject/
      settings/
         __init__.py
         base.py
         local.py
         production.py
         test.py
      apache/
         myproject.wsgi
      logs/
      templates/
      urls.py
   LICENSE
   fabfile.py
   manage.py
   requirements.txt
</pre>
<p>It is a subtle change, but I like it. It now makes it clear that my project is
just an application itself, consisting of the top-level <tt class="docutils literal">urls.py</tt>, settings,
templates and logs. The <tt class="docutils literal">manage.py</tt> file is now at the top level directory
also, which seems right.</p>
<p>I had always made my imports as <tt class="docutils literal">from app.models import MyModel</tt> instead of
<tt class="docutils literal">from myproject.app.models</tt>, so I didn't have to update any imports.</p>
<p>Since I use the &quot;settings as a package&quot; scheme, I did have to update the imports
in my settings files. For example, in my <tt class="docutils literal">local.py</tt> I had to change <tt class="docutils literal">from
settings.base import *</tt> to <tt class="docutils literal">myproject.settings.base import *</tt>.</p>
</div>
<div class="section" id="what-i-didn-t-do">
<h3>What I didn't do</h3>
<p>Django 1.4's largest new feature is probably its support for timezones. I
decided for this project not to take advantage of that. It would require a lot
of changes, and it isn't really worth it for this small site. I may use it on
the next site I convert to Django 1.4, and I will definitely be using it on new
projects.</p>
</div>
<div class="section" id="conclusion">
<h3>Conclusion</h3>
<p>The upgrade process went smoother and quicker than I thought thanks to the
excellent release notes and the Django team's use of Python warnings to flag
deprecated features.</p>
</div>
</div>
]]></content:encoded>
    </item>
    <item>
      <title>Django Uploads and UnicodeEncodeError</title>
      <link>http://deathofagremmie.com/2011/06/04/django-uploads-and-unicodeencodeerror</link>
      <pubDate>Sat, 04 Jun 2011 20:00:00 CDT</pubDate>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Linux]]></category>
      <category><![CDATA[Unicode]]></category>
      <category><![CDATA[Django]]></category>
      <guid isPermaLink="true">http://deathofagremmie.com/2011/06/04/django-uploads-and-unicodeencodeerror</guid>
      <description>Django Uploads and UnicodeEncodeError</description>
      <content:encoded><![CDATA[<div class="document">
<p>Something strange happened that I wish to document in case it helps others.  I
had to reboot my Ubuntu server while troubleshooting a disk problem. After the
reboot, I began receiving internal server errors whenever someone tried to view
a certain forum thread on my <a class="reference external" href="http://djangoproject.com">Django</a> powered website. After some detective work,
I determined it was because a user that had posted in the thread had an avatar
image whose filename contained non-ASCII characters. The image file had been
there for months, and I still cannot explain why it just suddenly started
happening.</p>
<p>The traceback I was getting ended with something like this:</p>
<div class="highlight"><pre><span class="n">File</span> <span class="s">&quot;/django/core/files/storage.py&quot;</span><span class="p">,</span> <span class="n">line</span> <span class="mi">159</span><span class="p">,</span> <span class="ow">in</span> <span class="n">_open</span>
<span class="k">return</span> <span class="n">File</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">path</span><span class="p">(</span><span class="n">name</span><span class="p">),</span> <span class="n">mode</span><span class="p">))</span>

<span class="ne">UnicodeEncodeError</span><span class="p">:</span> <span class="s">&#39;ascii&#39;</span> <span class="n">codec</span> <span class="n">can</span><span class="s">&#39;t encode characters in position 72-79: ordinal not in range(128)</span>
</pre></div>
<p>So it appeared that the <tt class="docutils literal">open()</tt> call was triggering the error. This led me on
a twisty Google search which had many dead ends. Eventually I found a suitable
explanation. Apparently, Linux filesystems don't enforce a particular Unicode
encoding for filenames. Linux applications must decide how to interpret
filenames all on their own. The Python OS library (on Linux) uses environment
variables to determine what locale you are in, and this chooses the encoding for
filenames.  If these environment variables are not set, Python falls back to
ASCII (by default), and hence the source of my <tt class="docutils literal">UnicodeEncodeError</tt>.</p>
<p>So how do you tell a Python instance that is running under Apache / <tt class="docutils literal">mod_wsgi</tt>
about these environment variables? It turns out the answer is in the <a class="reference external" href="https://docs.djangoproject.com/en/1.3/howto/deployment/modpython/#if-you-get-a-unicodeencodeerror">Django
documentation</a>, albeit in the <tt class="docutils literal">mod_python</tt> integration section.</p>
<p>So, to fix the issue, I added the following lines to my <tt class="docutils literal">/etc/apache2/envvars</tt>
file:</p>
<div class="highlight"><pre><span class="nb">export </span><span class="nv">LANG</span><span class="o">=</span><span class="s1">&#39;en_US.UTF-8&#39;</span>
<span class="nb">export </span><span class="nv">LC_ALL</span><span class="o">=</span><span class="s1">&#39;en_US.UTF-8&#39;</span>
</pre></div>
<p>Note that you must cold stop and re-start Apache for these changes to take
effect. I got tripped up at first because I did an <tt class="docutils literal">apache2ctrl
graceful</tt>, and that was not sufficient to create a new environment.</p>
</div>
]]></content:encoded>
    </item>
  </channel>
</rss>

