<?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>Psychic Origami &#187; Django</title>
	<atom:link href="http://www.psychicorigami.com/category/django/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.psychicorigami.com</link>
	<description>folding with my brain</description>
	<lastBuildDate>Wed, 03 Aug 2011 19:13:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Django User Profiles and select_related optimisation</title>
		<link>http://www.psychicorigami.com/2011/02/12/django-user-profiles-and-select_related-optimisation/</link>
		<comments>http://www.psychicorigami.com/2011/02/12/django-user-profiles-and-select_related-optimisation/#comments</comments>
		<pubDate>Sat, 12 Feb 2011 19:01:03 +0000</pubDate>
		<dc:creator>john</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.psychicorigami.com/?p=416</guid>
		<description><![CDATA[If you want to associate extra information with a user account in Django you need to create a separate &#8220;User Profile&#8221; model. To get the profile for a given User object one simply calls get_profile. This is a nice easy way of handling things and helps keep the User model in Django simple. However it [...]]]></description>
			<content:encoded><![CDATA[<p>If you want to associate extra information with a user account in Django you need to create <a href="http://docs.djangoproject.com/en/dev/topics/auth/#storing-additional-information-about-users">a separate &#8220;User Profile&#8221; model</a>.  To get the profile for a given User object one simply calls <a href="http://docs.djangoproject.com/en/dev/topics/auth/#django.contrib.auth.models.User.get_profile">get_profile</a>.  This is a nice easy way of handling things and helps keep the User model in Django simple.  However it does have a downside &#8211; fetching the user and user profile requires two database queries.  That&#8217;s not so bad when we&#8217;re selecting just one user and profile, but when we are displaying a list of users we&#8217;d end up doing one query for the users and another n-queries for the profiles &#8211; the classic <a href="http://www.pbell.com/index.cfm/2006/9/17/Understanding-the-n1-query-problem">n+1 query problem</a>!</p>
<p>To reduce the number of queries to just one we can use <a href="http://docs.djangoproject.com/en/dev/ref/models/querysets/#select-related">select_related</a>.  Prior to Django 1.2 <code>select_related</code> did not support the reverse direction of a <code>OneToOneField</code>, so we couldn&#8217;t actually use it with the user and user profile models.  Luckily that&#8217;s no longer a problem.</p>
<p>If we are clever we can setup the user profile so it stills works with <code>get_profile</code> and does not create an extra query.</p>
<p><code>get_profile</code> looks like this:</p>
<pre><code>
def get_profile(self):
        if not hasattr(self, '_profile_cache'):
            # ...
            # query to get profile and store it in _profile_cache on instance
            # so we don't need to look it up again later
            # ...
        return self._profile_cache
</code></pre>
<p>So if <code>select_related</code> stores the profile object in <code>_profile_cache</code> then <code>get_profile</code> will not need to do any more querying.</p>
<p>To do this we&#8217;d define the user profile model like this:</p>
<pre><code>
class UserProfile(models.Model):
    user = models.OneToOneField(User, related_name='_profile_cache')
    # ...
    # other model fields
    # ...
</code></pre>
<p>The key thing is that we have set <code>related_name</code> on the <code>OneToOneField</code> to be <code>'_profile_cache'</code>.  The <code>related_name</code> defines the attribute on the *other* model (User in this case) and is what we need to refer to when we use <code>select_related</code>.</p>
<p>Querying for all user instances and user profiles at the same time would look like:</p>
<pre><code>
User.objects.selected_related('_profile_cache')
</code></pre>
<p>The only downside is that this does change the behaviour of <code>get_profile</code> slightly.  Previously if no profile existed for a given user a <code>DoesNotExist</code> exception is raised.  With this approach <code>get_profile</code> instead returns <code>None</code>.  So you&#8217;re code will need to handle this.  On the upside repeated calls to <code>get_profile</code>, when no profile exists, won&#8217;t re-query the database.</p>
<p>The other minor problem is that we are relying on the name of a private attribute on the User model (that little pesky underscore indicates it&#8217;s not officially for public consumption).  Theoretically the attribute name could change in a future version of Django.  To mitigate against the name changing I&#8217;d personally just store the name in a variable or on the profile model as a class attribute and reference that whenever you need it, so at least there&#8217;s only one place to make any change.  Apart from that this only requires a minor modification to your user profile model and the use of <code>select_related</code>, so it&#8217;s not a massively invasive optimisation.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.psychicorigami.com/2011/02/12/django-user-profiles-and-select_related-optimisation/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Django Batch Select</title>
		<link>http://www.psychicorigami.com/2009/11/23/django-batch-select/</link>
		<comments>http://www.psychicorigami.com/2009/11/23/django-batch-select/#comments</comments>
		<pubDate>Mon, 23 Nov 2009 10:00:00 +0000</pubDate>
		<dc:creator>john</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://www.psychicorigami.com/?p=228</guid>
		<description><![CDATA[So quite a while ago I wrote about avoiding the n+1 query problem with SQLObject. I&#8217;ve since been using Django a lot more. In particular at my day job I&#8217;ve been improving a Django site we&#8217;ve inherited. This particular site suffered from a few too many SQL queries and needed speeding up. Some of the [...]]]></description>
			<content:encoded><![CDATA[<p>So quite a while ago I wrote about <a href="http://www.psychicorigami.com/2007/12/16/using-raw-sql-with-sqlobject-and-keeping-the-object-y-goodness/">avoiding the n+1 query problem with SQLObject</a>.  I&#8217;ve since been using <a href="http://www.djangoproject.com/">Django</a> a lot more.  In particular at <a href="http://www.sensibledevelopment.com/">my day job</a> I&#8217;ve been improving a Django site we&#8217;ve inherited.  This particular site suffered from a few too many SQL queries and needed speeding up.  Some of the issues related to the classic n+1 problem.  i.e. one initial query triggering a further n queries (where n is the number of results in the first query).</p>
<p>A liberal dose of <a href="http://docs.djangoproject.com/en/dev/ref/models/querysets/#id4">select_related</a> helped.  However that was only useful in the cases where a ForeignKey needed to be pre-fetched.</p>
<p>In the case however there was a page that was selecting a set of objects that had tags.  The tags for each object were being displayed along side a link to the main object.  Given that the initial query returned over three hundred objects, this meant the page was performing another three hundred (plus) queries to fetch the individual tags for each object!  Now we could cache the page and that&#8217;s was indeed what was being done.  The trouble however was when the cache expired.  It also made things painful when developing &#8211; as I&#8217;d typically want to disable caching whilst I&#8217;m making changes to pages frequently.</p>
<p>I came up with a specific solution for this project &#8211; to perform the initial query, then a second query to fetch *all* of the other tags in one go.  The results of the second query could then be stitched into the original results, to make them available in a handy manor within the page&#8217;s template.</p>
<p>I took the original idea and made it re-usable and am now releasing that code as <a href="http://github.com/lilspikey/django-batch-select">Django Batch Select</a>.  There are examples of how to use it over at <a href="http://github.com/lilspikey/django-batch-select">github</a>, but it works a bit like this:</p>
<pre><code>
&gt;&gt;&gt; entries = Entry.objects.batch_select('tags').all()
&gt;&gt;&gt; entry = entries[0]
&gt;&gt;&gt; print entry.tags_all
[&lt;Tag: Tag object&gt;]
</code></pre>
<p>It&#8217;s a very early release &#8211; after the result of only a few hours coding, so use with care.  It does have 100% test code coverage at the moment and I&#8217;m reasonable confident about it working.  Please try it out and let me know whether it works for you.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.psychicorigami.com/2009/11/23/django-batch-select/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Django simple admin ImageField thumbnail</title>
		<link>http://www.psychicorigami.com/2009/06/20/django-simple-admin-imagefield-thumbnail/</link>
		<comments>http://www.psychicorigami.com/2009/06/20/django-simple-admin-imagefield-thumbnail/#comments</comments>
		<pubDate>Sat, 20 Jun 2009 11:11:00 +0000</pubDate>
		<dc:creator>john</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.psychicorigami.com/?p=168</guid>
		<description><![CDATA[The Django admin site is one of the best features of Django. It really lets you just get on with building your app, without having to worry too much about how you&#8217;ll administer your site. The defaults are generally pretty good, but it&#8217;s often the case that you&#8217;ll want to tweak and change it (particularly [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://www.djangoproject.com/">Django</a> admin site is one of the best features of Django.  It really lets you just get on with building your app, without having to worry too much about how you&#8217;ll administer your site.</p>
<p>The defaults are generally pretty good, but it&#8217;s often the case that you&#8217;ll want to tweak and change it (particularly when you have clients involved).  Luckily it&#8217;s pretty easy to customize.</p>
<p>One common change that many people will want to do is to display a thumbnail of an uploaded image in the admin.  The default image field (when an image has been uploaded) in the admin looks like:</p>
<p><img class="alignnone size-full wp-image-169" title="image_field1" src="http://www.psychicorigami.com/wp-content/uploads/2009/06/image_field1.jpg" alt="image_field1" width="331" height="44" /></p>
<p>and we want to change it to look like this:</p>
<p><img class="alignnone size-full wp-image-170" title="image_field2" src="http://www.psychicorigami.com/wp-content/uploads/2009/06/image_field2.jpg" alt="image_field2" width="257" height="77" /></p>
<p>In my case I had images that I knew would be fairly small so I didn&#8217;t need to use any auto-resizing or anything like that.  I found <a href="http://www.djangosnippets.org/snippets/934/">this snippet</a> for doing the same task, but decided to simplify it a fair bit and ended up with:</p>
<pre><code>
from django.contrib.admin.widgets import AdminFileWidget
from django.utils.translation import ugettext as _
from django.utils.safestring import mark_safe

class AdminImageWidget(AdminFileWidget):
    def render(self, name, value, attrs=None):
        output = []
        if value and getattr(value, "url", None):
            image_url = value.url
            file_name=str(value)
            output.append(u' &lt;a href="%s" target="_blank"&gt;&lt;img src="%s" alt="%s" /&gt;&lt;/a&gt; %s ' % \
                (image_url, image_url, file_name, _('Change:')))
        output.append(super(AdminFileWidget, self).render(name, value, attrs))
        return mark_safe(u''.join(output))
</code></pre>
<p>Then to use it I simply override <code>formfield_for_dbfield</code> to return a field that uses that widget for the field I&#8217;m interested in:</p>
<pre><code>
class MyAdmin(admin.ModelAdmin):
    def formfield_for_dbfield(self, db_field, **kwargs):
        if db_field.name == 'profile_image':
            request = kwargs.pop("request", None)
            kwargs['widget'] = AdminImageWidget
            return db_field.formfield(**kwargs)
        return super(MyAdmin,self).formfield_for_dbfield(db_field, **kwargs)
</code></pre>
<p>It&#8217;s a fairly straightforward alteration to how the <code>ImageField</code> widget renders in the admin, but it is often a big help to be able to actually see the image in question.</p>
<p>UPDATED: Feb 24th, 2010.  Based on Jeremy&#8217;s comment below and having upgraded to Django 1.1 I&#8217;ve modified this example to remove the &#8220;request&#8221; param from kwargs before passing it db_field.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.psychicorigami.com/2009/06/20/django-simple-admin-imagefield-thumbnail/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
	</channel>
</rss>

