0

Thanks to this article

https://stackoverflow.com/questions/431628/how-can-i-combine-two-or-more-querysets-in-a-django-view#:~:text=Use%20union%20operator%20for%20queryset,querysets%20by%20using%20union%20operator.&text=One%20other%20way%20to%20achieve,to%20use%20itertools%20chain%20function.

I use QuerySetChain class to concatenate multiple queryset

class QuerySetChain(object):
    """
    Chains multiple subquerysets (possibly of different models) and behaves as
    one queryset.  Supports minimal methods needed for use with
    django.core.paginator.
    """

    def __init__(self, *subquerysets):
        self.querysets = subquerysets

    def count(self):
        """
        Performs a .count() for all subquerysets and returns the number of
        records as an integer.
        """
        return sum(qs.count() for qs in self.querysets)

    def _clone(self):
        "Returns a clone of this queryset chain"
        return self.__class__(*self.querysets)

    def _all(self):
        "Iterates records in all subquerysets"
        return chain(*self.querysets)
  
    def __getitem__(self, ndx):
        """
        Retrieves an item or slice from the chained set of results from all
        subquerysets.
        """
        if type(ndx) is slice:
            return list(islice(self._all(), ndx.start, ndx.stop, ndx.step or 1))
        else:
            return islice(self._all(), ndx, ndx+1).next()

Now I pick up some tables

    md = sm.Message.history.all()
    sw = sm.Worker.history.all()
    st = sm.Template.history.all()
    gp = sm.GlobalParam.history.all()


    matches = QuerySetChain(md, sw, st,gp) # it makes one queryset successfully

    result_list = sorted( #error occurs here
        matches,
        key=lambda instance: instance.updated_at)

When I am trying to sort the items, The error occurs like this below.

'itertools.islice' object has no attribute 'next' when sorting chained object

Is it possible to sort this?

whitebear
  • 8,922
  • 18
  • 81
  • 171
  • i do not understand why you need to create a class just for chaining differents models just use `from itertools import chain matches = list(chain(md, sw, st,gp))` and even better you can use `.union()` you can read more here https://docs.djangoproject.com/en/4.0/ref/models/querysets/#django.db.models.query.QuerySet.union – Thierno Amadou Sow Apr 14 '22 at 05:12

0 Answers0