<?xml version="1.0" encoding="utf-8" ?>
<feed xmlns="http://www.w3.org/2005/Atom"
      xmlns:dc="http://purl.org/dc/elements/1.1/"
      xml:base="http://reinout.vanrees.org/" xml:lang="en">
  <link rel="self"
        href="http://reinout.vanrees.org/weblog/pythonfeed.xml" />
  <link href="http://reinout.vanrees.org/weblog/"
        rel="alternate" type="text/html" />

  <div xmlns="http://www.w3.org/1999/xhtml">
    <a href="http://www.atomenabled.org/feedvalidator/check.cgi?url=http://reinout.vanrees.org/weblog/pythonfeed.xml">
      <img title="Validate my Atom feed" width="88"
           height="31"
           src="http://www.atomenabled.org/feedvalidator/images/valid-atom.png"
           alt="[Valid Atom]" border="0px" />
    </a>
    <p>
      <span>
        This is an Atom formatted XML site feed. It is intended to be viewed in
        a Newsreader or syndicated to another site. Please visit
      </span>
      <a href="http://www.atomenabled.org/">Atom Enabled</a>
      <span>
        for more info.
      </span>
    </p>
  </div>

  <title type="html">Reinout van Rees' weblog</title>
  <subtitle>Python, grok, books, history, faith, etc.</subtitle>
  <updated>2009-04-04T21:44:00+01:00</updated>
  <id>urn:syndication:a55644db8591c020bd38852775819a9a</id>

  
  <entry>
    <title>Upgrading your svn checkouts to 1.7 with checkoutmanager</title>
    <link rel="alternate" type="text/html"
          href="http://reinout.vanrees.org/./weblog/2012/02/09/upgrading-svn-with-checkoutmanager.html" />
      <id>http://reinout.vanrees.org/./weblog/2012/02/09/upgrading-svn-with-checkoutmanager.html</id>
      <author>
        <name>Reinout van Rees</name>
      </author>
      <published>2012-02-09T00:00:00+01:00</published>
      <updated>2012-02-09T11:24:00+01:00</updated>

      
      <category term="python" />
      

      <content type="xhtml"
               xml:base="http://reinout.vanrees.org/"
               xml:lang="en-US"
               xml:space="preserve">
        <div xmlns="http://www.w3.org/1999/xhtml">
          <div class="document">
<p>I updated subversion yesterday (because I installed git-svn). Subversion
version 1.7 has a new repository structure and requires you to upgrade all
your existing checkouts:</p>
<pre class="literal-block">
$&gt; svn up
svn: E155036: Please see the 'svn upgrade' command
svn: E155036: Working copy 'xyz' is too old (format 10, created by Subversion 1.6)
</pre>
<p>Calling <tt class="docutils literal">svn upgrade</tt> by hand for all checkouts is boring. And I made
<a class="reference external" href="http://pypi.python.org/pypi/checkoutmanager">checkoutmanager</a> to make
checkouts less boring. A simple <tt class="docutils literal">checkoutmanager up</tt> in the morning does an
<tt class="docutils literal">svn up</tt>, <tt class="docutils literal">git pull</tt> or <tt class="docutils literal">hg pull <span class="pre">-u</span></tt> in every one of my checkouts.</p>
<p>And <a class="reference external" href="http://maurits.vanrees.org/">my brother</a> luckily added a hidden command
<tt class="docutils literal">upgrade</tt> to checkoutmanager. It is called hidden because it is only listed
on the <a class="reference external" href="http://pypi.python.org/pypi/checkoutmanager">pypi page</a>, not when
you call <tt class="docutils literal">checkoutmanager <span class="pre">--help</span></tt>, because it is so rarely needed.</p>
<p>But anyway, a simple <tt class="docutils literal">checkoutmanager upgrade</tt> call later and all my svn
checkouts were upgraded! Nice.</p>
</div>

        </div>
      </content>

    </entry>
    
  <entry>
    <title>Apple lion reinstall experience and surprise</title>
    <link rel="alternate" type="text/html"
          href="http://reinout.vanrees.org/./weblog/2012/02/05/apple-lion-reinstall.html" />
      <id>http://reinout.vanrees.org/./weblog/2012/02/05/apple-lion-reinstall.html</id>
      <author>
        <name>Reinout van Rees</name>
      </author>
      <published>2012-02-05T00:00:00+01:00</published>
      <updated>2012-02-05T21:12:00+01:00</updated>

      
      <category term="python" />
      
      <category term="django" />
      
      <category term="apple" />
      

      <content type="xhtml"
               xml:base="http://reinout.vanrees.org/"
               xml:lang="en-US"
               xml:space="preserve">
        <div xmlns="http://www.w3.org/1999/xhtml">
          <div class="document">
