Opened 9 years ago

Closed 9 years ago

#24807 closed Bug (duplicate)

Prefetch_related broken when two models have an M2M to the same model with related_name='+'

Reported by: Baptiste Mispelon Owned by: nobody
Component: Database layer (models, ORM) Version: 1.8
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Consider the following models:

from django.db import models

class Foo(models.Model):
    pass


class Bar(models.Model):
    bar_foos = models.ManyToManyField(Foo, related_name='+')


class Baz(models.Model):
    baz_foos = models.ManyToManyField(Foo, related_name='+')

Doing Bar.objects.prefetch_related('+') raises the following error:

[...]
  File "./django/django/db/models/query.py", line 162, in __iter__
    self._fetch_all()
  File "./django/django/db/models/query.py", line 967, in _fetch_all
    self._prefetch_related_objects()
  File "./django/django/db/models/query.py", line 591, in _prefetch_related_objects
    prefetch_related_objects(self._result_cache, self._prefetch_related_lookups)
  File "./django/django/db/models/query.py", line 1516, in prefetch_related_objects
    obj_list, additional_lookups = prefetch_one_level(obj_list, prefetcher, lookup, level)
  File "./django/django/db/models/query.py", line 1615, in prefetch_one_level
    prefetcher.get_prefetch_queryset(instances, lookup.get_current_queryset(level)))
  File "./django/django/db/models/fields/related.py", line 935, in get_prefetch_queryset
    queryset = queryset._next_is_sticky().filter(**query)
  File "./django/django/db/models/query.py", line 679, in filter
    return self._filter_or_exclude(False, *args, **kwargs)
  File "./django/django/db/models/query.py", line 697, in _filter_or_exclude
    clone.query.add_q(Q(*args, **kwargs))
  File "./django/django/db/models/sql/query.py", line 1304, in add_q
    clause, require_inner = self._add_q(where_part, self.used_aliases)
  File "./django/django/db/models/sql/query.py", line 1331, in _add_q
    current_negated=current_negated, connector=connector, allow_joins=allow_joins)
  File "./django/django/db/models/sql/query.py", line 1173, in build_filter
    self.check_related_objects(field, value, opts)
  File "./django/django/db/models/sql/query.py", line 1071, in check_related_objects
    self.check_query_object_type(v, opts)
  File "./django/django/db/models/sql/query.py", line 1052, in check_query_object_type
    (value, opts.object_name))
ValueError: Cannot query "Bar object": Must be "Baz" instance.

Using two different related_name (like '1+' and '2+' for example) makes everything work again.

See attached reproduction testcase.

Attachments (1)

repro-24807.patch (1.1 KB ) - added by Baptiste Mispelon 9 years ago.
Reproduction testcase

Download all attachments as: .zip

Change History (2)

by Baptiste Mispelon, 9 years ago

Attachment: repro-24807.patch added

Reproduction testcase

comment:1 by Baptiste Mispelon, 9 years ago

Resolution: duplicate
Status: newclosed

Nevermind folks, this is a duplicated of #24505 which was fixed with 4ee08958f154594b538207a53c1d457687b3f7ae.

Sorry for the noise.

Note: See TracTickets for help on using tickets.
Back to Top