Django ORM replacement for extra where

Viewed 319

Here is a scenario that I currently plan solving with .extra(where=...) call:

class CustomData(models.Model):
   data = models.CharField()
   target_type = models.ForeignKey(ContentType)
   target_object_id = models.PositiveInteger()
   target_object = GenericForeignKey('target_type', 'target_object_id')

# list of tuples with object ID and mixed content type ID [(1, 15), (2, 15), (3, 11), (4, 12), ...]
related_objects = get_list_of_objects(...)
releated_custom_data = CustomData.objects.extra(
      where=['(target_object_id, target_type_id) = ANY (VALUES %s)'], 
      params=str(related_objects)[1:-1]
)

Based on the django docs extra is getting deprecated in the future. Is there a sensible alternative for making a value pair filtering with the ORM?

1 Answers

You can make a Q object that filters combinations of the two, like:

from django.db.models import Q

data = [(1, 15), (2, 15), (3, 11), (4, 12)]
q_filter = Q(
    *[Q(target_object_id=d1, target_type_id=d2) for d1, d2 in data],
    _connector=Q.OR
)

CustomData.objects.filter(q_filter)
Related