<p>My year-old macbook installation was showing its age. Or rather, there were
some things wrong with it:</p>
<ul class="simple">
<li>The original OS was 10.6, snow leopard. I upgraded it to lion (10.7) half a
year ago. This was an in-place upgrade, not a fresh install. I wanted a
fresh install to clean some stuff up and because it started to feel slow. I
heard that a clean install would help a lot regarding speed.</li>
<li>I work a lot with geographic libraries, Django and geodjango. So originally
I installed everything via the <a class="reference external" href="http://www.kyngchaos.com/software/unixport">kyngchaos packages</a>. Mapnik, gdal, spatialite and
so on. But after the lion upgrade, I couldn't compile any python packages
with C extensions anymore as gcc 4.0 (which everything had been build with)
had been replaced by 4.2. And spatialite never would work right anyway. So I
wanted to replace this.</li>
<li>I used <a class="reference external" href="http://mxcl.github.com/homebrew/">homebrew</a> as a package manager
for the gnu/unix side of things instead of <a class="reference external" href="http://www.macports.org/">macports</a> I'd been using before. It works, but I missed
some things, like <a class="reference external" href="http://www.qgis.org/">Quantum GIS (QGIS)</a>, which is
included in macports. I hoped to get everything python+gis related done with
one package manager, in my case macports.</li>
</ul>
<p>So I made sure my backups were OK, that my code was all committed, that my
repositories were cleaned up, that all my dotfiles in my homedir were in
version control and so on. Most of it was already OK, but of course there were
some small things left. I'll do a write-up later on of my backup strategy and
how I handle my dotfiles and so.</p>
<p>Time for the <strong>actual lion reinstall</strong>. How does that work? I bought Lion from
the app store, so it was downloaded and installed by my mac: I didn't have an
install DVD. Turns out to be <strong>easy</strong>: just restart and <a class="reference external" href="http://support.apple.com/kb/HT4718">press command-r</a> during bootup and you'll get a &quot;lion
recovery&quot; menu. Choose the reinstall option and it will download the latest
full version and install it for you. Simple and works.</p>
<p>The big <strong>surprise</strong> came when the computer rebooted. I expected a dialog to
set up a main user. Instead, I got the regular login screen. Ok... Logging
in... Hey! All my stuff is still there! All the settings, all my documents,
all my music... No need to restore backups.</p>
<p>So: an OSX lion restore wipes <strong>only the OS</strong> and reinstalls it. Including
xcode, btw. The rest (your own data, applications, settings) is
retained. Actually pretty handy.</p>
<p>This <em>did</em> mean I had to clean up the kyngchaos packages and homebrew by
hand. Just a matter of deleting some directories, telling <a class="reference external" href="http://superuser.com/a/203740/90698">homebrew to erase
itself</a> and adjusting my paths.</p>
</div>

        </div>
      </content>

    </entry>
    
  <entry>
    <title>Website changes: sphinx code, layout, twitter bootstrap, less</title>
    <link rel="alternate" type="text/html"
          href="http://reinout.vanrees.org/./weblog/2012/01/22/website-changes.html" />
      <id>http://reinout.vanrees.org/./weblog/2012/01/22/website-changes.html</id>
      <author>
        <name>Reinout van Rees</name>
      </author>
      <published>2012-01-22T00:00:00+01:00</published>
      <updated>2012-01-22T22:49:00+01:00</updated>

      
      <category term="python" />
      
      <category term="django" />
      

      <content type="xhtml"
               xml:base="http://reinout.vanrees.org/"
               xml:lang="en-US"
               xml:space="preserve">
        <div xmlns="http://www.w3.org/1999/xhtml">
          <div class="document">
<p>I've made a couple of changes to my website (and thus weblog):</p>
<ul class="simple">
<li>I moved from svn to git.</li>
<li>I made my weblog-related sphinx customizations public.</li>
<li>I'm using <a class="reference external" href="http://twitter.github.com/bootstrap/">twitter bootstrap</a> as the
css framework instead of the yahoo one I've been using before.</li>
<li>I changed the layout. Bigger font, less clutter. More bare-bones. Most of
the looks (font type, headers) is from the bootstrap css, but the ordering
is mine. I especially like the bigger font.</li>
</ul>
<div class="section" id="svn-to-git">
<h1>Svn to git</h1>
<p>I'm getting used to git at the office. And my website was in svn. The svn is
on me and <a class="reference external" href="http://maurits.vanrees.org">my brother</a>'s server. And we're going
to re-build that server in the near future. And not having to set up svn there
saves quite some time.</p>
<p>So I moved part of the code to github and the actual content to a simple
directory in our own server. Git works just fine with a repository URL like
<tt class="docutils literal"><span class="pre">ssh://vanrees.org/~/git/websitecontent</span></tt>. Just init a repo in
<tt class="docutils literal">~/git/websitecontent</tt> on the server and off you go.</p>
</div>
<div class="section" id="sphinx-as-weblog-code-is-now-available-somewhat">
<h1>Sphinx as weblog: code is now available (somewhat)</h1>
<p>My site is static html now for two years or so. Generated with
<a class="reference external" href="Sphinx">http://sphinx.pocoo.org/</a>. No Plone (which it was when I worked
with Plone) and no Django (which I'd like, as I work with it, but my current
text-only setup works real fine and Sphinx is an essential Django
documentation ingredient, too).</p>
<p>I also make my weblog with Sphinx. I need a couple of custom restructuredtext
tags for that (like <tt class="docutils literal">..tags::</tt> for handling tags). I basically point a
script at a sphinx directory that contains my entries and it generates
<tt class="docutils literal">index.txt</tt> files for all the directories with a list of entries. And it
generates <tt class="docutils literal">tags/TAGNAME.txt</tt> files for the tags. Afterwards, I just run
Sphinx and everything gets generated OK.</p>
<p>I got some questions in the past about my code, but never followed up by
publishing my terribly Reinout-specific code. It <em>is</em> still Reinout-specific,
but <strong>I've published it now</strong>. It might provide some ideas. The full code is
at <a class="reference external" href="https://github.com/reinout/reinout.vanrees.org">https://github.com/reinout/reinout.vanrees.org</a> . Again: this is not
something you can <tt class="docutils literal">pip install</tt>. Best you can do is borrow and copy at the
moment. (Threat the Python code in there as public domain).</p>
<p>Most of interest are probably
<a class="reference external" href="https://github.com/reinout/reinout.vanrees.org/blob/master/rvo/rst.py">https://github.com/reinout/reinout.vanrees.org/blob/master/rvo/rst.py</a> which
provides the custom restructuredtext (and thus sphinx) tags. And
<a class="reference external" href="https://github.com/reinout/reinout.vanrees.org/blob/master/rvo/weblog.py">https://github.com/reinout/reinout.vanrees.org/blob/master/rvo/weblog.py</a> which
creates all the index and tags files.</p>
<p>It is not well-documented and quite specific to my case. But there are some
docstrings and the code is nicely PEP8 compliant :-) If you need any info,
feel free to contact me.</p>
</div>
<div class="section" id="twitter-bootstrap-css">
<h1>Twitter bootstrap css</h1>
<p>I have to re-visit the layout of the websites we make at my work (<a class="reference external" href="http://www.nelen-schuurmans.nl">Nelen &amp;
Schuurmans</a>). One of the things we want is
to have a more attractive layout. And after some browsing, <a class="reference external" href="http://twitter.github.com/bootstrap/">twitter bootstrap</a> struck me as a good basis.</p>
<p>And, as I do often, I first experiment on myself. So I set out to change the
layout of my own website by using twitter bootstrap. I'm not even using half
of bootstrap's possibilities, but I'm quite happy with the result. The basic
typography is fine. There are some handy helpers for common things like labels
(which I used to liven up the tags below the weblog headers on my weblog). And
I quite like the simple header at the top of the page: just a simple bar.</p>
<p>And there's another good thing about twitter bootstrap: less. See below.</p>
</div>
<div class="section" id="less">
<h1>Less</h1>
<p>What coffeescript is for javascript, <a class="reference external" href="http://lesscss.org/">less</a> is for
css. A simpler syntax that helps you write better and <em>less duplicated</em> css.</p>
<p>I like it! Take for example the headings of this entry. Hover over one and
you'll see a paragraph token at the end. Sphinx adds this so you can link to
individual sections in a bigger file. Sphinx also has some css that hides the
paragraph token normally and only shows it when you hover over the heading:</p>
<pre class="literal-block">
a.headerlink {
    visibility: hidden;
}

