#33008: prefetch_related for GenericForeignKey - Object doesn't exist behaviour
-------------------------------------+-------------------------------------
               Reporter:  Martin     |          Owner:  nobody
  Svoboda                            |
                   Type:             |         Status:  new
  Uncategorized                      |
              Component:  Database   |        Version:  3.2
  layer (models, ORM)                |
               Severity:  Normal     |       Keywords:
           Triage Stage:             |      Has patch:  0
  Unreviewed                         |
    Needs documentation:  0          |    Needs tests:  0
Patch needs improvement:  0          |  Easy pickings:  0
                  UI/UX:  0          |
-------------------------------------+-------------------------------------
 prefetch_related called for GenericForeignKey sets content_type_id and
 object_id to None, if the foreign object doesn't exist. This behaviour is
 not documented.

 GenericForignKey is often used for audit records, so it can keep links to
 non-existing objects. Probably prefetch_related shouldn't touch original
 values of object_id and content_type_id and only set content_object to
 None.


 {{{
 from django.contrib.auth.models import User
 from django.contrib.contenttypes.fields import GenericForeignKey
 from django.contrib.contenttypes.models import ContentType
 from django.db import models


 class TaggedItem(models.Model):
     tag = models.SlugField()
     content_type = models.ForeignKey(ContentType,
 on_delete=models.CASCADE)
     object_id = models.PositiveIntegerField()
     content_object = GenericForeignKey('content_type', 'object_id')

 # init data
 guido = User.objects.create(username='Guido')
 t = TaggedItem(content_object=guido, tag='test')
 t.save()
 guido.delete()

 # get content_object normally
 tags_1 = TaggedItem.objects.filter(tag='test')
 tags_1[0].content_object  # returns None
 tags_1[0].object_id  # returns 1
 tags_1[0].content_type_id  # returns X

 # use prefetch_related
 tags_2 =
 TaggedItem.objects.filter(tag='test').prefetch_related("content_object")
 tags_2[0].content_object  # returns None
 tags_2[0].object_id  # returns None
 tags_2[0].content_type_id # returns None
 }}}

-- 
Ticket URL: <https://code.djangoproject.com/ticket/33008>
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 on the web visit 
https://groups.google.com/d/msgid/django-updates/056.925bbf8c6cbeac611081b76312ca83e6%40djangoproject.com.

Reply via email to