[Python-modules-team] Bug#876816: python-django: Can't defer() fields from super- and sub-class at the same time

Andrew Donnellan andrew.donnellan at au1.ibm.com
Tue Sep 26 08:35:34 UTC 2017


Package: python-django
Severity: normal
Tags: patch

Upstream bug: https://code.djangoproject.com/ticket/28549

 From the upstream bug report:

-----------------------------
  Using the models:

from django.db import models

class Base(models.Model):
     f1 = models.CharField(max_length=10)

class Sub(Base):
     f2 = models.CharField(max_length=10)

it seems that I can't defer() both f1 and f2 in a single query:

>>> Sub.objects.defer('f1', 'f2').query.sql_with_params()[0]
u'SELECT "defer_base"."id", "defer_base"."f1", "defer_sub"."base_ptr_id" 
FROM "defer_sub" INNER JOIN "defer_base" ON ("defer_sub"."base_ptr_id" = 
"defer_base"."id")'

(we're seeing f1 in the SELECT value list).

I seem to be able to defer f1 or f2 separately though.

I'm no django hacker, but: it seems as though 
django.db.models.sql.query.Query.deferred_to_data() is iterating both 
models in the loop:

#640:
             for model, values in six.iteritems(seen):
                 for field in model._meta.fields:
                     if field in values:
                         continue

- and so is discovering f1 twice: once as Base.f1 and again as Sub.f1. 
Since the field in values test only skips Base.f1, we're still left with 
Sub.f1 in the workset dict.
-----------------------------

This bug caused significant performance degradation when we upgraded a 
Django application to a new version that relied on model inheritance.

The attached patch is a backport of commit 
84b7cb7df00192b2f804e2c6fd98b78b5bfd1ffa from upstream master.

This issue applies to both 1:1.10.7-2 and 1:1.11.5-1.

Patch supplied by Jeremy Kerr and tested/backported by Daniel Axtens.


Regards,
-- 
Andrew Donnellan              OzLabs, ADL Canberra
andrew.donnellan at au1.ibm.com  IBM Australia Limited
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Fixed-28549-Fixed-QuerySet.defer-with-super-and-subc.patch
Type: text/x-patch
Size: 1959 bytes
Desc: not available
URL: <http://lists.alioth.debian.org/pipermail/python-modules-team/attachments/20170926/2ef34580/attachment.bin>


More information about the Python-modules-team mailing list