I have a model which has a ForeignKey to itself, intended to mark duplicates similar to a bug/ticket-tracking system:
class Bug(models.Model): name = models.CharField(maxlength=64) duplicate_of = models.ForeignKey('self', related_name='duplicates', null=True) def __str__(self): return self.name When searching through bug names for a particular string, I don't want the duplicate bugs to appear; instead, I want both bugs with a matching name and bugs whose set of duplicates contains one with a matching name. I would have expected this filter to work: Bug.objects.filter( Q(name__contains=string) | Q(duplicates__name__contains=string), duplicate_of__isnull=True) It doesn't. Instead, I get this very surprising behavior: >>> for t in Bug.objects.all(): ... print t.name, t.duplicate_of ... eggs1 None eggs2 spam spam None >>> qs = Bug.objects.filter(duplicate_of__isnull=True) >>> r1 = qs.filter(name__contains='eggs') >>> r2 = qs.filter(duplicates__name__contains='eggs') >>> r1 [<Bug: eggs1>] >>> r2 [<Bug: spam>] >>> r1 | r2 [<Bug: spam>] >>> It seems that this is because Django is using INNER JOIN in its query: SELECT "test_bug"."id","test_bug"."name","test_bug"."duplicate_of_id" FROM "test_bug" INNER JOIN "test_bug" AS "test_bug__duplicates" ON "test_bug"."id" = "test_bug__duplicates"."duplicate_of_id" WHERE (("test_bug"."duplicate_of_id" IS NULL AND "test_bug"."name" LIKE %eggs% ESCAPE '\') OR ("test_bug"."duplicate_of_id" IS NULL AND "test_bug__duplicates"."name" LIKE %eggs% ESCAPE '\')) Replacing the INNER JOIN with a LEFT OUTER JOIN gives me the results I expected. Is this a bug, or am I doing something silly? -Zak --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to [EMAIL PROTECTED] To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/django-users?hl=en -~----------~----~----~----~------~----~------~--~---