h1:hover &gt; a.headerlink,
h2:hover &gt; a.headerlink,
h3:hover &gt; a.headerlink,
h4:hover &gt; a.headerlink,
h5:hover &gt; a.headerlink,
h6:hover &gt; a.headerlink,
dt:hover &gt; a.headerlink {
    visibility: visible;
}
</pre>
<p>I restricted that to:</p>
<pre class="literal-block">
.headerlink {
  visibility: hidden;
  }

h1, h2, h3, h4, h5, h6, dt {
  &amp;:hover {
    .headerlink {
      visibility: visible;
      }
    }
  }
</pre>
<p>It looks just like css, as you see in that first <tt class="docutils literal">.headerlink</tt> rule. The
second one has the special less stuff. The ampersand means an extra condition,
so the <tt class="docutils literal">&amp;:hover</tt> effectively adds <tt class="docutils literal">:hover</tt> to each of the
<tt class="docutils literal">h1</tt>..``dt``. This really shines if you have a couple of other extra
conditions on the same set of elements.</p>
<p>Anyway, head over to <a class="reference external" href="http://lesscss.org/">http://lesscss.org/</a> where they have a better explanation.</p>
</div>
<div class="section" id="closing-off">
<h1>Closing off</h1>
<p>I'm happy with the change. One extra change that I didn't mention yet: I've
removed deliverance from the mix. Deliverance is a tool that I used to change
the layout of a couple of inputs (sphinx, docbook2html, latex2html) into my
vanrees.org layout. It did that on the fly. But the versions kept changing and
the versions I had were getting old and hard to update. And I had to run a
wsgi process to run it, even though the actual website was all plain html.</p>
<p>I'm back to plain html now. I've implemented the layout in a Sphinx
template. Simple to do, as it is just jinja2, which has the same syntax as
Django. And the docbook and latex html exports are just that. I'll leave them
that way. It isn't that important to have my logo on those pages :-)</p>
<p>One extra advantage: the site ought to be faster!</p>
</div>
</div>

        </div>
      </content>

    </entry>
    
  <entry>
    <title>Back</title>
    <link rel="alternate" type="text/html"
          href="http://reinout.vanrees.org/./weblog/2012/01/18/back.html" />
      <id>http://reinout.vanrees.org/./weblog/2012/01/18/back.html</id>
      <author>
        <name>Reinout van Rees</name>
      </author>
      <published>2012-01-18T00:00:00+01:00</published>
      <updated>2012-01-18T13:48:00+01:00</updated>

      
      <category term="django" />
      
      <category term="book" />
      
      <category term="nelenschuurmans" />
      

      <content type="xhtml"
               xml:base="http://reinout.vanrees.org/"
               xml:lang="en-US"
               xml:space="preserve">
        <div xmlns="http://www.w3.org/1999/xhtml">
          <div class="document">
<p>Despite my back, I'm back.</p>
<div class="section" id="ouch-my-back-ouch">
<h1>Ouch, my back, ouch</h1>
<p>Since the summer my right leg is acting up. We moved to a new house and I
probably did too much hard work. My right leg muscles started contracting the
whole time, making me limp a bit, giving me muscle pain. Sometimes it felt
like my leg was partially on fire.</p>
<p>I went to the doctor and she told me it was probably a lower back problem. A
lower back problem can squeeze out another muscle or nerve by constricting it
or limiting oxygen supply or so. The problem then radiates from the lower back
into other body parts: for instance, a leg. Of course, limping a bit on that
leg isn't too good for your posture, potentially leading to other back
problems. The verdict: nothing major, just irritating. She suggested me to go
visit a physiotherapist.</p>
<p>Four days later I bend over the wrong way while standing in the bath. It took
me five minutes to crawl out of the bath: I severely wrecked my back
muscles. I had to lie down in bed or on the sofa for four days. On my left
hand side. Sitting or lying or standing or walking were <strong>painful</strong>. Going to
the toilet was a major undertaking.</p>
<p>After three days I started taking stronger-than-aspirine painkillers
(ibuproven), which helped getting the pain a bit under control and allowed me
to move again. Moving sore muscles is necessary for getting them back in order again.</p>
<p>At the end of the week I managed to sit down (yes! accomplishment!) at my
parents' 40 year wedding anniversery dinner.</p>
</div>
<div class="section" id="back-at-work">
<h1>Back at work</h1>
<p>I stayed home for more than two weeks. First I couldn't move or sit. Later I
could actually sit down on the couch, but not in a regular office chair. And
soaking your muscles in a nice hot bath halfway the day, that's not something
I'm going to attempt at the office :-)</p>
<p>Luckily I'm back at work again. The going is slow, as I tire at the end of the
day, even when I take regular walks through the office instead of sitting. So
I go home earlier.</p>
<p>And I come into the office later, as the internal body repair functions
apparently take a lot of energy, so I need to sleep more. And I still prefer
to soak in a hot bath in the morning to get my muscles going.</p>
</div>
<div class="section" id="back-at-my-book">
<h1>Back at my book</h1>
<p>One thing that really suffered during those weeks was my Django book. I wanted
to finish three chapters by the end of the month, but that schedule was
obviously shot. I'm still occasionally tired (and most book work is in the
evening), but I've gotten back on track.</p>
<p>Good news: today and tomorrow I've taken a day off to work full-time on my
book. Well, full-time <em>apart from this evening</em> as there's a <a class="reference external" href="http://wiki.python.org/moin/DjangoMeetingNL/DM/ABC120118">Django meeting
in Amsterdam tonight</a> which I'll
attend.</p>
</div>
<div class="section" id="back-at-the-physiotherapist">
<h1>Back at the physiotherapist</h1>
<p>I went to the physiotherapist a couple of years ago. And I'm back. With my
back. The lower back this time: the last time it was more in my shoulder
area.</p>
<p>He helps, as I can do much more than a few weeks ago. I still limp and walking
is a chore, but I can at least move about again.</p>
</div>
<div class="section" id="back-to-the-middle-ages">
<h1>Back to the middle ages</h1>
<p>Back to the medieval times of torture... Ouch, it hurts to have a
physiotherapist massage a leg muscle that's been rock solid hard for a couple
of months... But it helped!</p>
</div>
<div class="section" id="back-to-django-blogging">
<h1>Back to (Django) blogging</h1>
<p>I haven't blogged in about a month; no wonder, seeing the above. I'm starting
again. That Django meeting in Amsterdam tonight? Great time to make summaries
again; the program looks great.</p>
<p>Last year was <strong>a good blogging year</strong>. 165 entries in one year: my second
best year. I somehow managed 182 in 2004. I like statistics, so I have two
<a class="reference external" href="http://reinout.vanrees.org/weblog/statistics.html">graphs with statistics on my weblog</a>.</p>
<p>Well, I'm back to writing my book now. Bye!</p>
</div>
</div>

        </div>
      </content>

    </entry>
    
  <entry>
    <title>Building secure Django websites - Erik Romijn</title>
    <link rel="alternate" type="text/html"
          href="http://reinout.vanrees.org/./weblog/2012/01/18/secure-django-websites.html" />
      <id>http://reinout.vanrees.org/./weblog/2012/01/18/secure-django-websites.html</id>
      <author>
        <name>Reinout van Rees</name>
      </author>
      <published>2012-01-18T00:00:00+01:00</published>
      <updated>2012-01-19T17:40:00+01:00</updated>

      
      <category term="django" />
      
      <category term="pun" />
      

      <content type="xhtml"
               xml:base="http://reinout.vanrees.org/"
               xml:lang="en-US"
               xml:space="preserve">
        <div xmlns="http://www.w3.org/1999/xhtml">
          <div class="document">
