<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Zeta-Puppis.com &#187; Django</title>
	<atom:link href="http://zeta-puppis.com/category/django/feed/" rel="self" type="application/rss+xml" />
	<link>http://zeta-puppis.com</link>
	<description>my very own personal corner</description>
	<lastBuildDate>Wed, 07 Apr 2010 15:36:25 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>What I learned by information retrieval in one week</title>
		<link>http://zeta-puppis.com/2008/10/19/what-i-learned-by-information-retrieval-in-one-week/</link>
		<comments>http://zeta-puppis.com/2008/10/19/what-i-learned-by-information-retrieval-in-one-week/#comments</comments>
		<pubDate>Sun, 19 Oct 2008 16:38:24 +0000</pubDate>
		<dc:creator>kratorius</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[information retrieval]]></category>
		<category><![CDATA[IR]]></category>
		<category><![CDATA[machine learning]]></category>
		<category><![CDATA[natural language processing]]></category>
		<category><![CDATA[nlp]]></category>
		<category><![CDATA[search engine]]></category>
		<category><![CDATA[text categorization]]></category>
		<category><![CDATA[tf-idf]]></category>

		<guid isPermaLink="false">http://zeta-puppis.com/?p=159</guid>
		<description><![CDATA[It has been about a week since I began doing a deeper study of information retrieval. Actually, everything just began with a new course at my university about that and I just fallen in love almost immediately. The fact is that this thing really got me interested, and I began doing some experiments (one involves [...]]]></description>
			<content:encoded><![CDATA[<p>It has been about a week since I began doing a deeper study of information retrieval. Actually, everything just began with a new course at my university about that and I just fallen in love almost immediately. The fact is that this thing really got me interested, and I began doing some experiments (one involves django as well, keep reading to know&nbsp;more).</p>
<p>In this week I learned a lot of things about information retrieval, text categorization, natural language processing and machine learning. But the most relevant thing is: <strong>the principles are easy, their implementation is not</strong>. The fact is that most of the techniques are relatively simple but you usually have to deal with very large datasets and this could be challenging, since one of the main requirements about information retrieval is time. It&#8217;s really much more important that you give less results in one second rather than giving better results in one hour. No one will ever care to use your system if it takes an hour to get some result. And if you&#8217;re considering to store your data in a database forget about normalization, it wouldn&#8217;t really take you&nbsp;anywhere.</p>
<p><span id="more-159"></span>Talking about storing informations, you know that if you&#8217;re dealing with documents most of the words are the so called <em>stop words</em>. Those stop words are words that doesn&#8217;t really mean anything, but they help the readers to get a better text flux. Classic examples of stop words are articles like &#8220;the&#8221;, &#8220;a&#8221;, &#8220;an&#8221; or logic connectors like &#8220;or&#8221; and &#8220;and&#8221;. <strong>These words are so common that their presence is quite useless since they&#8217;re are&#8230; everywhere</strong>. If you&#8217;re going to study information retrieval than you&#8217;ll learn about a weighting technique called <a href="http://en.wikipedia.org/wiki/Tf-idf">tf-idf</a> that gives a weight near to 0 to these words, but since you&#8217;d probably use a reverse index for words (an index that given a word, tells you in which documents that word appears) you can understand that this would take a lot of space if you&#8217;re going to include stop&nbsp;words.</p>
<p>So one of the biggest issues until now is that you&#8217;re going to deal with extremely large datasets, so you have to strip as many things as possible. Now consider those words: &#8220;fishing&#8221;, &#8220;fishes&#8221;, &#8220;fish&#8221;. They all talk about &#8220;fish&#8221;, and an user that is searching for &#8220;fish&#8221; would probably be interested in &#8220;fishes&#8221; or &#8220;fishing&#8221; as well. Additionally, it&#8217;s useless to store three words that are almost identical. So here comes the <em>stemming</em> that, by quoting the related <a href="http://en.wikipedia.org/wiki/Stemming">wikipedia page</a>, is the <cite>process for reducing inflected (or sometimes derived) words to their stem, base or root form – generally a written word form</cite>. Fortunately, if you&#8217;re dealing with english texts, there&#8217;s the <a href="http://tartarus.org/~martin/PorterStemmer/">Porter algorithm</a> that is the state-of-the-art algorithm for this sort of things. But that works only with english, so <strong>if your documents are written in another language or they are written in multiple languages, things are going to be&nbsp;complicated</strong>.</p>
<p>This leads to think about the problem of the language identification. How do you know if some text is written in a language or in another just by looking at it? Of course you can describe the document&#8217;s language with some kind of meta tagging, but not all the documents have this kind of description, just think about the web. There are some kind of statistical methods based upon the classification of <a href="http://en.wikipedia.org/wiki/N-gram">n-grams</a> but I haven&#8217;t deeply investigated about them yet, so I can&#8217;t really say&nbsp;anything.</p>
<p>Now you got your collection of documents that <em>match</em> a certain query. Now: how do you know what document is more relevant than another (in other words: how do you <em>rank</em> pages)? You got two alternatives (well, probably more, but I know just these at this moment): <strong>the tf-idf that we said above and the <a href="http://en.wikipedia.org/wiki/Cosine_similarity">cosine similarity</a></strong>. The latter is an interesting one: consider the tf-idf vectors of the documents, then consider the query as a document too. Now plot those tf-idf vectors and measure their cosine of the angle between them. The more you&#8217;re near to 1, the more relevant is the&nbsp;document.</p>
<p>There are a lot of other important things that need to be said like the precision and recall concept, but that&#8217;s enough for now. I&#8217;ll talk about this another&nbsp;time.</p>
<p>Anyway I&#8217;m doing an experimental project named <a href="http://code.google.com/p/django-searchable/">django searchable</a>. It&#8217;s a pluggable app for django that implements an information retrieval engine based on tf-idf weighting. Play with it if you&#8217;re brave&nbsp;enough.</p>
]]></content:encoded>
			<wfw:commentRss>http://zeta-puppis.com/2008/10/19/what-i-learned-by-information-retrieval-in-one-week/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Running Django with fastcgi</title>
		<link>http://zeta-puppis.com/2008/10/08/running-django-with-fastcgi/</link>
		<comments>http://zeta-puppis.com/2008/10/08/running-django-with-fastcgi/#comments</comments>
		<pubDate>Wed, 08 Oct 2008 18:18:01 +0000</pubDate>
		<dc:creator>kratorius</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[fcgi]]></category>
		<category><![CDATA[lighttpd]]></category>
		<category><![CDATA[pid]]></category>
		<category><![CDATA[runfcgi]]></category>
		<category><![CDATA[server]]></category>
		<category><![CDATA[socket]]></category>
		<category><![CDATA[startserver]]></category>

		<guid isPermaLink="false">http://zeta-puppis.com/?p=152</guid>
		<description><![CDATA[Running django with fastcgi is not a difficult task, also because of the excellent documentation provided. Anyway the doc provides a very basic script to automatize the start/stop fcgi process, so today I had to write my own so I don&#8217;t have to manually fix things if something goes wrong since I let my script [...]]]></description>
			<content:encoded><![CDATA[<p>Running django with fastcgi is not a difficult task, also because of the excellent documentation provided. Anyway the doc provides a very basic script to <em>automatize</em> the start/stop fcgi process, so today I had to write my own so I don&#8217;t have to manually fix things if something goes wrong since I let my script handle the various&nbsp;situations.</p>
<p><span id="more-152"></span>It has a very basic start/stop/restart interface like normal startup scripts. Let see an example of basic&nbsp;usage:</p>
<pre><code>kratorius@becks:~/prj$ sudo sh startserver.sh start
Starting fcgi process... done!
kratorius@becks:~/prj$ sudo sh startserver.sh stop
kratorius@becks:~/prj$ sudo sh startserver.sh restart
fcgi process is not running
kratorius@becks:~/prj$ sudo sh startserver.sh start
Starting fcgi process... done!
kratorius@becks:~/prj$ sudo sh startserver.sh restart
Starting fcgi process... done!</code></pre>
<p>And here it&nbsp;is:</p>
<pre><code>#!/bin/bash
# Start and stop a django fcgi process
# Giuliani Vito Ivan &lt;giuliani.v@gmail.com&gt;

# project directory
PROJDIR=`pwd`

# user owner (usually www-data)
USER_OWNER="www-data"

# group owner (usually www-data)
GROUP_OWNER="www-data"

# extra python path (leave empty if unneeded)
PYTHONPATH="../python:.."

# do not edit anything below
PIDFILE="$PROJDIR/technosec.pid"
SOCKET="$PROJDIR/technosec.sock"

start_fcgi()
{
	if [ -f $PIDFILE ] || [ -f $SOCKET ]; then
		echo "The fcgi process is already running, please stop"
		echo "that before running another process"
	else
		echo -n "Starting fcgi process... "

		nohup /usr/bin/env - \
			PYTHONPATH=$PYTHONPATH \
			python manage.py runfcgi socket=$SOCKET pidfile=$PIDFILE &gt; /dev/null 2&gt;&amp;1 &amp;
		if [ $? -eq 0 ]; then
			sleep 1
			chown $USER_OWNER:$GROUP_OWNER $SOCKET
			chown $USER_OWNER:$GROUP_OWNER $PIDFILE
			echo "done!"
		else
			echo "failed!"
		fi

		return $?
	fi

	return 1
}

stop_fcgi()
{
	cd $PROJDIR
	if [ -f $PIDFILE ]; then
		kill `cat -- $PIDFILE`
		rm -f -- $PIDFILE
		rm -f -- $SOCKET

		return 0
	else
		echo "fcgi process is not running"
		return 1
	fi
}

restart_fcgi()
{
	stop_fcgi
	if [ $? -eq 0 ]; then
		start_fcgi
	fi
}

case "$1" in
	start)
		start_fcgi
		;;
	stop)
		stop_fcgi
		;;
	restart)
		restart_fcgi
		;;
	*)
		echo "Usage: $0 {start|stop|restart}"
		exit 1
		;;
