﻿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
11460	Admin changelist shows no rows with a non-zero count where ForeignKeys are used in list_display and data is bad	afitzpatrick	nobody	"If you have a record with a foreign key pointing to a non-existent object and that foreign key is included is list_display, the record will not be shown in the admin changelist.

The qs.select_related() call on line 210 of admin/views/main.py in Django 1.0.2-final won't return any rows with bad FK references, as expected.

However, whilst admin tool knows that there are X records to display, select_related() will return (X - number_of_bad_fks) for display. The tool should be able to figure out whether X != (X - number_of_bad_fks) and say ""Hey, I'm about to tell you there are 10 records but only show you 5 and not explain why..."".

I've been plagued by this problem whilst working on a fairly large application where the data is getting hacked about by a bunch of people. I wrote a little hacky patch for 1.0.2, which I'm sure reviewers won't like. I'll be happy to update for HEAD and fix the way I raise the exception if there's a better way to do this:

{{{
--- main.py	2009-07-11 18:24:11.450376926 +0100
+++ /home/afitzpatrick/main-patch.py	2009-07-11 18:24:07.138416529 +0100
@@ -197,8 +197,6 @@ class ChangeList(object):
 
         # Use select_related() if one of the list_display options is a field
         # with a relationship.
-        result_count = len(qs)
-
         if self.list_select_related:
             qs = qs.select_related()
         else:
@@ -212,9 +210,6 @@ class ChangeList(object):
                         qs = qs.select_related()
                         break
 
-        if len(qs) != result_count:
-             raise ValueError( 'select_related() returned %d records but %d were expected; there is likely a foreign key mismatch' % (len(qs), result_count) )
-
         # Set ordering.
         if self.order_field:
             qs = qs.order_by('%s%s' % ((self.order_type == 'desc' and '-' or ''), self.order_field))
}}}
To replicate the problem, assume something like this:

{{{
class Country(models.Model):
	iso = models.CharField(max_length=2, primary_key=True)

class Company(models.Model):
	name = models.CharField(max_length=128)
	country = models.ForeignKey(Country)

class CompanyAdmin(admin.ModelAdmin):
	list_display = ['name', 'company']`
}}}

Create a single record in the Company table where the country_id field references a Country that doesn't exist, then try to view all Company objects in the admin tool. It'll say ""1 Companys"" but none will be shown. Django's generated query code (below) will return no records, as it should:

{{{SELECT `app_company`.`id`, `app_country`.`iso` INNER JOIN `app_company` ON (`app_country`.`id` = `app_company`.`iso`)}}}
"	Bug	closed	Documentation	1.0	Normal	fixed		tonightslastsong@… timograham@…	Accepted	1	0	0	0	0	0