<p>(Talk at the <a class="reference external" href="http://wiki.python.org/moin/DjangoMeetingNL/DM/ABC120118">2012-01-18 Dutch Django meeting</a>)</p>
<p>Security is about three things:</p>
<ul class="simple">
<li>Integrity of your data. I should not be able to change it.</li>
<li>Confidentiality: can I access what I should not be able to access?</li>
<li>Availability: can I break your website?</li>
</ul>
<p>A well-known bad case is DigiNotar. Malware on most of their computers,
including the most secure once. Their digital certificates were compromised
and the company went bankrupt in three weeks time.</p>
<p>One thing that we have to take care of regarding Django: cookies. Cookies are
stored in your browser and are linked to a website. All requests to that
website get the cookies in every request. In Django, your <strong>session ID</strong> is
stored in your cookie. If you get hold of the session ID, you get hold of the
user's session. Django stores the actual session's data in the database, so
the actual data is safe.</p>
<p>In Django 1.4 there are cookie-based sessions, but they're a bad idea: never
use them. He doesn't know why they even build it in. <strong>UPDATE: they're not
that bad, see the comments.</strong></p>
<p>CSRF: cross site request forging. Tricking the browser into posting requests
to other websites. <a class="reference external" href="http://your-router/set_password?pwd=hamster">http://your-router/set_password?pwd=hamster</a> . Django
protects you by adding a secred csrf_token to every POST form and checking for
it. So you're safe.</p>
<p>XSS injection. Cross site scripting. Happens when you don't filter/escape user
submitted content. So you could send a <tt class="docutils literal">&lt;script&gt;</tt> tag with a script that for
instance steals every cookie on your server for stealing session IDs. Common
is tricking a single user into running the script. A more
powerful, but rarer, way is to get a script on some website and trick everyone
visiting the site...</p>
<p>Django is mostly safe as it escapes template tag output by default. There is a
rare vulnerability if you don't put double quotes around html
attributes. Everything after a space in var in <tt class="docutils literal">&lt;p <span class="pre">class={{</span> var }}&gt;</tt> ends up
as a separate attibute...</p>
<p>Cookie security is pretty good in Django. 1.4 sets <tt class="docutils literal">SESSION_COOKIE_HTTPONLY</tt> to
true. You ought to do this always. And if you always use https, set
<tt class="docutils literal">CSRF_COOKIE_SECURE</tt> and <tt class="docutils literal">SESSION_COOKIE_SECURE</tt> to true.</p>
<p>And... don't trust in a regex that filters dirty tags out of your
user-submitted code. There are SO many tricks and ways to circumvent any
regex. Use markdown or something like that.</p>
<p>SQL injection is common, but Django has no know exploits. It is rock
solid. But there are other ways. For instance LDAP injection. Don't put an
unfiltered username into your LDAP query as you can hack the query. Or direct
user input into filenames. And what about shell injection?
<tt class="docutils literal">some_filename.txt;rm <span class="pre">-rf</span></tt>... Shell calls are always very risky, but
Python's <tt class="docutils literal">subprocess()</tt> helps a lot.</p>
<p>There's a difference between validation and escaping. Validation is done as
early as possible. Escaping is done as late as possible. Both serve a
different purpose. As always: whitelisting is better than blacklisting.</p>
<p>A new option is clickjacking that overlays a transparent website over another
one, stealing your form fields and clicks. It works with iframes. Django 1.4
has a new <tt class="docutils literal"><span class="pre">X_FRAME_OPTIONS='DENY'</span></tt> that works with newer browsers.</p>
<p>And... Don't trust browsers. If you disable something in javascript, a user
can work around it, for instance. The speaker could always book rooms in
school before anyone else could as the only-two-weeks-in-advance limitation
was implemented in javascript, not in the backend...</p>
<p>Regarding tests: check login-protected pages as anonymous first. Check actions
for the admin user first as anonymous, then as a regular user. Check it.</p>
<p>And if you run some test site that's (temporarily) on an external IP address,
you can be sure someone finds it. So watch out.</p>
<p>If you run backups, do you also run restores? Do you keep backups with a
different provider? Once a provider was hacked and its servers were
wiped. Including their backups. All customer data lost.</p>
<p>Django: don't ever run it in DEBUG mode in production. It gives away way too
much information. Another tip: name the admin url something different than
<tt class="docutils literal">/admin</tt>. it is a dead give-away that it is a Django website.</p>
<p>Watch out for other apps on the same server. Your Django server <em>can</em> be
compromised by running some faulty-configured PHP code on the same server.</p>
<p>Always restrict database access per app.</p>
<p><strong>Summary</strong>. Django helps out with CSRF, SQL injection and XSS; you need to
take care of all other injection attacs (LDAP, filesystem, etc). Use the
build-in Django security features. And never trust what the browser sends. And
secure the web server itself as well. Make backups.</p>
</div>

        </div>
      </content>

    </entry>
    
  <entry>
    <title>Dutch Django meeting - lightning talks</title>
    <link rel="alternate" type="text/html"
          href="http://reinout.vanrees.org/./weblog/2012/01/18/pun-lightning-talks.html" />
      <id>http://reinout.vanrees.org/./weblog/2012/01/18/pun-lightning-talks.html</id>
      <author>
        <name>Reinout van Rees</name>
      </author>
      <published>2012-01-18T00:00:00+01:00</published>
      <updated>2012-01-18T21:17:00+01:00</updated>

      
      <category term="django" />
      
      <category term="pun" />
      

      <content type="xhtml"
               xml:base="http://reinout.vanrees.org/"
               xml:lang="en-US"
               xml:space="preserve">
        <div xmlns="http://www.w3.org/1999/xhtml">
          <div class="document">
