<?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>tawmas.net</title> <atom:link href="http://www.tawmas.net/feed/" rel="self" type="application/rss+xml" /><link>http://www.tawmas.net</link> <description></description> <lastBuildDate>Fri, 18 Nov 2011 13:17:50 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <item><title>Unofficial daily PPA for Scribes</title><link>http://www.tawmas.net/2011-07-06/unofficial-daily-ppa-for-scribes/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=unofficial-daily-ppa-for-scribes</link> <comments>http://www.tawmas.net/2011-07-06/unofficial-daily-ppa-for-scribes/#comments</comments> <pubDate>Wed, 06 Jul 2011 22:43:10 +0000</pubDate> <dc:creator>tawmas</dc:creator> <category><![CDATA[digital life]]></category> <category><![CDATA[daily]]></category> <category><![CDATA[ppa]]></category> <category><![CDATA[scribes]]></category> <category><![CDATA[ubuntu]]></category> <guid
isPermaLink="false">http://www.tawmas.net/?p=125</guid> <description><![CDATA[When it comes to coding, Scribes is my editor of choice. So, this morning it wasn&#8217;t good news when Scribes author Lateef Alabi-Oki (Mystilleef) announced on twitter: « I haven&#8217;t found a way to build deb packages or update the Ubuntu PPA from Fedora. So Scribes&#8217; Ubuntu PPA is going to be in a rot :-( » Luckily, Launchpad provides [...]]]></description> <content:encoded><![CDATA[<p>When it comes to coding, <a
title="Scribes project on Launchpad" href="https://launchpad.net/scribes">Scribes</a> is my editor of choice. So, this morning it wasn&#8217;t good news when Scribes author Lateef Alabi-Oki (Mystilleef) <a
href="https://twitter.com/#!/mystilleef/status/88581307231244288">announced on twitter</a>: « I haven&#8217;t found a way to build deb packages or update the Ubuntu PPA from Fedora. So Scribes&#8217; Ubuntu PPA is going to be in a rot :-( »</p><p>Luckily, Launchpad provides <a
href="https://help.launchpad.net/Packaging/SourceBuilds/Recipes">build recipes</a>, an easy way to set up an automated daily build, given a source code branch and a branch with Debian packaging. Even though I have no experience with Debian packaging, I was able to make a working recipe using the official Ubuntu packaging branch and set up a PPA.</p><p>So, if you want to try out the latest and greatest Scribes, you can use my <a
title="The Unofficial daily builds of Scribes PPA on Launchpad" href="https://launchpad.net/~tawmas/+archive/scribes-unofficial-ppa/">Unofficial daily builds of Scribes</a>:</p><pre class="brush: bash; gutter: true">sudo apt-add-repository ppa:tawmas/scribes-unofficial-ppa
sudo apt-get update
sudo apt-get install scribes</pre><p>If you are upgrading from Mystilleef&#8217;s no longer maintained daily PPA, you will need to remove and reinstall Scribes, as the version numbering scheme I adopted is not compatible.</p> ]]></content:encoded> <wfw:commentRss>http://www.tawmas.net/2011-07-06/unofficial-daily-ppa-for-scribes/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Embracing class-based views</title><link>http://www.tawmas.net/2011-07-05/embracing-class-based-views/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=embracing-class-based-views</link> <comments>http://www.tawmas.net/2011-07-05/embracing-class-based-views/#comments</comments> <pubDate>Tue, 05 Jul 2011 13:56:48 +0000</pubDate> <dc:creator>tawmas</dc:creator> <category><![CDATA[coding]]></category> <category><![CDATA[class-based views]]></category> <category><![CDATA[django]]></category> <category><![CDATA[paradigms]]></category> <category><![CDATA[python]]></category> <guid
isPermaLink="false">http://www.tawmas.net/?p=93</guid> <description><![CDATA[I recently realized that class-based views are a beautiful, powerful tool to build clean, streamlined views that are easy to understand and maintain. Let me make my case with a trivial example. Let&#8217;s have a look at the canonical way to deal with a form in function-based views: def contact(request): if request.method == 'POST': # [...]]]></description> <content:encoded><![CDATA[<p>I recently realized that class-based views are a beautiful, powerful tool to build clean, streamlined views that are easy to understand and maintain.</p><p>Let me make my case with a trivial example. Let&#8217;s have a look at the canonical way to deal with a form in function-based views:</p><pre class="brush: python">def contact(request):
    if request.method == 'POST': # If the form has been submitted...
        form = ContactForm(request.POST) # A form bound to the POST data
        if form.is_valid(): # All validation rules pass
            # Process the data in form.cleaned_data
            # ...
            return HttpResponseRedirect('/thanks/') # Redirect after POST
        else:
            form = ContactForm() # An unbound form
        return render_to_response('contact.html', {'form': form,})</pre><p>What we have here is a good deal of boilerplate code, complete with an ugly nested if to deal with the submit and validation logic. Hardly the kind of style I would promote.</p><p>With class-based views, we can instead write:</p><pre class="brush: python">class Contact(FormView):
    template_name = 'contact.html'
    form_class = ContactForm
    success_url = '/thanks/'
    def form_valid(self, form):
        # Process the data in form.cleaned_data
        return super(Contact, self).form_valid(form)</pre><p>The boilerplate code has been abstracted away, we can express the easy cases in a declarative style and we can concern ourselves with just the application logic. Of course, there are more advantages than this simple example can show: pre-made views, a good deal of pre-made composable mixins and, of course, the full power of OOP.</p><p>Yet, discovering and adopting the new style is more difficult than it should be. The documentation is filled with function-based view examples that should really be ported to class-based views, and even the section on class-based view is a dump of lists with little to none information on how the details come together.</p><p>So, expect to have to dive into the source code, ask around and look for sample code (I plan to post some here in my blog as I discover things). And, if you&#8217;re a long-time Django user, or if you&#8217;re just approaching Django and you rely a lot on Google and code samples, expect to find a mismatch between old best practices and class-based views.</p><p>For example, class-based views provide an obvious means to compose view functionality: multiple inheritance and mixins. And function-based views did provide an obvious means to compose view functionality: function decorators. While class-based views do support old function decorators, when I&#8217;m using the two extensively, I&#8217;m constantly aware that I am mixing two paradigms, I&#8217;m constantly looking out for potential trouble at the intersection of the two worlds, and I&#8217;m aware that I need to make a conscious choice between the two.</p><p>Should these difficulties stop you from adopting class-based views in your current project? It depends on your context. Should these difficulties stop you from looking into adopting class-based views for your current or your next project? Not really.</p> ]]></content:encoded> <wfw:commentRss>http://www.tawmas.net/2011-07-05/embracing-class-based-views/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Perform extra work after rendering a view</title><link>http://www.tawmas.net/2011-06-06/perform-extra-work-after-rendering-a-view/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=perform-extra-work-after-rendering-a-view</link> <comments>http://www.tawmas.net/2011-06-06/perform-extra-work-after-rendering-a-view/#comments</comments> <pubDate>Mon, 06 Jun 2011 19:31:54 +0000</pubDate> <dc:creator>tawmas</dc:creator> <category><![CDATA[coding]]></category> <category><![CDATA[class-based views]]></category> <category><![CDATA[django]]></category> <category><![CDATA[python]]></category> <category><![CDATA[templateresponse]]></category> <guid
