diff --git a/django/db/models/query.py b/django/db/models/query.py
a
|
b
|
class QuerySet(object):
|
275 | 275 | for row in self.query.results_iter(): |
276 | 276 | if fill_cache: |
277 | 277 | obj, _ = get_cached_row(self.model, row, index_start, |
278 | | max_depth, requested=requested) |
| 278 | max_depth, requested=requested, |
| 279 | follow_null=self.query.follow_null) |
279 | 280 | else: |
280 | 281 | obj = self.model(*row[index_start:]) |
281 | 282 | for i, k in enumerate(extra_select): |
… |
… |
class QuerySet(object):
|
532 | 533 | related objects are included in the selection. |
533 | 534 | """ |
534 | 535 | depth = kwargs.pop('depth', 0) |
| 536 | follow_null = kwargs.pop('follow_null', False) |
535 | 537 | if kwargs: |
536 | 538 | raise TypeError('Unexpected keyword arguments to select_related: %s' |
537 | 539 | % (kwargs.keys(),)) |
… |
… |
class QuerySet(object):
|
544 | 546 | obj.query.select_related = True |
545 | 547 | if depth: |
546 | 548 | obj.query.max_depth = depth |
| 549 | obj.query.follow_null = follow_null |
547 | 550 | return obj |
548 | 551 | |
549 | 552 | def dup_select_related(self, other): |
… |
… |
class EmptyQuerySet(QuerySet):
|
788 | 791 | |
789 | 792 | |
790 | 793 | def get_cached_row(klass, row, index_start, max_depth=0, cur_depth=0, |
791 | | requested=None): |
| 794 | requested=None, follow_null=False): |
792 | 795 | """ |
793 | 796 | Helper function that recursively returns an object with the specified |
794 | 797 | related attributes already populated. |
… |
… |
def get_cached_row(klass, row, index_sta
|
806 | 809 | else: |
807 | 810 | obj = klass(*fields) |
808 | 811 | for f in klass._meta.fields: |
809 | | if not select_related_descend(f, restricted, requested): |
| 812 | if not select_related_descend(f, restricted, requested, follow_null): |
810 | 813 | continue |
811 | 814 | if restricted: |
812 | 815 | next = requested[f.name] |
813 | 816 | else: |
814 | 817 | next = None |
815 | 818 | cached_row = get_cached_row(f.rel.to, row, index_end, max_depth, |
816 | | cur_depth+1, next) |
| 819 | cur_depth+1, next, follow_null) |
817 | 820 | if cached_row: |
818 | 821 | rel_obj, index_end = cached_row |
819 | 822 | if obj is not None: |
diff --git a/django/db/models/query_utils.py b/django/db/models/query_utils.py
a
|
b
|
class Q(tree.Node):
|
48 | 48 | obj.negate() |
49 | 49 | return obj |
50 | 50 | |
51 | | def select_related_descend(field, restricted, requested): |
| 51 | def select_related_descend(field, restricted, requested, follow_null): |
52 | 52 | """ |
53 | 53 | Returns True if this field should be used to descend deeper for |
54 | 54 | select_related() purposes. Used by both the query construction code |
… |
… |
def select_related_descend(field, restri
|
61 | 61 | return False |
62 | 62 | if restricted and field.name not in requested: |
63 | 63 | return False |
64 | | if not restricted and field.null: |
| 64 | if not restricted and not follow_null and field.null: |
65 | 65 | return False |
66 | 66 | return True |
67 | 67 | |
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
a
|
b
|
class BaseQuery(object):
|
77 | 77 | # Arbitrary maximum limit for select_related. Prevents infinite |
78 | 78 | # recursion. Can be changed by the depth parameter to select_related(). |
79 | 79 | self.max_depth = 5 |
| 80 | |
| 81 | # Does select_related follow fields that can be NULL? |
| 82 | self.follow_null = False |
80 | 83 | |
81 | 84 | # These are for extensions. The contents are more or less appended |
82 | 85 | # verbatim to the appropriate clause. |
… |
… |
class BaseQuery(object):
|
182 | 185 | obj.select_related = self.select_related |
183 | 186 | obj.related_select_cols = [] |
184 | 187 | obj.max_depth = self.max_depth |
| 188 | obj.follow_null = self.follow_null |
185 | 189 | obj.extra_select = self.extra_select.copy() |
186 | 190 | obj.extra_tables = self.extra_tables |
187 | 191 | obj.extra_where = self.extra_where |
… |
… |
class BaseQuery(object):
|
1014 | 1018 | restricted = False |
1015 | 1019 | |
1016 | 1020 | for f, model in opts.get_fields_with_model(): |
1017 | | if not select_related_descend(f, restricted, requested): |
| 1021 | if not select_related_descend(f, restricted, requested, |
| 1022 | self.follow_null): |
1018 | 1023 | continue |
1019 | 1024 | # The "avoid" set is aliases we want to avoid just for this |
1020 | 1025 | # particular branch of the recursion. They aren't permanently |