<p>(Short 5 minute talks at the <a class="reference external" href="http://wiki.python.org/moin/DjangoMeetingNL/DM/ABC120118">2012-01-18 Dutch Django meeting</a>)</p>
<div class="section" id="coffeescript-django-roald-de-vries">
<h1>Coffeescript &amp; Django - Roald de Vries</h1>
<p><a class="reference external" href="http://coffeescript.org/">Coffeescript</a> is not really a language, but it is
syntactic sugar for javascript. A nicer syntax. It compiles to javascript. It
uses indentation (like Python) to indicate code blocks instead of using curly
braces, for instance. And the way to declare functions is easier and less
verbose.</p>
<p>Coffeescript also allows classes, including constructors, and inheritance.</p>
<p>Nice: on the coffeescript site you can type in some code and get it
transformed in to javascript. Handy for trying it out.</p>
<p>The language isn't difficult. You can learn it within the hour (he said 'a bit
more than 5 minutes'). You can compile it into javascript on the server with
node.js. You can also include the coffeescript.js script in your page and let
the browser handle the compiling automatically (at a performance penalty, but
it is easier for development).</p>
<p>Django-coffeescript integrates the compiling into Django. And you can even put
inline coffeescript in your template. But normally you'll just point at
external files.</p>
<p>Bonus tip: django-less. <a class="reference external" href="http://lesscss.org/">Less</a> is css + variables +
nesting + inheritance. Integrated in the same way as django-coffeescript.</p>
<p>One drawback of coffeescript: it makes debugging harder as you have to debug
the javascript that comes out of the compiler instead of the coffeescript code
you just wrote.</p>
</div>
<div class="section" id="django-fluent-dashboard-diederik-van-der-boor">
<h1>Django-fluent-dashboard - Diederik van der Boor</h1>
<p>&quot;<a class="reference external" href="http://django-fluent-dashboard.readthedocs.org/en/latest/index.html">Django-fluent-dashboard</a> - a
fresh dashboard for your admin interface&quot; was the title.</p>
<p>Django is a bit technical. His thought: how to make the Django admin more
usable as a CMS that's friendly? Another core thing in his thinkwork was the
idea of reusable apps.</p>
<p>If you look at the current admin, you directly see the huge number of
apps. Not nice.</p>
<p>Somebody made <a class="reference external" href="http://django-admin-tools.readthedocs.org/en/latest/index.html">Django admin tools</a>. Nice. A
good solution. It gives the admin a nicer layout and even a menu bar that
helps you find things.</p>
<p><strong>The core idea</strong>: django-fluent-dashboard only modifies the first page of the admin: instead of
the big list of apps you get friendly, grouped, icons.</p>
<p>He made a modification (or plugin, or newer version, I don't know) that looks
even nicer. More dashboard-based. See the example on the <a class="reference external" href="http://django-fluent-dashboard.readthedocs.org/en/latest/index.html">documentation site</a>.</p>
<p>In the end, he hopes to turn it into a full CMS. There's already a
django-fluent-contents and django-fluent-pages on github. But they're separate
projects. django-fluent-dashboard works just fine with Django Fiber, for
instance.</p>
</div>
<div class="section" id="who-hates-stdlib-s-logging-remco-wendt">
<h1>Who hates stdlib's logging? - Remco Wendt</h1>
<p>A small teaser for a bigger talk at <a class="reference external" href="http://wiki.python.org/moin/PUN/ABC201202">next month's Dutch python meeting</a>.</p>
<p><a class="reference external" href="http://pypi.python.org/pypi/Logbook">Logbook</a> is nicer logging for python
than the standard library's default logging module.</p>
<p>And for Django: whatever logging module you use, use django-sentry to get a
website that collects your various site's logs. He made a version that works
especially nice with logbook, as logbooks gives you all logs of a web request
if something goes wrong: it doesn't only give you just the last traceback. So use
debug logging liberally, it will help you debug.</p>
</div>
<div class="section" id="loops-net-django-hosting-christo-buschek">
<h1>30loops.net Django hosting - Christo Buschek</h1>
<p><a class="reference external" href="http://30loops.net/">http://30loops.net/</a> is a Python and Django hosting platform, located in
Amsterdam (and a bit in Berlin since he moved recently).</p>
<p>They have years of experience in sysadmin and hosting, so they're building yet
another django/python/wsgi hosting platform. What you normally get at such a
&quot;platform as a service:</p>
<ul class="simple">
<li>Pay only for what you use.</li>
<li>Scale horizontally as needed.</li>
<li>You can concentrate on developpment, we care about the rest</li>
</ul>
<p>They differ on two major points:</p>
<ul class="simple">
<li>REST interface with json. You can build your own custom tools if needed.</li>
<li>One app can have multiple environments, like
development/staging/production. You can clone environments. Handy for
testing and running performance tests - all without interfering with
production.</li>
</ul>
<p>They actually abstracted away quite a lot, so you can run your apps on
30loops' own hardware, but also on other cloud providers. Handy if you have to
deploy to multiple physical locations.</p>
<p>You can access all logs and metrics with REST: you own all your data.</p>
<p>They're also on github: <a class="reference external" href="https://github.com/30loops">https://github.com/30loops</a></p>
<p>You can sign up for private beta now, btw.</p>
</div>
<div class="section" id="what-does-is-take-to-be-a-professional-developer-nicolaas-heyning">
<h1>What does is take to be a professional developer? - Nicolaas Heyning</h1>
<p>Asking around gave the usual list of &quot;good tools&quot;, &quot;passion&quot; and &quot;emacs&quot;. He
mentioned:</p>
<ul class="simple">
<li>Clients. Online like freelance.nl, linkedin, network meetings, by
reference. From the audience: organize stuff; run a blog.</li>
<li>Administration. Taxes, budgetting, investments, staff. From the audience:
outsourcing (but be very, very careful); having a partner in the company
that wants to do this.</li>
<li>Professional work. Provide documentation. Add
tests. Internationalization. Data migrations. Etcetera.</li>
</ul>
<p>Why all these questions? Reason: there is a big need for professional software
developers. You see lots of mails on the mailinglist asking for personell.</p>
<p>Would it be a good idea to start a &quot;django academy&quot;? Certification? Learning
about acquiring clients? Create a network for supply and demand of
professional developers?</p>
<p>There was quite some discussion afterwards (and I didn't agree with some of
the points, for the record).</p>
</div>
<div class="section" id="django-fiber-11-000-downloads-later-dennis-bunskoek">
<h1>Django Fiber - 11.000 downloads later - Dennis Bunskoek</h1>
<p><a class="reference external" href="https://github.com/ridethepony/django-fiber">Django fiber</a> is a simple,
user friendly CMS for your Django projects. It is getting bigger and
bigger. 11k downloads since April 7, 2011. That's about 1250 downloads per
month. That's only counted on pypi, though. Django CMS has 60k downloads since
the beginning of time, as a comparison. So it is turning out to be pretty big!</p>
<p>What did we do since early 2011?</p>
<ul class="simple">
<li>Performance and admin improvements.</li>
<li>Translations. (Via transifex, they got quite some contributed translations!)</li>
<li>Lots of spit&amp;polish. Better WYSIWIG editor.</li>
</ul>
<p>And... they build a lot of sites and apps with it (he said to me they build
some 60 sites!)</p>
<p>Near-future plans:</p>
<ul class="simple">
<li>Better integration of <em>your</em> models.</li>
<li>UI and performance improvements. They are having a sprint session tomorrow
with some designers that are also users of a Fiber website. Nice.</li>
<li>Better page creation (widgets, lists and views of <em>your</em> model instances).</li>
<li>Versioning of pages and content.</li>
<li>More tests and even better documentation. Sass/coffeescript.</li>
</ul>
<p>They are realizing that they need to build a community around it if they want
to get it off the ground further:</p>
<ul class="simple">
<li>Create a real django fiber website.</li>
<li>Better documentation: read the docs website. And videos.</li>
<li>More examples in the Django fiber example.</li>
<li>Get more use out of github. More interaction via issues and pull requests.</li>
</ul>
<p>Nice: a couple of days ago, Luke Plant mentioned <a class="reference external" href="http://lukeplant.me.uk/blog/posts/some-quick-django-optimisation-lessons/">some big db optimizations
for Django</a>. They
will look at that tomorrow, too.</p>
<p>(I wrote about an <a class="reference external" href="http://reinout.vanrees.org/weblog/2011/04/13/django-fiber.html">earlier 30 minute talk he gave on Django Fiber</a> for if you
want more information.)</p>
</div>
</div>

        </div>
      </content>

    </entry>
    
  <entry>
    <title>Scalable Vector Graphics (SVG) - Jeroen Dijkmeijer</title>
    <link rel="alternate" type="text/html"
          href="http://reinout.vanrees.org/./weblog/2012/01/18/scalable-vector-graphics.html" />
      <id>http://reinout.vanrees.org/./weblog/2012/01/18/scalable-vector-graphics.html</id>
      <author>
        <name>Reinout van Rees</name>
      </author>
      <published>2012-01-18T00:00:00+01:00</published>
      <updated>2012-01-22T23:02:00+01:00</updated>

      
      <category term="django" />
      
      <category term="pun" />
      

      <content type="xhtml"
               xml:base="http://reinout.vanrees.org/"
               xml:lang="en-US"
               xml:space="preserve">
        <div xmlns="http://www.w3.org/1999/xhtml">
          <div class="document">
<p>(Talk at the <a class="reference external" href="http://wiki.python.org/moin/DjangoMeetingNL/DM/ABC120118">2012-01-18 Dutch Django meeting</a>)</p>
<p>Jeroen actually has zero Django experience, but he <a class="reference external" href="http://www.iscriptdesign.com/">does nice things</a> :-) That website of his is actually made
with SVG.</p>
<dl class="docutils">
<dt><strong>Update 2012-01-23</strong>: his presentation is online at</dt>
<dd><a class="reference external" href="http://www.iscriptdesign.com/svgopen/presentation/">http://www.iscriptdesign.com/svgopen/presentation/</a> .</dd>
</dl>
<p>SVG is more than 10 years old, Adobe published the first version in 1999. IE6
supported it with an adobe plugin, most other browsers started adopting it in
2003. IE9 fully supports it, btw. Nice: since 2011 (<strong>corrected</strong>, I said
2001...) it is even part of the html5 specification.</p>
<p>Scalable vector images are, well, scalable. Despite the screen size, you won't
see the pixels as in an upscaled pixel image.</p>
<p>SVG as a format is just XML. You can draw lines, arcs, circles, boxes and so
on on a canvas. The output can be styled with css, just like html. It are DOM
elements. And you can manipulate the drawn SVG elements with javascript, too.</p>
<p>What you use often is pen movements. M or m for move, L or l to draw a
line. The lower case is relative to the current location, the upper case for
absolute location. <tt class="docutils literal">M 10 10 l 10 20 l 20 20 l 20 10 l 10 10</tt> would draw a
rectangle. For more elaborate forms you can use <a class="reference external" href="http://inkscape.org/">inkscape</a>, an open source SVG editor.</p>
<p>Nice: events on SVG objects can be processed by Javascript. You can also do
animations with SVG. There are three ways:</p>
<ul class="simple">
<li>CSS. Very promising, but browser support is spotty and it is still not
really completely standardized.</li>
<li>SMIL. Synchronised multimedia language. It came from CWI, where Python also
came from :-) It ran out of steam early on because of flash and so, but it
is now back inside SVG.</li>
<li>With javascript. &quot;Simple&quot; DOM manipulation.</li>
</ul>
<p>As browser compatibility is still a bit of a problem, you're probably best off
by using libraries like <a class="reference external" href="http://raphaeljs.com">raphaeljs</a> if you want to use
SVG. (Personal note: I used raphaeljs with success in a small Django project
last week).</p>
<p>He showed a couple of demos. What was particularly good was the easy and
on-the-fly integration between forms and the picture (like for a custom table
that can hover over the couch). Put in a different height of the couch and the
table would adjust. Good javascript integration.</p>
<p>He uses it for making designs for feeding them into CNC milling machines like
they have at the <a class="reference external" href="http://fablab.waag.org/">fab lab in The Waag in Amsterdam</a>.</p>
</div>

        </div>
      </content>

    </entry>
    
  <entry>
    <title>Django explained with model/view/controller (MVC)</title>
    <link rel="alternate" type="text/html"
          href="http://reinout.vanrees.org/./weblog/2011/12/13/django-mvc-explanation.html" />
      <id>http://reinout.vanrees.org/./weblog/2011/12/13/django-mvc-explanation.html</id>
      <author>
        <name>Reinout van Rees</name>
      </author>
      <published>2011-12-13T00:00:00+01:00</published>
      <updated>2011-12-12T23:38:00+01:00</updated>

      
      <category term="django" />
      
      <category term="book" />
      

      <content type="xhtml"
               xml:base="http://reinout.vanrees.org/"
               xml:lang="en-US"
               xml:space="preserve">
        <div xmlns="http://www.w3.org/1999/xhtml">
          <div class="document">