esac

exit 0</code></pre>
<p>Just in case you may want to download it, <a href="/wp-content/uploads/2008/10/startserver.sh">here it&nbsp;is</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://zeta-puppis.com/2008/10/08/running-django-with-fastcgi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Announcing Pytagram</title>
		<link>http://zeta-puppis.com/2008/08/21/announcing-pytagram/</link>
		<comments>http://zeta-puppis.com/2008/08/21/announcing-pytagram/#comments</comments>
		<pubDate>Thu, 21 Aug 2008 14:42:11 +0000</pubDate>
		<dc:creator>kratorius</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[pytagram]]></category>
		<category><![CDATA[svg]]></category>
		<category><![CDATA[toc]]></category>

		<guid isPermaLink="false">http://zeta-puppis.com/?p=138</guid>
		<description><![CDATA[Today I just ended one of my side projects: pytagram. Basically it generates an SVG file (that can successively be saved as eps/pdf/whatever and eventually manually manipulated) starting from a tree-like plain text file. This can be useful for generating cheat sheets or quick references to classes or functions that belongs to some&#160;project.
I did this [...]]]></description>
			<content:encoded><![CDATA[<p>Today I just ended one of my side projects: pytagram. Basically it generates an SVG file (that can successively be saved as eps/pdf/whatever and eventually manually manipulated) starting from a tree-like plain text file. This can be useful for generating <strong>cheat sheets or quick references</strong> to classes or functions that belongs to some&nbsp;project.</p>
<p>I did this for generating a <a href="http://djangoproject.com">django</a> quick reference (<a href="http://zeta-puppis.com/wp-content/uploads/2008/08/django1.svg">here it is</a>) since it has a lot of functions and I know what&#8217;s their purpose, but I can never remember the names (and now two A4 papers are right in front of&nbsp;me).</p>
<p>If you&#8217;re interested in this, check out the <a href="http://code.google.com/p/pytagram/">google code project page</a> and grab your copy from the SVN&nbsp;repository.</p>
<p>There are <strong>tons of things that can be changed/optimized</strong> (i.e.: add some optional short explanation of the function, add more examples, easier way to change colors, &#8230;) but now the code is working quite well so that can be already useful to the people out&nbsp;there.</p>
]]></content:encoded>
			<wfw:commentRss>http://zeta-puppis.com/2008/08/21/announcing-pytagram/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Practical Django Projects</title>
		<link>http://zeta-puppis.com/2008/07/05/practical-django-projects/</link>
		<comments>http://zeta-puppis.com/2008/07/05/practical-django-projects/#comments</comments>
		<pubDate>Sat, 05 Jul 2008 12:02:58 +0000</pubDate>
		<dc:creator>kratorius</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Me]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[amazon]]></category>
		<category><![CDATA[book]]></category>
		<category><![CDATA[practical django projects]]></category>

		<guid isPermaLink="false">http://zeta-puppis.com/?p=95</guid>
		<description><![CDATA[Due to my devotion to the Django web framework, I finally got my copy of Practical Django Projects, by James Bennet. Not really expecting to have that soon, but a beautiful suprise anyway (to say the truth, I didn&#8217;t bought this: this has been sent to me as replacement prize for djangodash because I was [...]]]></description>
			<content:encoded><![CDATA[<p>Due to my devotion to the <a href="http://djangoproject.com">Django</a> web framework, I finally got my copy of <a href="http://www.amazon.com/dp/1590599969/">Practical Django Projects</a>, by <a href="http://b-list.org">James Bennet</a>. Not really expecting to have that soon, but a <strong>beautiful suprise</strong> anyway (to say the truth, I didn&#8217;t bought this: this has been sent to me as <em>replacement prize</em> for <a href="http://djangodash.com">djangodash</a> because I was not elegible to get the G33K beers since I live outside US. Thanks to the generosity of <a href="http://toastdriven.com">Daniel&nbsp;Lindsley</a>).</p>
<p><span id="more-95"></span></p>
<p><img src="/wp-content/uploads/2008/07/practical.jpg" alt="the Django Practical Projects book" width="400" height="308" class="aligncenter size-full wp-image-96" /></p>
]]></content:encoded>
			<wfw:commentRss>http://zeta-puppis.com/2008/07/05/practical-django-projects/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>And djangodash is ended&#8230;</title>
		<link>http://zeta-puppis.com/2008/06/11/and-djangodash-is-ended/</link>
		<comments>http://zeta-puppis.com/2008/06/11/and-djangodash-is-ended/#comments</comments>
		<pubDate>Wed, 11 Jun 2008 14:43:23 +0000</pubDate>
		<dc:creator>kratorius</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[dash]]></category>
		<category><![CDATA[djangodash]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://zeta-puppis.com/?p=93</guid>
		<description><![CDATA[And I&#8217;ve been 6th. So I won a shared 2 hosting plan at webfaction and a 12 pack of G33K B33R caffeinated root beer (still trying to understand what this is exactly, anyway) from bawls. Anyway, here follows a short resume of what happened from Saturday through Tuesday (if you&#8217;re asking yourself why it didn&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p>And I&#8217;ve been 6th. So I won a shared 2 hosting plan at <a href="http://webfaction.com">webfaction</a> and a 12 pack of G33K B33R caffeinated root beer (still trying to understand what this is exactly, anyway) from <a href="http://www.bawlstyle.com">bawls</a>. Anyway, here follows <strong>a short resume of what happened</strong> from Saturday through Tuesday (if you&#8217;re asking yourself why it didn&#8217;t ended on Sunday, well, keep&nbsp;reading).</p>
<p>The competition began very well, I worked normally for the first part of the day but then I had to stop for a while. When I came back, <strong>svn and <a href="http://djangodash.com">djangodash</a> website was not working anymore</strong>. I initially thought that it was some connection issue but when I saw that other sites were working properly so they definitely had some&nbsp;problems.</p>
<p><span id="more-93"></span>I just waited, then gone sleeping. In the morning I received in my mailbox a message that informed me of a big power outage in <a href="http://www.theplanet.com">The Planet</a> datacenter where webfaction hosts a lot of their server (among the which there was the <a href="http://djangodash.com">djangodash</a> one) caused by power generator&#8217;s explosion. Then <strong>the competition has been delayed for other two days</strong>, so I decided to take a breath and wait &#8216;till the svn would came back. But that didn&#8217;t happen on Sunday, so after a while I chosen (as the mail suggested) to work locally without committing anything at least until the svn&nbsp;return.</p>
<p>Then Monday came and I had other things to do, so I had to postpone <a href="http://djangodash.com">djangodash</a> for the evening when I&#8217;d freed myself from other, most urgent things. On Monday <strong>I did a very little coding</strong>, as well on Tuesday. So at the end of competition I cannot complete my project, and not even reach the 50%&nbsp;milestone.</p>
<p>Today I discovered that <strong>I was one of the winners</strong> (ok not really, 6th place was not really a good place, but at least I tried) and I really have to thanks the organizers for this event and hope to join another <a href="http://djangodash.com">djangodash</a> next year. Maybe, as I said to one of them in an email thread, hosting the site/svn in two different datacenters, just to be insured against eventual thunderstorms, tornado, earthquakes and so on&#8230;). I have to say that I really enjoyed the whole thing, and hope to have more competitors next&nbsp;year!</p>
<p>If you want to get more news about final process of <a href="http://djangodash.com">djangodash</a> with some stats, <a href="http://www.toastdriven.com/fresh/django-dash-factoids/">read this article</a> on the <a href="http://www.toastdriven.com">Toast Driven</a> website (that&#8217;s the company that ran the&nbsp;dash).</p>
]]></content:encoded>
			<wfw:commentRss>http://zeta-puppis.com/2008/06/11/and-djangodash-is-ended/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Let meet at djangodash</title>
		<link>http://zeta-puppis.com/2008/05/04/let-meet-at-djangodash/</link>
		<comments>http://zeta-puppis.com/2008/05/04/let-meet-at-djangodash/#comments</comments>
		<pubDate>Sun, 04 May 2008 10:20:59 +0000</pubDate>
		<dc:creator>kratorius</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[competition]]></category>
		<category><![CDATA[dash]]></category>
		<category><![CDATA[djangodash]]></category>
		<category><![CDATA[prizes]]></category>

		<guid isPermaLink="false">http://zeta-puppis.com/?p=89</guid>
		<description><![CDATA[As probably many of you already knows, on May 31 will begin the Django dash competition. Djangodash&#160;is:
[&#8230;] is a chance for Django enthusiasts to flex their coding skills a little and put a fine point on “perfectionists with deadlines” by giving you a REAL deadline. 48 hours from start to stop to produce the best [...]]]></description>
			<content:encoded><![CDATA[<p>As probably many of you already knows, <strong>on May 31</strong> will begin the Django dash competition. <a href="http://djangodash.com">Djangodash</a>&nbsp;is:</p>
<blockquote><p>[&#8230;] is a chance for Django enthusiasts to flex their coding skills a little and put a fine point on “perfectionists with deadlines” by giving you a REAL deadline. 48 hours from start to stop to produce the best app you can and have a little fun in the&nbsp;process.</p></blockquote>
<p>I&#8217;ll be participating, so if you haven&#8217;t registered yet, <strong>do it now</strong>! And don&#8217;t forget to check out <a href="http://djangodash.com/sponsors/">the cool prizes</a>&nbsp;:)</p>
]]></content:encoded>
			<wfw:commentRss>http://zeta-puppis.com/2008/05/04/let-meet-at-djangodash/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Forcing ImageField width/height in django</title>
		<link>http://zeta-puppis.com/2008/03/02/forcing-imagefield-widthheight-in-django/</link>
		<comments>http://zeta-puppis.com/2008/03/02/forcing-imagefield-widthheight-in-django/#comments</comments>
		<pubDate>Sun, 02 Mar 2008 09:24:22 +0000</pubDate>
		<dc:creator>kratorius</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[dimension]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[imagefield]]></category>
		<category><![CDATA[pil]]></category>
		<category><![CDATA[size]]></category>
		<category><![CDATA[workaround]]></category>

		<guid isPermaLink="false">http://zeta-puppis.com/2008/03/02/forcing-imagefield-widthheight-in-django/</guid>
		<description><![CDATA[Ultimately I had to force the size of a uploaded image in the django admin area to a fixed dimension of 620x250px. Even if it could look a simple thing, in fact it&#160;isn&#8217;t.
The main issue is that even if an ImageField has a width_field/height_field option that refers to (presumably) integer fields that will be auto-filled [...]]]></description>
			<content:encoded><![CDATA[<p>Ultimately I had to force the size of a uploaded image in the django admin area to a <strong>fixed dimension</strong> of 620x250px. Even if it could look a simple thing, in fact it&nbsp;isn&#8217;t.</p>
<p>The main issue is that even if an ImageField has a width_field/height_field option that refers to (presumably) integer fields that will be auto-filled with the image size, <strong>we can&#8217;t ran a validator across those fields</strong> (we can do so only in a form, but my problem was to validate the image in the admin area). So we have to manually load the image in memory and run a custom validator that uses <a href="http://www.pythonware.com/products/pil/">PIL</a> to get the needed information and validate the&nbsp;image.</p>
<p><span id="more-84"></span></p>
<p>Here&#8217;s the resulting code for the&nbsp;model:</p>
<pre><code>class FImage(models.Model):
    ...
    img = models.ImageField(upload_to='images', blank=False,
            verbose_name=_("Image"),
            validator_list=[custom_validators.ImageLarge(620, 250,
            _("The image must be 620x250px large!")), ],
            help_text=_("Image must be 620x250px large."))
    ...</code></pre>
<p>And for the validator (that you should put in some separated&nbsp;file):</p>
<pre><code>from django.utils.translation import gettext_lazy as _
from django.core import validators
import StringIO
from PIL import Image

class ImageLarge(object):
    def __init__(self, width, height, error_message=_("The image isn't as large as expected!")):
        self.w, self.h, self.error_message = width, height, error_message

    def __call__(self, field_data, all_data):
        im = Image.open(StringIO.StringIO(field_data['content']))
        if im.size[0] != self.w or im.size[1] != self.h:
            raise validators.ValidationError, self.error_message </code></pre>
<p>The main issue with this solution is that we store the <strong>entire image content in memory</strong> for processing through PIL. Additionally I don&#8217;t know if it will still work when the <a href="http://code.djangoproject.com/ticket/2070">#2070</a> ticket&#8217;s patch will be included in trunk (and I didn&#8217;t checked with the<br />
actual existing&nbsp;patch).</p>
<p>If you want, you can read the full discussion on&nbsp;<a href="http://groups.google.com/group/django-users/t/ed5d06a82ddfdd98">django-users</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://zeta-puppis.com/2008/03/02/forcing-imagefield-widthheight-in-django/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>When the &#8220;Python Vs PHP&#8221; war matters</title>
		<link>http://zeta-puppis.com/2008/02/21/when-the-python-vs-php-war-matters/</link>
		<comments>http://zeta-puppis.com/2008/02/21/when-the-python-vs-php-war-matters/#comments</comments>
		<pubDate>Thu, 21 Feb 2008 19:45:52 +0000</pubDate>
		<dc:creator>kratorius</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[IT]]></category>
		<category><![CDATA[mvc]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://zeta-puppis.com/2008/02/21/when-the-python-vs-php-war-matters/</guid>
		<description><![CDATA[Yesterday I had a meeting with a customer about a new site I should develop for them. Since they&#8217;re a book publisher, they wanted an online book store. Apart from the technical details (the site isn&#8217;t as simple as you may believe, they need a lot of not-so-easy-to-do stuff), the most important point we focused [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday I had a meeting with a customer about a new site I should develop for them. Since they&#8217;re a book publisher, they wanted an online book store. Apart from the technical details (the site isn&#8217;t as simple as you may believe, they need a lot of not-so-easy-to-do stuff), the most important point we focused on is the fact that <strong>they have an internal IT technician</strong> that handles all their computer needs. If you&#8217;re asking yourself why this matters, keep&nbsp;reading:</p>
<ul>
<li>me (to be precise, my company) stopped development of PHP sites about one year ago in favor of&nbsp;Python</li>
<li>we release the web site&#8217;s code to&nbsp;them</li>
<li>for this project, <strong>we haven&#8217;t been asked any kind of future support</strong>; this means that when the site is finished, we won&#8217;t touch the product anymore (unless they don&#8217;t pay us to do the modifies they&nbsp;need)</li>
<li>but they don&#8217;t want to pay us to these modifies, because they have their internal IT&nbsp;technician</li>
<li><strong>their technician knows only PHP</strong> (and he never even known the Python&#8217;s existence until&nbsp;yesterday)</li>
</ul>
<p><span id="more-82"></span></p>
<p>So I had to illustrate why me and my company chosen Python for our web development needs, and here&#8217;s a summary of what I told them yesterday. Note that <strong>I&#8217;m not talking about why a language is better than the other</strong>, because this would move us in another direction, but <strong>why we chosen Python as our main programming language</strong> (even if this unconsciously lead us to say why, for us, Python is better than PHP, but that&#8217;s another story)&nbsp;:</p>
<ul>
<li><strong>Time</strong>: remember that time is money. If I&#8217;d build an application in PHP, I&#8217;d spend about 1/3 of the time more if I&#8217;d develop the same application in&nbsp;Python</li>
<li><strong>Frameworks</strong>: nowadays all the popular languages have their web frameworks; Ruby has <a href="http://www.rubyonrails.org/">Ruby on Rails</a>, PHP has <a href="http://www.symfony-project.org/">Symfony</a>, <a href="http://www.phpmvc.net/">php.MVC</a>, Python has <a href="http://djangoproject.com/">Django</a>, <a href="http://www.cherrypy.org/">CherryPy</a>, <a href="http://pylonshq.com/">Pylons</a>, and so on. But none of them (apart from rails, but we&#8217;re talking about PHP Vs Python) goes near to the completeness and functionality of django. And this take us at the previous point: less time in develop the same&nbsp;application</li>
<li><strong>Future modifies</strong>: even if for this project this isn&#8217;t the case, it&#8217;s much easier to modify a Python application than a PHP one due to the syntax of the language and its strong <a href="http://en.wikipedia.org/wiki/Object-oriented_programming">OOP</a> orientation. You may argue that PHP 5 introduced a deep OOP support too, but that&#8217;s not the same thing and you know. PHP is born as procedural programming language, and even if we had OOP introduction in version 5, it doesn&#8217;t even comes near to Python under this point of&nbsp;view</li>
</ul>
<p>With this I&#8217;m not saying that PHP is useless: what I mean is that <strong>Python is more convenient under the (our) business point of view</strong>. So if someone ask me why I use Python to do the same thing I can make with PHP, the answer will be: because with Python I can make the same thing in a shorter time and, consequently, with a lower&nbsp;budget.</p>
]]></content:encoded>
			<wfw:commentRss>http://zeta-puppis.com/2008/02/21/when-the-python-vs-php-war-matters/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Django and syncdb&#8217;s signal processing</title>
		<link>http://zeta-puppis.com/2008/01/01/django-and-syncdb-signals-processing/</link>
		<comments>http://zeta-puppis.com/2008/01/01/django-and-syncdb-signals-processing/#comments</comments>
		<pubDate>Tue, 01 Jan 2008 16:56:37 +0000</pubDate>
		<dc:creator>kratorius</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[manage.py]]></category>
		<category><![CDATA[models]]></category>
		<category><![CDATA[orm]]></category>
		<category><![CDATA[setup]]></category>
		<category><![CDATA[syncdb]]></category>

		<guid isPermaLink="false">http://zeta-puppis.com/2008/01/01/django-and-syncdb-signals-processing/</guid>
		<description><![CDATA[One feature of django is worth to note is that it supports signals. In fact, under its skin it implements PyDispatcher, a python library that allows to emit signals and to dispatch&#160;them.
If at first glance this couldn&#8217;t look so useful to you, well, this hasn&#8217;t been true for me since it was exactly that kind [...]]]></description>
			<content:encoded><![CDATA[<p>One feature of django is worth to note is that it supports <b>signals</b>. In fact, under its skin it implements <a href="http://pydispatcher.sourceforge.net/">PyDispatcher</a>, a python library that allows to emit signals and to dispatch&nbsp;them.</p>
<p>If at first glance this couldn&#8217;t look so useful to you, well, this hasn&#8217;t been true for me since it was exactly that kind of stuff I was looking for. What I was trying to do was to implement some kind of auto-installer for an application that I&#8217;m writing, and in order to do so I had to run the set up after that the syncdb command is issued. So the main problem was: <b>how do I know when a user does the syncdb</b> in a non-intrusive&nbsp;way?</p>
<p>After some googling, I found that in django exists the semi-hidden feature of <b>signals</b>, so I began exploring them. The only thing you can look at on the official site is <a href="http://code.djangoproject.com/wiki/Signals">a page on their wiki</a>, and additionally there are <a href="http://feh.holsman.net/articles/2006/06/13/django-signals">some</a> <a href="http://www.mercurytide.co.uk/whitepapers/django-signals/">cool</a> <a href="http://www.martin-geber.com/weblog/2007/10/29/django-signals-vs-custom-save-method/">articles</a> over the net. Anyway, if you want to know a fast way to catch the syncdb command just follow up the&nbsp;reading.</p>
<p><span id="more-77"></span></p>
<p>First of all, let say that django looks for a file named management.py in every installed application&#8217;s directory whenever the syncdb command is ran. In this file we&#8217;ll write our management functions and <b>we&#8217;ll link those functions to django</b> through its signal&nbsp;system.</p>
<p>To do so we need to import some basic django&#8217;s&nbsp;modules:</p>
<pre><code>from django.dispatch import dispatcher
from django.db.models import signals</code></pre>
<p>With these modules we have everything to handle the django&#8217;s signals, and so here we&nbsp;go:</p>
<pre><code>dispatcher.connect(do_something_with_the_signal, signal=signals.post_syncdb, sender=model)</code></pre>
<p>With that function we <i>connect</i> our function <code>do_something_with_the_signal</code> to the django&#8217;s signal handler. A word apart has to be given to the <code>sender</code> attribute. In that way we say that our function must be called <b>only when the appropriate model gets called</b> in the syncdb&nbsp;phase.</p>
<p>The signal handling&#8217;s function must be defined as&nbsp;following:</p>
<pre><code>def do_something_with_the_signal(app, created_models, verbosity, **kwargs):</code></pre>
<p>So let describe the parameter&nbsp;list:</p>
<ul>
<li><b>app</b>: the dispatcher sender&#8217;s&nbsp;attribute</li>
<li><b>created_models</b>: a list of models that have been created with this&nbsp;syncdb</li>
<li><b>verbosity</b>: django&#8217;s verbosity&nbsp;level</li>
<li><b>kwargs</b>: a variable-length&#8217;s list of optional&nbsp;arguments</li>
</ul>
<p>Let suppose we want to create a function that inserts the <code>settings.LANGUAGES</code> list into a model (as I had to do for a little work). Here is how the code looks&nbsp;like:</p>
<pre><code>from django.conf import settings
from django.dispatch import dispatcher
from django.db.models import signals
from project.translatable import models as transmodel

def create_language_list(app, created_models, verbosity, **kwargs):
    for lang in settings.LANGUAGES:
        lcode, literal = lang

        if transmodel.Language in created_models:
            print "Adding %s (%s)..." % (literal, lcode)
            new_lang = transmodel.Language(code=lcode, name=literal)
            new_lang.save()

dispatcher.connect(create_language_list, signal=signals.post_syncdb, sender=transmodel)</code></pre>
<p>It&#8217;s worth noting here that using the <code>print</code> statement is perfectly OK (this is done by django&#8217;s auth system for example). Another thing to note is that <b>we check that our model has been created in that syncdb&#8217;s phase</b>. I do so because in this way the model is filled just the first time the model is&nbsp;created.</p>
<p>Another use of this stuff is to insert initial raw data into the model <b>by using django&#8217;s ORM</b> and not by using raw SQL. In this way we&#8217;ll be database-backend indipendent and we&#8217;ll have a transparent way to have initial data in our&nbsp;models.</p>
]]></content:encoded>
			<wfw:commentRss>http://zeta-puppis.com/2008/01/01/django-and-syncdb-signals-processing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
