king-off-none-coding
king-off-none-coding

Reputation: 21

Django merge querysets in one page

In django rest framework i am using pagination of 20 on a model. Now i want to make a queryset which takes 5 items which has the featured field as true. The other 15 should be items which has the featured field as false.

Does anyone have an idea how to make this work?

permission_classes = [AllowAny]
serializer_class = JobSerializer
pagination_class = Pagination

order_types = {
    1: 'job_order', #by randomized job order
    2: '-created_date', #newest to oldest
    3: 'created_date', #oldest to newest
    4: 'name', #by name A -> Z,
    5: '-name' #by name Z -> A,
}

def get_queryset(self):
 
    requirements = self.request.query_params.getlist('requirements', None)
    order_param = self.request.query_params.get('order_by', 1)

    #make querysets
    queryset_featured = Job.objects.all().filter(active=True, featured=True).order_by(self.order_types[int(order_param)])
    queryset_non_featured = Job.objects.all().filter(active=True, featured=False).order_by(self.order_types[int(order_param)])
    
   
    return queryset.distinct()

Upvotes: 1

Views: 120

Answers (1)

FlipperPA
FlipperPA

Reputation: 14311

Use a union of two separate queries:

https://docs.djangoproject.com/en/3.1/ref/models/querysets/#union

This will allow you to make one ORM query for the featured items with [0:5], and then union to an ORM query for non-featured items with [0:15].

I haven't tested this, but here's an example with your code:

queryset_featured = Job.objects.all().filter(active=True, featured=True).order_by(self.order_types[int(order_param)])[0:5]
queryset_non_featured = Job.objects.all().filter(active=True, featured=False).order_by(self.order_types[int(order_param)])[0:15]
queryset_combined = queryset_featured.union(queryset_non_featured)

for row in queryset_combined:
    print(row)

Upvotes: 3

Related Questions