Opened 18 years ago

Closed 18 years ago

#3149 closed defect (worksforme)

select_related() filters objects with ANY fk foreign relation

Reported by: Doug Napoleone Owned by: Adrian Holovaty
Component: Database layer (models, ORM) Version: dev
Severity: normal Keywords: select_related() null=True
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

This is different from not following FK relations with null=True which is documented.
This is select_related() EXCLUDING relations with any fk null=True where ANY fk row entry is Null.

ScheduledEvent.objects.filter(roomisnull=True)

[<ScheduledEvent: ScheduledEvent object>]

ScheduledEvent.objects.filter(roomisnull=True).select_related()

[]

ScheduledEvents have other FK's besides 'room' which are not 'null=True', for which select_related() gives a good speedup (5x over 8000 rows w/ 4 FK's). Unfortunatly it excludes all relations with a null room FK.

My current workaround is to create a special 'NULL' room which now needs to be queried for, the id cached, and .exclude(room=NullRoomId) added as a special object manager on the class. Less than optimal and would hate to have to do with for all my null=True fk relations, but might help others with this problem.

Change History (2)

comment:1 by Doug Napoleone, 18 years ago

>>> ScheduledEvent.objects.filter(room__isnull=True)
[<ScheduledEvent: ScheduledEvent object>]
>>> ScheduledEvent.objects.filter(room__isnull=True).select_related()
[]

comment:2 by Michael Radziej <mir@…>, 18 years ago

Resolution: worksforme
Status: newclosed

I tried this, but I get different results. Perhaps this has been fixed in the meantime.

models:

from django.db import models

class A(models.Model):
    pass

class B(models.Model):
    a = models.ForeignKey(A, null=True)

shell:

In [1]: from testproj.testapp import models;

In [2]: models.B.objects.create()
Out[2]: <B: B object>

In [3]: models.B.objects.filter(a__isnull=True)
Out[3]: [<B: B object>]

In [4]: models.B.objects.filter(a__isnull=True).select_related()
Out[4]: [<B: B object>]
Note: See TracTickets for help on using tickets.
Back to Top