<p>In an early chapter of my upcoming &quot;solid Django&quot; book, I have to explain
Django. How it works, what it is, how it does things. I use several ways. One
of them is the well-known <a class="reference external" href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller">model/view/controller</a> (MVC)
architecture.</p>
<p>Most web frameworks explain themselves in that way and every web framework
sees MVC a bit differently. For Django, for instance, you also see
&quot;model/view/template&quot; as an explanation. I myself think that MVC offers a
pretty helpful way to look at Django. Only, it is pretty hard to explain
right. And I have to leave out quite some details: it is an early chapter. So
I'm leaving out middleware, forms, template tags and so on :-)</p>
<p>Here's the core of my explanation. If you've got any
<strong>suggestion/gripe/complaint/praise</strong>, please share it as a comment on this
article. That way I can improve my chapter! I'm well aware that you can
explain Django in lots of ways so I want to make sure I don't foul it up.</p>
<ul class="simple">
<li><strong>Controller</strong>.  A controller is the heart of the system, it steers
everything. For a web framework, this means handling requests and responses,
setting up database connections and loading add-ons. For this, Django reads
a <em>settings file</em> so that it knows what to load and set up. And Django reads
a <em>URL config file</em> that tells it what to do with the incoming requests from
browsers.</li>
<li><strong>Model</strong>. The model layer in Django means the database plus the Python code
that directly uses it. It models reality. You capture whatever your website
needs in database tables. Django helps you write Python classes (called
<em>models</em>) that tie 1:1 to the database tables.</li>
<li><strong>View</strong>. The view layer is the user interface. Django splits this up in the
actual HTML pages and the Python code (called <em>views</em>) that renders
them. And it also has an automatic web admin interface for editing the
models.</li>
</ul>
<p>I've also made a video where I'm explaining it this way. I'm experimenting to
find a good setup for making such a video, so it isn't perfect yet. Especially
the sound can be better, I think.</p>
<a class="reference external image-reference" href="http://photos.reinout.vanrees.org/Grok-zope-plone-python/Plone-videos/6596747_FJqGQW#1629164503_rMjWJwV-A-LB"><img alt="video explaining Django with the model/view/controller paradigm" src="http://photos.reinout.vanrees.org/photos/1629164503_rMjWJwV-M.jpg" /></a>
</div>

        </div>
      </content>

    </entry>
    
  <entry>
    <title>Checking out tags from git on your server</title>
    <link rel="alternate" type="text/html"
          href="http://reinout.vanrees.org/./weblog/2011/12/10/git-fetch-tag.html" />
      <id>http://reinout.vanrees.org/./weblog/2011/12/10/git-fetch-tag.html</id>
      <author>
        <name>Reinout van Rees</name>
      </author>
      <published>2011-12-10T00:00:00+01:00</published>
      <updated>2011-12-10T20:22:00+01:00</updated>

      
      <category term="django" />
      

      <content type="xhtml"
               xml:base="http://reinout.vanrees.org/"
               xml:lang="en-US"
               xml:space="preserve">
        <div xmlns="http://www.w3.org/1999/xhtml">
          <div class="document">
