My solution for Django> 1.10 and PostgreSQL> 9.5
from django.db.models import Func, Value, IntegerField, CharField from django.contrib.postgres.fields import ArrayField class ArrayPosition(Func): function = 'array_position' def __init__(self, items, *expressions, **extra): if isinstance(items[0], int): base_field = IntegerField() else: base_field = CharField(max_length=max(len(i) for i in items)) first_arg = Value(list(items), output_field=ArrayField(base_field)) expressions = (first_arg, ) + expressions super().__init__(*expressions, **extra) pk_list = [234,12,23] queryset = SomeModel.objects.filter(pk__in=pk_list, ...)\ .annotate(ordering=ArrayPosition(pk_list, F('pk'), output_field=IntegerField()))\ .order_by('ordering')
source share