<?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>Alexis Petrounias</title>
	<atom:link href="http://www.petrounias.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.petrounias.org</link>
	<description>Information Systems Engineer, Athens and Thessaloniki, Greece</description>
	<lastBuildDate>Mon, 17 Jun 2013 23:32:46 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Django application import and missed class_prepared signals.</title>
		<link>http://www.petrounias.org/articles/2011/08/11/django-application-import-and-missed-class_prepared-signals/</link>
		<comments>http://www.petrounias.org/articles/2011/08/11/django-application-import-and-missed-class_prepared-signals/#comments</comments>
		<pubDate>Thu, 11 Aug 2011 10:17:43 +0000</pubDate>
		<dc:creator>Alexis Petrounias</dc:creator>
				<category><![CDATA[Django]]></category>

		<guid isPermaLink="false">http://www.petrounias.org/?p=368</guid>
		<description><![CDATA[Due to opaque application loading semantics within the Django i18n code, several model classes may be imported before a class_prepared signal listener connects, resulting in missing the signal entirely. Specifically, connecting to this signal from an application which appears first in INSTALLED_APPS, does not guarantee that it will execute when a class is first imported [...]]]></description>
				<content:encoded><![CDATA[<p>Due to opaque application loading semantics within the Django i18n code, several model classes may be imported before a <code>class_prepared</code> signal listener connects, resulting in missing the signal entirely. Specifically, connecting to this signal from an application which appears <em>first</em> in <code>INSTALLED_APPS</code>, does not guarantee that it will execute when a class is first imported by any of the subsequent applications.</p>
<p><em>This problem is current as of Django 1.3 and has no generic solution as far as I know.</em><br />
<span id="more-368"></span></p>
<p>A <code>class_prepared</code> signal is dispatched when the model class is instantiated for the first time; this happens inside class Model&#8217;s metaclass at <code>django.db.models.base</code>: 257:</p>
<pre class="brush: python">        signals.class_prepared.send(sender=cls)</pre>
<p>Therefore, we would expect that connecting to this signal from the <code>__init__.py</code> of an app which appears <em>first</em> in the <code>INSTALLED_APPS</code> list, would ensure that our listener receives the signal for all Models loaded in the remainder apps (following is the beginning of a typical such list):</p>
<pre class="brush: python">INSTALLED_APPS = (
  'class_prepared_listener_app',
  'django.contrib.auth',
  'django.contrib.contenttypes',
  'django.contrib.sessions',
  'django.contrib.sites',
  'django.contrib.messages',
  'django.contrib.admin',
  ...
)</pre>
<p>However, this is not (always) the case. Tracing, for example, shell execution, we find that <code>django.core.management.commands.shell</code>: 45:</p>
<pre class="brush: python">from django.db.models.loading import get_models
loaded_models = get_models()</pre>
<p>requests all models from the app cache which first calls <code>_populate</code> to initialize itself at <code>django.db.models.loading</code>: 167:</p>
<pre class="brush: python">self._populate()</pre>
<p>which loads all apps into the cache the first time it&#8217;s called and does nothing for subsequent calls at <code>django.db.models.loading</code>: 58:</p>
<pre class="brush: python">            for app_name in settings.INSTALLED_APPS:
                if app_name in self.handled:
                    continue
                self.load_app(app_name, True)
            if not self.nesting_level:
                for app_name in self.postponed:
                    self.load_app(app_name)
                self.loaded = True</pre>
<p>The apps are loaded in <code>_populate</code> in the order they&#8217;re listed in <code>INSTALLED_APPS</code>; some apps can be postponed though if they can&#8217;t be imported at the time of traversal at <code>django.db.models.loading</code>: 77:</p>
<pre class="brush: python">        try:
            models = import_module('.models', app_name)
        except ImportError:
            self.nesting_level -= 1
            # If the app doesn't have a models module, we can just ignore the
            # ImportError and return no models for it.
            if not module_has_submodule(app_module, 'models'):
                return None
            # But if the app does have a models module, we need to figure out
            # whether to suppress or propagate the error. If can_postpone is
            # True then it may be that the package is still being imported by
            # Python and the models module isn't available yet. So we add the
            # app to the postponed list and we'll try it again after all the
            # recursion has finished (in populate). If can_postpone is False
            # then it's time to raise the ImportError.
            else:
                if can_postpone:
                    self.postponed.append(app_name)
                    return None
                else:
                    raise</pre>
<p>A print statement in <code>_populate</code> indicates that no apps are postponed and that all apps are, in fact, loaded in sequence. Furthermore the signal gets connected before any other apps are loaded. The output of <code>manage.py shell</code> with several print statements:</p>
<p><code>Signal connected.<br />
class_prepared_listener_app<br />
django.contrib.auth<br />
django.contrib.contenttypes<br />
django.contrib.sessions<br />
django.contrib.sites<br />
django.contrib.messages<br />
django.contrib.admin<br />
...</code></p>
<p>Adding a print statement in the Model&#8217;s metaclass indicates that some classes are instantiated before their owner apps are loaded:</p>
<p><code>Preparing class 'django.contrib.contenttypes.models.ContentType'<br />
Preparing class 'django.contrib.auth.models.Permission'<br />
Preparing class 'django.contrib.auth.models.Group_permissions'<br />
Preparing class 'django.contrib.auth.models.Group'<br />
Preparing class 'django.contrib.auth.models.User_user_permissions'<br />
Preparing class 'django.contrib.auth.models.User_groups'<br />
Preparing class 'django.contrib.auth.models.User'<br />
Preparing class 'django.contrib.auth.models.Message'<br />
Preparing class 'django.contrib.sites.models.Site'<br />
Signal connected.<br />
Preparing class 'django.contrib.sessions.models.Session'<br />
Preparing class 'django.contrib.admin.models.LogEntry'<br />
...</code></p>
<p>Further snooping shows that these classes are instantiated by translation-related preparation code, before the shell command is properly handled, at <code>django.core.management.base</code>: 202:</p>
<pre class="brush: python">        # Switch to English, because django-admin.py creates database content
        # like permissions, and those shouldn't contain any translations.
        # But only do this if we can assume we have a working settings file,
        # because django.utils.translation requires settings.
        if self.can_import_settings:
            try:
                from django.utils import translation
                translation.activate('en-us')</pre>
<p>Models are instantiated inside the last call to <code>activate()</code> which eventually calls <code>translation()</code> at <code>django.utils.translation.trans_real</code>: 161:</p>
<pre class="brush: python">        for appname in reversed(settings.INSTALLED_APPS):
            app = import_module(appname)
            apppath = os.path.join(os.path.dirname(app.__file__), 'locale')

            if os.path.isdir(apppath):
                res = _merge(apppath)</pre>
<p>From the above, it is straightforward to see that by removing the admin and auth apps, or by placing our app <em>after</em> the admin and auth apps, our signal connects before any Models are loaded. Neither of these two &#8220;solutions&#8221; however appear robust or welcome.</p>
<p>It should be noted that, because the call to <code>translation.activate()</code> is being made inside the execute method of the base class from which all management commands derive, this behaviour is to be expected when Django starts up through commands other than shell.</p>
<p>Admittedly, the official Django documentation for this signal <a href="https://docs.djangoproject.com/en/dev/ref/signals/#class-prepared">states</a> &#8220;Django uses this signal internally; it&#8217;s not generally used in third-party applications.&#8221; however, I strongly feel that Django would benefit from a formal and deterministic load order for <code>INSTALLED_APPS</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.petrounias.org/articles/2011/08/11/django-application-import-and-missed-class_prepared-signals/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Propagating field changes in Django Model instance aliases</title>
		<link>http://www.petrounias.org/articles/2010/04/05/propagating-field-changes-in-django-model-instance-aliases/</link>
		<comments>http://www.petrounias.org/articles/2010/04/05/propagating-field-changes-in-django-model-instance-aliases/#comments</comments>
		<pubDate>Mon, 05 Apr 2010 10:11:23 +0000</pubDate>
		<dc:creator>Alexis Petrounias</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[alias]]></category>

		<guid isPermaLink="false">http://www.petrounias.org/?p=279</guid>
		<description><![CDATA[Django&#8217;s ORM creates multiple aliases for the same Model instance. In certain situations this may result in problematic behavior, as multiple operations on the same instance are interleaved, however, field access happens on different aliases of the instance, ultimately resulting in loss of updates. For instance, consider the following two Models: class A(Model): pass class [...]]]></description>
				<content:encoded><![CDATA[<p>Django&#8217;s ORM creates multiple aliases for the same Model instance. In certain situations this may result in problematic behavior, as multiple operations on the same instance are interleaved, however, field access happens on different <em>aliases</em> of the instance, ultimately resulting in loss of updates.<span id="more-279"></span></p>
<p>For instance, consider the following two Models:</p>
<pre class="brush: python">class A(Model):
    pass

class B(Model):

    a = OneToOneField(A)

    value = IntegerField()

    def __unicode__(self):
        return str(self.value)</pre>
<p>And the following sequence of statements:</p>
<pre class="brush: python">&gt;&gt;&gt; a = A.objects.create()
&gt;&gt;&gt; b = B.objects.create(a = a, value = 69)
&gt;&gt;&gt; b.value
69
&gt;&gt;&gt; a.b.value
69
&gt;&gt;&gt; b.value = 42
&gt;&gt;&gt; b.save()
&gt;&gt;&gt; b.value
42
&gt;&gt;&gt; a.b.value
69</pre>
<p>Clearly, the two instances of <strong>B</strong> are different objects, and updating one has no effect on the rest, as witnessed by the different values on lines 10 and 12.</p>
<p>It is possible to automatically propagate field changes to all aliases of a Model by (a) keeping track of aliases, and (b) propagating upon assignment. Assuming you have a list of all aliases of a Model instance (see below), then field changes from a <em>reference</em> alias to all the remainder <em>target</em> aliases can be achieved in the following straightforward way.</p>
<pre class="brush: python">def propagate_field_update(reference, field_name, targets):
    value = getattr(reference, field_name)

    for target in targets:
        setattr(target, field_name, value)</pre>
<p>Another option is to update all fields together (for instance, after a save signal, as done below); this can be achieved in the following way.</p>
<pre class="brush: python">def propagate_field_updates(reference, targets):

    mapping = [(f.attname, getattr(reference, f.attname)) for \
        f in reference._meta.fields]

    for target in targets:
        for (f_attname, v) in mapping:
            setattr(target, f_attname, v)</pre>
<p>Note, however, that updates to fields which are not handled through Django&#8217;s Model fields will not be captured using the above technique.</p>
<p>The following mini-framework uses post initialization and post save signal listeners to maintain weak references of aliases, as well as propagates field changes to all aliases using post save and post delete signals.</p>
<pre class="brush: python">from django.db.models.signals import post_init, post_save, post_delete
from collections import defaultdict
from weakref import WeakValueDictionary

MODEL_INSTANCES_ALIASES = defaultdict(WeakValueDictionary)

def record_alias(sender, instance, **kwargs):
    """ Keeps a weak reference to all aliases of a Model instance, using the
        class and primary key as a key to a default dictionary of weak value
        dictionary entries, which in turn use the id of aliases mapped to weak
        references to the aliases themselves, in the following manner:

        { (Class, PK) : { id : instance, id : instance, ... }, ... }

        Recording will happen post initialization, but also post save in the
        event that a Model instance is created directly from a class (and not
        the create Manager method), and hence does not yet feature a primary
        key.
    """

    if instance.pk is not None:
        aliases = MODEL_INSTANCES_ALIASES[(sender, instance.pk)]
        if not aliases.has_key(id(instance)):
            aliases[id(instance)] = instance

post_init.connect(record_alias)
post_save.connect(record_alias)

def propagate_updates_to_aliases(sender, instance, **kwargs):
    """ Propagates all field values of a given Model instance to all its aliases
        post save and delete. Can also be invoked explicitly, or used in a
        decorator for methods which update fields.
    """

    mapping = [(f.attname, getattr(instance, f.attname)) for \
        f in instance._meta.fields]

    # Propagate field values to all aliases.
    for target in MODEL_INSTANCES_ALIASES[
        (instance.__class__, instance.pk)].itervalues():
        # Ignore the given instance.
        if not id(target) == id(instance):
            for (f_attname, v) in mapping:
                setattr(target, f_attname, v)

post_save.connect(propagate_updates_to_aliases)
post_delete.connect(propagate_updates_to_aliases)</pre>
<p>Using the above technique, the example becomes as follows.</p>
<pre class="brush: python">&gt;&gt;&gt; a = A.objects.create()
&gt;&gt;&gt; b = B.objects.create(a = a, value = 69)
&gt;&gt;&gt; b.value
69
&gt;&gt;&gt; a.b.value
69
&gt;&gt;&gt; b.value = 42
&gt;&gt;&gt; b.save()
&gt;&gt;&gt; b.value
42
&gt;&gt;&gt; a.b.value
42</pre>
<p>Which demonstrates that the two aliases have consistent field values.</p>
<p>I&#8217;m currently experimenting with a mini-framework for propagating field updates as they happen. I am also planning on determining the kind of performance and memory impact this has on realistic Django production code; more updates in the future.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.petrounias.org/articles/2010/04/05/propagating-field-changes-in-django-model-instance-aliases/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Capturing invoking method information in Python</title>
		<link>http://www.petrounias.org/articles/2010/03/16/capturing-invoking-method-information-in-python/</link>
		<comments>http://www.petrounias.org/articles/2010/03/16/capturing-invoking-method-information-in-python/#comments</comments>
		<pubDate>Tue, 16 Mar 2010 11:04:37 +0000</pubDate>
		<dc:creator>Alexis Petrounias</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[inspect]]></category>
		<category><![CDATA[invoker]]></category>
		<category><![CDATA[method]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[stack frame]]></category>

		<guid isPermaLink="false">http://www.petrounias.org/?p=296</guid>
		<description><![CDATA[The following decorator will capture all available information regarding the method which invokes the decorated method (the invoked method).The available information consists of the following: the instance object of the invoker (the subject), the name of the method (the name), and the invocation frame in the current stack (the frame). This information is passed to [...]]]></description>
				<content:encoded><![CDATA[<p>The following decorator will capture all available information regarding the method which invokes the decorated method (the invoked method).<span id="more-296"></span>The available information consists of the following:</p>
<ol>
<li>the instance object of the invoker (the subject),</li>
<li>the name of the method (the name), and</li>
<li>the invocation frame in the current stack (the frame).</li>
</ol>
<p>This information is passed to the invoked method through a keyword argument, by default <strong>_invoker_info</strong>, which can be overridden through the <strong>name</strong> argument to the decorator.</p>
<pre class="brush: python">import inspect

from functools import partial, wraps

def capture_invoking_method_info(name = '_invoker_info'):
    """ Decorator which captures invoking method information and places it in
        the keyword arguments of the decorated method, by default as the keyword
        argument '_invoker_info' which can be set via the 'name' argument. The
        information captured consists of the subject (who contains the method
        which is invoking), the invoking method name, and the stack frame of the
        invocation.
    """

    def _capture_controller(wrapped_method):

        def _capture_controlled(*m_args, **m_kwargs):

            frame = inspect.currentframe().f_back

            # If the invocation is from the shell, or the invoker frame's
            # locals are missing, the subject becomes None.
            if len(frame.f_code.co_varnames) &gt; 0:

                subject = frame.f_locals[frame.f_code.co_varnames[0]]

            else:

                subject = None

            m_kwargs[name] = (subject, frame.f_code.co_name, frame)

            return wrapped_method(*m_args, **m_kwargs)

        return wraps(wrapped_method)(_capture_controlled)

    return partial(_capture_controller)</pre>
<p>The following example demonstrates its use. Assume a class <strong>A</strong> which defines two methods, <strong>x</strong> and <strong>y</strong>, where <strong>x</strong> invokes <strong>y</strong>, and <strong>y</strong> is decorated with the above decorator.</p>
<pre class="brush: python">class A(object):

  def x(self):
    return self.y()

  @capture_invoking_method_info()
  def y(self, _invoker_info):
    return _invoker_info

class B(A):
  pass</pre>
<p>An instance object b of class <strong>B</strong> will return the following captured information tuple when its <strong>x</strong> method is invoked:</p>
<pre class="brush: python">&gt;&gt;&gt; b.x()
(&lt;__main__.B object at 0x10162ee90&gt;, 'x', &lt;frame object at 0x101560090&gt;)</pre>
<p>And, since we are in the interactive python shell, the same object <strong>b</strong> will return the following captured information tuple when its <strong>y</strong> method is invoked:</p>
<pre class="brush: python">&gt;&gt;&gt; b.y()
(None, '&lt;module&gt;', &lt;frame object at 0x101562750&gt;)</pre>
<p>Obviously, the subject here is <strong>None</strong>, as the invocation was performed from the shell and not another instance object.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.petrounias.org/articles/2010/03/16/capturing-invoking-method-information-in-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ordering on a field in the &#8216;through&#8217; Model of a recursive ManyToMany relation in Django</title>
		<link>http://www.petrounias.org/articles/2010/02/06/ordering-on-a-field-in-the-through-model-of-a-recursive-manytomany-relation-in-django/</link>
		<comments>http://www.petrounias.org/articles/2010/02/06/ordering-on-a-field-in-the-through-model-of-a-recursive-manytomany-relation-in-django/#comments</comments>
		<pubDate>Sat, 06 Feb 2010 13:11:52 +0000</pubDate>
		<dc:creator>Alexis Petrounias</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[manytomany]]></category>
		<category><![CDATA[ordering]]></category>
		<category><![CDATA[recursive relation]]></category>
		<category><![CDATA[through]]></category>

		<guid isPermaLink="false">http://new.petrounias.org/?p=101</guid>
		<description><![CDATA[It is not possible to order a Model on a field of the Model acting as the intermediate &#8216;through&#8216; of a ManyToMany relation in Django, because queries will not return items in the correct order, and in addition will include duplicate items, even when using .distinct(). This problem is current as of Django 1.3 and [...]]]></description>
				<content:encoded><![CDATA[<p>It is not possible to order a <strong>Model</strong> on a field of the <strong>Model</strong> acting as the intermediate &#8216;<strong>through</strong>&#8216; of a ManyToMany relation in <a href="http://www.djangoproject.com/">Django</a>, because queries will not return items in the correct order, and in addition will include duplicate items, even when using <strong>.distinct()</strong>.</p>
<p><em>This problem is current as of Django 1.3 and has no generic solution as far as I know.</em></p>
<p><span id="more-101"></span>Assuming the following <strong>Model</strong>:</p>
<pre class="brush: python">class Category(models.Model):

    related = models.ManyToManyField('self', symmetrical = False, \
        through = 'CategoryRelation', null = True, blank = True)</pre>
<p>Assuming the following intermediate &#8216;<strong>through</strong>&#8216; relation:</p>
<pre class="brush: python">class CategoryRelation(models.Model):

    source = models.ForeignKey('Category', null = False, blank = False, \
        related_name = 'relation_source')

    target = models.ForeignKey('Category', null = False, blank = False, \
        related_name = 'relation_target')

    order = models.PositiveIntegerField(_('order'), default = 0, \
        null = False, blank = True)

    class Meta:
        ordering = ( 'order', )</pre>
<p>How can we obtain the <strong>Category</strong> objects related to a given <strong>Category</strong> while preserving their ordering? The following code will produce the correct <strong>Category</strong> objects, not in the correct order, and include duplicate entries in the Query Set even when using <strong>.distinct()</strong>:</p>
<pre class="brush: python">relations = CategoryRelation.objects.filter(source = self)

Category.objects.filter(relation_target__in = relations).order_by('related')</pre>
<p>The following works for ordering correctly, but does not leave out duplicate entries:</p>
<pre class="brush: python">relations = CategoryRelation.objects.filter(source = self)

Category.objects.filter(relation_target__in = relations).order_by('relation_target')</pre>
<p>Calling <strong>.distinct()</strong> will not make a difference, because <strong>.order_by(&#8230;)</strong> is applied by the ORM after the SQL <strong>SELECT DISTINCT</strong> clause is built. However, it is possible &#8211; in this case &#8211; to exploit the fact that the order is a positive integer field, and annotate each <strong>Category</strong> with the <strong>Min</strong> value of the order field of the <strong>relation_target</strong> field, and use this new annotation field for ordering:</p>
<pre class="brush: python">return Category.objects.filter(relation_target__in = relations).annotate(
    relation_target_order = models.Min('relation_target__order')).order_by(
        'relation_target_order')</pre>
<p>This is almost complete, but since the semantics of this query essentially make it unique, it would be wise to call <strong>.distinct()</strong> just to make sure the distinct flag is <em>True</em> so that later combinations with other distinct queries can take place:</p>
<pre class="brush: python">return Category.objects.filter(relation_target__in = relations).annotate(
    relation_target_order =models.Min('relation_target__order')).order_by(
        'relation_target_order').distinct()</pre>
<p>In this case <strong>.distinct()</strong> does not affect the query in the slightest, but ensures that <em>db/models/sql/query.py</em> method <strong>combine(self, rhs, connector)</strong> passes its assertion:</p>
<pre class="brush: python">assert self.distinct == rhs.distinct, \ ...</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.petrounias.org/articles/2010/02/06/ordering-on-a-field-in-the-through-model-of-a-recursive-manytomany-relation-in-django/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Duplicate items when ordering by Generic Relation in Django</title>
		<link>http://www.petrounias.org/articles/2010/01/27/duplicate-items-when-ordering-by-generic-relation-in-django/</link>
		<comments>http://www.petrounias.org/articles/2010/01/27/duplicate-items-when-ordering-by-generic-relation-in-django/#comments</comments>
		<pubDate>Wed, 27 Jan 2010 08:50:50 +0000</pubDate>
		<dc:creator>Alexis Petrounias</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[content types]]></category>
		<category><![CDATA[generic relation]]></category>
		<category><![CDATA[ordering]]></category>

		<guid isPermaLink="false">http:/?p=1</guid>
		<description><![CDATA[When the optional ordering = &#8230; attribute of a model&#8217;s Meta class contains a GenericRelation from the Content Types framework in Django, there is no way to eliminate duplicate items being returned, even when using .distinct() (since .order_by(&#8230;) is applied by the ORM only after the SQL SELECT DISTINCT clause is built). This problem is [...]]]></description>
				<content:encoded><![CDATA[<p>When the optional <strong>ordering = &#8230;</strong> attribute of a model&#8217;s <strong>Meta</strong> class contains a <strong>GenericRelation</strong> from the <a href="http://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/">Content Types</a> framework in <a href="http://www.djangoproject.com/">Django</a>, there is no way to eliminate duplicate items being returned, even when using <strong>.distinct()</strong> (since <strong>.order_by(&#8230;)</strong> is applied by the ORM only after the SQL <strong>SELECT DISTINCT</strong> clause is built).</p>
<p><em>This problem is current as of Django 1.3 and has no generic solution as far as I know.</em></p>
<p><span id="more-1"></span>This problem will manifest when two or more different Models instances are attached to instances of the Model with the Generic Foreign Key. In the following example, we have Model <strong>X</strong> which has a Generic Foreign Key, and two Models, <strong>Y</strong> and <strong>Z,</strong> which have Generic Relations to <strong>X</strong> and ordering based on these relations.</p>
<pre class="brush: python">from django.db.models import CharField

from django.contrib.contenttypes.models import ContentType

from django.contrib.contenttypes.generic import GenericForeignKey, GenericRelation</pre>
<pre class="brush: python">class X(Model):
    """ This Model has a unique name and is attached to another Model through a
        Generic relation.
    """

    # The unique name of this X.
    name = CharField(u'name', unique = True, max_length = 128, null = False)

    # The Content Type of the generic relation to the attached content.
    content_type = models.ForeignKey(ContentType, null = True, blank = True,
        related_name = 'x_contents')

    # The ID of the attached content.
    content_id = models.PositiveIntegerField(null = True, blank = True)

    # The attached content.
    content = GenericForeignKey('content_type', 'content_id')

    def __unicode__(self):
        """ The textual representation of this Model is its name.
        """

        return self.name

    class Meta:

        app_label = 'cmf'

        # Order by X's name.
        ordering = ['name', ]</pre>
<pre class="brush: python">class Y(Model):
    """ This Model acts as content for an X, and has a convenient reverse
        Generic Relation to X.
    """

    # The unique name of this Y.
    name = CharField(u'name', unique = True, max_length = 128, null = False)

    # The X this Y is attached to.
    xs = GenericRelation(X, content_type_field = 'content_type',
        object_id_field = 'content_id')

    def __unicode__(self):
        """ The textual representation of this Model is its name.
        """

        return self.name

    class Meta:

        # Order by X's name.
        ordering = ['xs__name', ]</pre>
<pre class="brush: py">class Z(Model):
    """ This Model acts as content for an X, and has a convenient reverse
        Generic Relation to X.
    """

    # The unique name of this Z.
    name = CharField(u'name', unique = True, max_length = 128, null = False)

    # The X this Z is attached to.
    xs = GenericRelation(X, content_type_field = 'content_type',
        object_id_field = 'content_id')

    def __unicode__(self):
        """ The textual representation of this Model is its name.
        """

        return self.name

    class Meta:

        app_label = 'cmf'

        # Order by X's name.
        ordering = ['xs__name', ]</pre>
<p>The following sequence of statements demonstrates this problem:</p>
<pre class="brush: python">x1 = X.objects.create(name = 'first x')
x2 = X.objects.create(name = 'second x')
x3 = X.objects.create(name = 'third x')
x4 = X.objects.create(name = 'fourth x')
y1 = Y.objects.create(name = 'first y')
y2 = Y.objects.create(name = 'second y')
z1 = Z.objects.create(name = 'first z')
z2 = Z.objects.create(name = 'second z')
x1.content = y1
x1.save()
x2.content = z1
x2.save()
x3.content = y2
x3.save()
x4.content = z2
x4.save()
X.objects.all()
[&lt;X: first x&gt;, &lt;X: fourth x&gt;, &lt;X: second x&gt;, &lt;X: third x&gt;]
Y.objects.all()
[&lt;Y: first y&gt;, &lt;Y: first y&gt;, &lt;Y: second y&gt;]</pre>
<p>Notice that &#8216;first y&#8217; appears twice. The SQL <strong>COUNT</strong> statement will not have any ordering applied, and so returns the correct value:</p>
<pre class="brush: python">Y.objects.count()
2</pre>
<p>However, when ordering is applied, the duplicate instance is present:</p>
<pre class="brush: python">len(Y.objects.all())
3</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.petrounias.org/articles/2010/01/27/duplicate-items-when-ordering-by-generic-relation-in-django/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