<p>Properly tagged and released: that, all our websites are. Most of them are subversion
projects, but a handful are now in git. When switching to a new version of a
site, the subversion process is clear:</p>
<pre class="literal-block">
$&gt; svn switch https://our.svn.server/project/tags/1.2
$&gt; bin/buildout
$&gt; ...
</pre>
<p>And the next time:</p>
<pre class="literal-block">
$&gt; svn switch https://our.svn.server/project/tags/1.3
$&gt; bin/buildout
$&gt; ...
</pre>
<p>What I did with our first git project (after an initial &quot;clone&quot; of course):</p>
<pre class="literal-block">
$&gt; git pull
$&gt; git checkout 1.2
... Dire warning about &quot;headless state&quot; as I checked out a tag ...
$&gt; bin/buildout
$&gt; ...
</pre>
<p>And the second time:</p>
<pre class="literal-block">
$&gt; git pull
... polite notice to bugger off as we're in a headless state ...
... no, we're not going to do a pull! ...
</pre>
<p>Ok, what now? I asked around on twitter and got the <strong>luckily simple answer</strong>:
use <tt class="docutils literal">git fetch</tt> instead of <tt class="docutils literal">git pull</tt>. Fetch fetches the last bunch of
commits from the server. Pull does the same and <em>additionally</em> updates the
checkout to the latest relevant version. Which it refuses to do if the current
checkout is a tag.</p>
<p>A tag as such is not really connected to the main tree of development that git
knows about. It is more of a light-weight pointer. You get a certain clearly
identified version of the code, but that version you have is not really hooked
up in to the git tree. It has no parent to point to, so it also doesn't have a
relation to some pointer to the latest version on this branch of the tree: the
head. That's where the &quot;headless state&quot; comes from.</p>
<p><tt class="docutils literal">git fetch</tt> just grabs the latest state from the server. And a subsequent
<tt class="docutils literal">git checkout 1.3</tt> checks out the 1.3 tag without a complaint:</p>
<pre class="literal-block">
$&gt; git fetch
$&gt; git checkout 1.3
$&gt; bin/buildout
$&gt; ...
</pre>
<a class="reference external image-reference" href="http://reinout.smugmug.com/Trains/Model-train-exhibitions/4740025_KfmfgJ#448558795_khhsH-A-LB"><img alt="Signal box on a model railway (Dreim&amp;uuml;hletalbahn)" src="http://photos.reinout.vanrees.org/photos/448558795_khhsH-M.jpg" /></a>
</div>

        </div>
      </content>

    </entry>
    
  <entry>
    <title>Many-to-many field, save() method and the Django admin</title>
    <link rel="alternate" type="text/html"
          href="http://reinout.vanrees.org/./weblog/2011/11/29/many-to-many-field-save-method.html" />
      <id>http://reinout.vanrees.org/./weblog/2011/11/29/many-to-many-field-save-method.html</id>
      <author>
        <name>Reinout van Rees</name>
      </author>
      <published>2011-11-29T00:00:00+01:00</published>
      <updated>2011-12-10T20:22:00+01:00</updated>

      
      <category term="django" />
      

      <content type="xhtml"
               xml:base="http://reinout.vanrees.org/"
               xml:lang="en-US"
               xml:space="preserve">
        <div xmlns="http://www.w3.org/1999/xhtml">
          <div class="document">