isPermaLink="false">http://www.tawmas.net/?p=72</guid> <description><![CDATA[At times, you need to perform some postprocessing after a view has been rendered. It could be some serious work, in which case you&#8217;d better arrange for it to be carried over by a separate thread, a separate process or even a separate server, or it could be just a quick update of the database. [...]]]></description> <content:encoded><![CDATA[<p>At times, you need to perform some postprocessing after a view has been rendered. It could be some serious work, in which case you&#8217;d better arrange for it to be carried over by a separate thread, a separate process or even a separate server, or it could be just a quick update of the database. In either case, you need to ensure that whatever has to be done does not influence the response.</p><p>Of course, in a manually  implemented view, rendering to the response need not be the last action. You can always write:</p><pre class="brush: python; gutter: true">def my_view(request):
    do_some_work()
    response = render_to_response('my_view.html')
    do_extra_work()
    return response</pre><p>But, when using a class-based generic view, you might be left wondering for a while, especially if you happen to focus too much on the <a
href="https://docs.djangoproject.com/en/1.3/topics/class-based-views/#performing-extra-work" target="_blank">wrong part of the documentation</a>.</p><p>Turns out that the answer is quite simple and elegant. Class-based generic views return a new kind of response introduced in Django 1.3, the <code>TemplateResponse</code>, which provides a <a
href="https://docs.djangoproject.com/en/1.3/ref/template-response/#post-render-callbacks" target="_blank">hook to perform extra work after the template has been rendered</a>. Armed with that knowledge, you can easily write a generic mixin like this:</p><pre class="brush: python; gutter: true">class PostprocessorMixin(object):
    def get(*args, **kwargs):
        resp = super(PostprocessorMixin, self).get(*args, **kwargs)
        resp.add_post_render_callback(self.postprocess)
        return resp</pre><p>When you later need to perform extra work after rendering the response, mix this in your custom derived views and implement your postprocessing in <code>postprocess</code>.</p> ]]></content:encoded> <wfw:commentRss>http://www.tawmas.net/2011-06-06/perform-extra-work-after-rendering-a-view/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Abstract base classes and backward relations</title><link>http://www.tawmas.net/2011-05-03/abstract-base-classes-and-backward-relations/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=abstract-base-classes-and-backward-relations</link> <comments>http://www.tawmas.net/2011-05-03/abstract-base-classes-and-backward-relations/#comments</comments> <pubDate>Tue, 03 May 2011 22:30:32 +0000</pubDate> <dc:creator>tawmas</dc:creator> <category><![CDATA[coding]]></category> <category><![CDATA[abstract base class]]></category> <category><![CDATA[django]]></category> <category><![CDATA[gotcha]]></category> <category><![CDATA[python]]></category> <category><![CDATA[relations]]></category> <guid
