﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
10722	Changelist view does not use select_related() on a nullable foreign key	mrts	nobody	"Given the following `models.py`:

{{{
from django.db import models

class Base(models.Model):
    name = models.CharField(max_length=10)
    lots_of_text = models.TextField()

    class Meta:
        abstract = True

    def __unicode__(self):
        return self.name

class A(Base):
    a_field = models.CharField(max_length=10)

class B(Base):
    b_field = models.CharField(max_length=10)

class C(Base):
    a = models.ForeignKey(A)
    b = models.ForeignKey(B)
    is_published = models.BooleanField()
}}}

and the following `admin.py`:

{{{
from django.contrib import admin
from improve_admin.models import A, B, C

class CAdmin(admin.ModelAdmin):
    list_display = ('name', 'a', 'b', 'is_published')

admin.site.register(A)
admin.site.register(B)
admin.site.register(C, CAdmin)
}}}

`select_related()` is used as documented in http://docs.djangoproject.com/en/dev/ref/contrib/admin/#list-select-related , resulting in the following query:

{{{
SELECT
	""improve_admin_c"".""id"", ""improve_admin_c"".""name"", ""improve_admin_c"".""lots_of_text"", ""improve_admin_c"".""a_id"", ""improve_admin_c"".""b_id"", ""improve_admin_c"".""is_published"", ""improve_admin_a"".""id"", ""improve_admin_a"".""name"", ""improve_admin_a"".""lots_of_text"", ""improve_admin_a"".""a_field"", ""improve_admin_b"".""id"", ""improve_admin_b"".""name"", ""improve_admin_b"".""lots_of_text"", ""improve_admin_b"".""b_field""
FROM
	""improve_admin_c""
	INNER JOIN ""improve_admin_a"" ON (""improve_admin_c"".""a_id"" = ""improve_admin_a"".""id"")
	INNER JOIN ""improve_admin_b"" ON (""improve_admin_c"".""b_id"" = ""improve_admin_b"".""id"")
ORDER BY
	""improve_admin_c"".""id"" DESC
}}}

----

Setting one foreign key field to be nullable:
{{{
# diff between the original and new models.py
 class C(Base):
-    a = models.ForeignKey(A)
+    a = models.ForeignKey(A, blank=True, null=True)
     b = models.ForeignKey(B)
}}}

results in the following SQL:
{{{
SELECT
	""improve_admin_c"".""id"", ""improve_admin_c"".""name"", ""improve_admin_c"".""lots_of_text"", ""improve_admin_c"".""a_id"", ""improve_admin_c"".""b_id"", ""improve_admin_c"".""is_published"", ""improve_admin_b"".""id"", ""improve_admin_b"".""name"", ""improve_admin_b"".""lots_of_text"", ""improve_admin_b"".""b_field""
FROM
	""improve_admin_c""
	INNER JOIN ""improve_admin_b"" ON (""improve_admin_c"".""b_id"" = ""improve_admin_b"".""id"")
ORDER BY
	""improve_admin_c"".""id"" DESC
}}}

and additional `n` queries for each of the referred `a` fields: 

{{{
SELECT
	""improve_admin_a"".""id"", ""improve_admin_a"".""name"", ""improve_admin_a"".""lots_of_text"", ""improve_admin_a"".""a_field""
FROM
	""improve_admin_a""
WHERE
	""improve_admin_a"".""id"" = 2
}}}"		closed	contrib.admin	dev		invalid	efficient-admin		Unreviewed	0	0	0	0	0	0
