django-hashid-field icon indicating copy to clipboard operation
django-hashid-field copied to clipboard

Using GenericRelation with prefetch_related

Open CleitonDeLima opened this issue 2 years ago • 0 comments

I'm having problems using the query with prefetch on a GenericRelation field. Follow the example:

class Action(models.Model):
    description = models.TextField()
    target_content_type = models.ForeignKey(
        "contenttypes.ContentType",
        on_delete=models.CASCADE,
    )
    # target_object_id save the hash
    target_object_id = models.TextField()
    target = GenericForeignKey(
        "target_content_type",
        "target_object_id",
    )

class ExampleModel(models.Model):
    id = hashid_field.BigHashidAutoField(primary_key=True)
    actions = GenericRelation(
        Action,
        content_type_field="target_content_type",
        object_id_field="target_object_id",
    )

When using the queryset below, the target object is not populated. I use models with id of type UUID and it works normally.

Action.objects.prefetch_related("target")

Digging through the django source code, mapping fields using prefetch_related is in search of a dict, in which the key is a tuple with the HashId and the model class.

  • https://github.com/django/django/blob/main/django/db/models/query.py#L2506-L2523
  • https://github.com/django/django/blob/066aabcb77579cf8d549119c860d11cd15e3eef1/django/contrib/contenttypes/fields.py#L204-L215

I wonder, if object Hashid(5) == 5, dict {Hashid(5): 'test'}.get(5) != 'test'. It sounds kind of silly but django does a similar option when linking instances. Perhaps some magic method is missing from the Hashid class.

CleitonDeLima avatar Mar 31 '23 18:03 CleitonDeLima