isPermaLink="false">http://www.tawmas.net/?p=45</guid> <description><![CDATA[In Django, when you create a relation using ForeignKey or a ManyToManyField, a corresponding backward relation is automatically created for you. This backward relation gets a reasonable default name. If you&#8217;d rather use a different name, you can specify one with the related_name parameter. But what if you don&#8217;t need or want the backward relation in [...]]]></description> <content:encoded><![CDATA[<p>In Django, when you create a relation using <code>ForeignKey</code> or a <code>ManyToManyField</code>, a corresponding backward relation is automatically created for you. This backward relation gets a reasonable default name. If you&#8217;d rather use a different name, you can specify one with the <code>related_name</code> parameter.</p><p>But what if you don&#8217;t need or want the backward relation in the first place? The <a
href="http://docs.djangoproject.com/en/1.3/ref/models/fields/#django.db.models.ForeignKey.related_name" target="_blank">online documentation</a> has advice to offer: « If you&#8217;d prefer Django didn&#8217;t create a backwards relation, set <tt>related_name</tt> to <tt>'+'</tt>. »</p><p>This works as advertised for plain models, but, at least in Django 1.3, it breaks with abstract base classes. The following code will not pass validation if more than one class inherits from the abstract base:</p><pre class="brush: python"># This is broken as of Django 1.3
class AbstractBaseClass(models.Model):
    readers = ForeignKey('Reader', related_name='+')
    class Meta:
        abstract = True</pre><p>The reason for the validation failure is found in the online documentation, under the very appropriate heading of <a
