1

Suppose I have a model call MyModel defined as below

class MyModel(models.Model):
     fk = models.ForeignKey('AnotherModel')
     rank = models.FloatField()

I wish to create a query set for serialization so that instances with instance.fk.other_fk_id in some set comes before the ones that don't and then sorted by decreasing rank.

So I wish to join

a = MyModel.objects.filter(fk__other_fk_id__in=some_set).order_by('-rank')

and

b = MyModel.objects.exclude(fk__other_fk_id__in=some_set).order_by('-rank')

sequentially so that a comes before b when it's handed to the serializers. Any idea on how to achieve this functionality efficiently? (let's say there is 50 instances in a and 200000 instances in b so I cannot directly concat those two as lists).

The end goal is to feed it into a custom serializer w/ pagination, say, to present in a webpage.

Kevin He
  • 1,210
  • 8
  • 19

2 Answers2

1

ok I figured this out. What you can do is to annotate another value, join them and sort by two fields.

a = a.annotate(rank2=Value(1, IntegerField()))
b = b.annotate(rank2=Value(0, IntegerField()))
qs = a.union(b).order_by('-rank2', '-rank')
Kevin He
  • 1,210
  • 8
  • 19
-1

You can use itertools.chain:

from itertools import chain
from django.core import serializers
data = serializers.serialize("xml", chain(a, b))
blhsing
  • 91,368
  • 6
  • 71
  • 106
  • why the 'xml'? would this work for a customized serializer? – Kevin He Feb 22 '19 at 03:54
  • I'm just using XML as an example. You can serialize the chained querysets in any way you want. Yes it would work for a customized serializer. – blhsing Feb 22 '19 at 03:55
  • It should be mentioned: this does not actually create a query set, which the question actually asked for. I'm not sure whether that's actually important, but it *might* be very important (for example if the db has changed in between evaluation of two queries). – wim Feb 22 '19 at 04:11
  • I just need it to put it in a custom serializer, not exactly a queryset – Kevin He Feb 22 '19 at 04:12
  • that seems to union the query but does not guarantee the order? – Kevin He Feb 22 '19 at 04:14