<p>I've got a model <tt class="docutils literal">UserGroup</tt> with many-to-many fields for managers and
members:</p>
<pre class="literal-block">
class UserGroup(models.Model):
    managers = models.ManyToManyField(User)
    members = models.ManyToManyField(User)
    # Note: some stuff stripped out for brevity
</pre>
<p>I wanted every manager to be a member, too, automatically. So I added a custom
<tt class="docutils literal">save()</tt> method:</p>
<pre class="literal-block">
class UserGroup(models.Model):
    managers = models.ManyToManyField(User)
    members = models.ManyToManyField(User)
    # Note: some stuff stripped out for brevity

    def save(self, *args, **kwargs):
        if self.id:
            members = self.members.all()
            for manager in self.managers.all():
                if manager not in members:
                    self.members.add(manager)
        super(UserGroup, self).save(*args, **kwargs)
</pre>
<p>Which worked fine in my unittest, but not in the actual admin interface.</p>
<p>I found the reason <a class="reference external" href="http://stackoverflow.com/questions/1925383/issue-with-manytomany-relationships-not-updating-inmediatly-after-save/1925784#1925784">on stackoverflow</a>:
the Django admin clears the many-to-many fields <em>after</em> saving the model and
sets them anew with the data it knows about. So my <tt class="docutils literal">save()</tt> method worked
fine, but saw its work zapped by Django's admin...</p>
<p>Django's development docs <a class="reference external" href="https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.save_related">say that 1.4 will have</a>
a <tt class="docutils literal">save_related()</tt> model admin method. Which sounds like it could help work
around this issue.</p>
<p>The solution I ended up with was to add a custom model admin form and to
use the <tt class="docutils literal">clean()</tt> method to just modify the form data. I got the idea <a class="reference external" href="http://stackoverflow.com/questions/1925383/issue-with-manytomany-relationships-not-updating-inmediatly-after-save/7000782#7000782">also
from stackoverflow</a>. Here's
the relevant part of my <tt class="docutils literal">admin.py</tt>:</p>
<pre class="literal-block">
class UserGroupAdminForm(ModelForm):
    class Meta:
        model = UserGroup

    def clean(self):
        &quot;&quot;&quot;Make sure all managers are also members.&quot;&quot;&quot;
        for manager in self.cleaned_data['managers']:
            if manager not in self.cleaned_data['members']:
                self.cleaned_data['members'].append(manager)
        return self.cleaned_data


class UserGroupAdmin(admin.ModelAdmin):
    model = UserGroup
    form = UserGroupAdminForm
</pre>
<p>It works fine now.</p>
<p><strong>Addition 2011-1202</strong>. It didnt' work so fine after all. There's one problem,
which you can also <a class="reference external" href="http://stackoverflow.com/questions/5527525/problem-appending-to-manytomany-form-field-when-cleaning-data">find on stackoverflow</a>. Django
converts the raw form data to python objects. In the case of these user object
you get a <em>queryset</em> in the latest Django version instead of a list of user
objects. <tt class="docutils literal">.append()</tt> doesn't work on a queryset. So I took one of the
suggestions on stackoverflow and converted the queryset to a list, first:</p>
<pre class="literal-block">
def clean(self):
    &quot;&quot;&quot;Make sure all managers are also members.&quot;&quot;&quot;
    members = list(self.cleaned_data['members'])
    for manager in self.cleaned_data['managers']:
        if manager not in members:
            members.append(manager)
    self.cleaned_data['members'] = members
    return self.cleaned_data
</pre>
<a class="reference external image-reference" href="http://photos.reinout.vanrees.org/Trains/Dutch-train-photos-80s-and/4740543_Pkn6T7#280835237_57rQK-A-LB"><img alt="Dutch station of Swalmen in the winter, late 1980s." src="http://photos.reinout.vanrees.org/photos/280835237_57rQK-M.jpg" /></a>
</div>

        </div>
      </content>

    </entry>
    

</feed>