href="http://docs.djangoproject.com/en/1.3/topics/db/models/#abstract-related-name" target="_blank">Be careful with <code>related_name</code></a>: «If you are using the <a
title="django.db.models.ForeignKey.related_name" href="http://docs.djangoproject.com/en/1.3/ref/models/fields/#django.db.models.ForeignKey.related_name"><tt>related_name</tt></a> attribute on a <tt>ForeignKey</tt> or <tt>ManyToManyField</tt>, you must always specify a <em>unique</em> reverse name for the field. »</p><p>Clearly, something is missing, as you can either specify a unique reverse name (using the substitution tags specifically introduced for abstract base classes), or set the name to <code>'+'</code>. Some digging around reveals that any name ending in <code>+</code> will do the trick, so you can indeed specify a unique reverse name for the relation and at the same time get rid of it. The following code will pass validation:</p><pre class="brush: python"># The proper way to do it in Django 1.3
class AbstractBaseClass(models.Model):
    readers = ForeignKey('Reader',
            related_name='readable_%(app_label)s_%(class)s_set+')
    class Meta:
        abstract = True</pre><p>Of course, you should not have to come up with a unique name for a relation that you don&#8217;t want created.</p><p>Indeed, using a special value for the name of an item to signal that you don&#8217;t want the item to be created in the first place is an example of adopting a clever hack instead of proper design. A separate boolean field would not only get the job done, but it would also avoid needless programmer surprises.</p> ]]></content:encoded> <wfw:commentRss>http://www.tawmas.net/2011-05-03/abstract-base-classes-and-backward-relations/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Filtering away the Facebook Send button</title><link>http://www.tawmas.net/2011-05-02/filtering-away-the-facebook-send-button/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=filtering-away-the-facebook-send-button</link> <comments>http://www.tawmas.net/2011-05-02/filtering-away-the-facebook-send-button/#comments</comments> <pubDate>Mon, 02 May 2011 12:07:07 +0000</pubDate> <dc:creator>tawmas</dc:creator> <category><![CDATA[digital life]]></category> <category><![CDATA[browsing]]></category> <category><![CDATA[facebook]]></category> <category><![CDATA[privacy]]></category> <guid
isPermaLink="false">http://www.tawmas.net/?p=31</guid> <description><![CDATA[The recently introduced Send button, just like the original Like button, gives Facebook the ability to track the web pages you visit while being logged in to their site. Since I don&#8217;t like to surrender this kind of information, I chose to filter away the Like and Send buttons. Back when the Like button was [...]]]></description> <content:encoded><![CDATA[<p>The recently introduced Send button, just like the original Like button, gives Facebook the ability to track the web pages you visit while being logged in to their site. Since I don&#8217;t like to surrender this kind of information, I chose to filter away the Like and Send buttons.</p><p>Back when the Like button was launched, several bloggers I follow published the regular expression they used to filter it. Since none of them seems to have posted an updated regular expression to deal with the Send button as well, I&#8217;m posting mine, as a reminder to myself.</p><p><code>/https?:\/\/([^/]*)\.facebook\.com\/(plugins|widgets)\/(like|send).*</code></p><p>You can use it with Adblock or a wealth of other filtering software.</p> ]]></content:encoded> <wfw:commentRss>http://www.tawmas.net/2011-05-02/filtering-away-the-facebook-send-button/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Hello world!</title><link>http://www.tawmas.net/2011-04-24/hello-world/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=hello-world</link> <comments>http://www.tawmas.net/2011-04-24/hello-world/#comments</comments> <pubDate>Sun, 24 Apr 2011 19:43:54 +0000</pubDate> <dc:creator>tawmas</dc:creator> <category><![CDATA[meta]]></category> <category><![CDATA[chatter]]></category> <guid
isPermaLink="false">http://www.tawmas.net/?p=1</guid> <description><![CDATA[In the beginning, there is, invariably, the Hello world! post. Its well-known words caress the author more than the reader: « Welcome to WordPress. – they say in a mellow tone – This is your first post. Edit or delete it, then start blogging! » At times, it might be different. It might be some clever, or not-so-clever, attempt at mocking [...]]]></description> <content:encoded><![CDATA[<p>In the beginning, there is, invariably, the <em>Hello world!</em> post. Its well-known words caress the author more than the reader: « Welcome to WordPress. – they say in a mellow tone – This is your first post. Edit or delete it, then start blogging! »</p><p>At times, it might be different. It might be some clever, or not-so-clever, attempt at mocking the stock <em>Hello world!</em> post.</p><p>Either way, some text is written, the first step is done, a journey begins…</p> ]]></content:encoded> <wfw:commentRss>http://www.tawmas.net/2011-04-24/hello-world/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> </channel> </rss>
