#36135: Prefetch GenericForeignKey with ManyToMany field error
--------------------------+-----------------------------------------
     Reporter:  john      |                     Type:  Bug
       Status:  new       |                Component:  Uncategorized
      Version:  5.1       |                 Severity:  Normal
     Keywords:  prefetch  |             Triage Stage:  Unreviewed
    Has patch:  0         |      Needs documentation:  0
  Needs tests:  0         |  Patch needs improvement:  0
Easy pickings:  0         |                    UI/UX:  0
--------------------------+-----------------------------------------
 I have some models in my app:

 {{{
 class User(models.Model):
     name = models.CharField()


 class Project(models.Model):
     name = models.CharField()
     users = models.ManyToManyField('User', related_name='projects')


 class Task(models.Model):
     name = models.CharField()
     project = models.ForeignKey('Project', on_delete=models.DO_NOTHING,
 related_name='tasks', null=True)

     link_entity_type = models.ForeignKey(ContentType,
 on_delete=models.DO_NOTHING, null=True, related_name='link_tasks')
     link_entity_id = models.IntegerField(null=True)
     link = GenericForeignKey('link_entity_type', 'link_entity_id')


 class Version(models.Model):
     name = models.CharField()
     task = models.ForeignKey('Task', on_delete=models.DO_NOTHING,
 related_name='versions', null=True)


 class Shot(models.Model):
     name = models.CharField()
     users = models.ManyToManyField('User', related_name='shots')

     link_tasks = GenericRelation(
         'Task',
         object_id_field='link_entity_id',
         content_type_field='link_entity_type'.format(field.name),
         related_query_name='link_Shot'
     )


 class Asset(models.Model):
     name = models.CharField()
     users = models.ManyToManyField('User', related_name='assets')

     link_tasks = GenericRelation(
         'Task',
         object_id_field='link_entity_id',
         content_type_field='link_entity_type'.format(field.name),
         related_query_name='link_Asset'
     )
 }}}

 If I query Task and prefetch project and users, I will use:
 {{{
 query = Task.objects.all().prefetch_related('project__users')
 for i in query:
     print(i.id)
 }}}

 This is ok, I can get the result.

 But if I want to query Task and prefetch link_Shot and users
 {{{
 query = Task.objects.all().prefetch_related('link_Shot__users')
 for i in query:
     print(i.id)
 }}}
 or
 {{{
 query = Version.objects.all().prefetch_related('task__link_Shot__users')
 for i in query:
     print(i.id)
 }}}


 I got error:
 {{{
 Traceback (most recent call last):
   File "/ela/workspace/xinghuan/issues/sins/sins2server/tmp/tst_query.py",
 line 35, in <module>
     for i in query:
   File
 
"/UNC/fs_user_ws.ela.com/ela/workspace/xinghuan/issues/sins/sins2server/tmp/django/db/models/query.py",
 line 398, in __iter__
     self._fetch_all()
   File
 
"/UNC/fs_user_ws.ela.com/ela/workspace/xinghuan/issues/sins/sins2server/tmp/django/db/models/query.py",
 line 1883, in _fetch_all
     self._prefetch_related_objects()
   File
 
"/UNC/fs_user_ws.ela.com/ela/workspace/xinghuan/issues/sins/sins2server/tmp/django/db/models/query.py",
 line 1273, in _prefetch_related_objects
     prefetch_related_objects(self._result_cache,
 *self._prefetch_related_lookups)
   File
 
"/UNC/fs_user_ws.ela.com/ela/workspace/xinghuan/issues/sins/sins2server/tmp/django/db/models/query.py",
 line 2321, in prefetch_related_objects
     obj_list, additional_lookups = prefetch_one_level(
   File
 
"/UNC/fs_user_ws.ela.com/ela/workspace/xinghuan/issues/sins/sins2server/tmp/django/db/models/query.py",
 line 2463, in prefetch_one_level
     ) = prefetcher.get_prefetch_queryset(instances,
 lookup.get_current_queryset(level))
   File
 
"/UNC/fs_user_ws.ela.com/ela/workspace/xinghuan/issues/sins/sins2server/tmp/django/db/models/fields/related_descriptors.py",
 line 746, in get_prefetch_queryset
     instance = instances_dict[rel_obj_attr(rel_obj)]
   File
 
"/UNC/fs_user_ws.ela.com/ela/workspace/xinghuan/issues/sins/sins2server/tmp/django/db/models/fields/related.py",
 line 750, in get_local_related_value
     return self.get_instance_value_for_fields(instance,
 self.local_related_fields)
   File
 
"/UNC/fs_user_ws.ela.com/ela/workspace/xinghuan/issues/sins/sins2server/tmp/django/db/models/fields/related.py",
 line 772, in get_instance_value_for_fields
     ret.append(getattr(instance, field.attname))
 AttributeError: 'Shot' object has no attribute 'link_entity_id'
 }}}

 The discussion link:
 [https://forum.djangoproject.com/t/how-to-prefetch-a-genericforeignkey-
 with-manytomany-field/38168]

 I'm using Django 4.2.16 and python 3.9.
 I also tried Django 5.1.5 and python 3.10 and the error is same.
-- 
Ticket URL: <https://code.djangoproject.com/ticket/36135>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/django-updates/010701949697f7e3-dc9bf39c-e7b5-4e48-9e89-94f88b92ebb5-000000%40eu-central-1.amazonses.com.

Reply via email to