MattBroach / DjangoRestMultipleModels

View (and mixin) for serializing multiple models or querysets in Django Rest Framework
MIT License
549 stars 67 forks source link

Different sorting fields based on query paramater #35

Closed kewal07 closed 6 years ago

kewal07 commented 6 years ago

First of all kudos for such a great project. It has helped speed up the dev time a lot.

One of the common use cases which occurs is sorting based on different fields. For ex, the api endpoint may be something like: GET /blogs?sort_field={sorting_field} Now in the above example, there can be different values of the sorting criteria like sort by published date or sort by number of upvotes and so on. How best can we do this.

kewal07 commented 6 years ago

Update: I tried overriding the sorting_field method but this does not work. In fact this is not getting called i think.

def sort_results(self, results):
        """
        determing if sort is ascending or descending
        based on the presence of '-' at the beginning of the
        sorting_field attribute
        """
        print('**********') # Does not print to console
                print(self.__dict__) # Does not print
        q = self.request.query_params.get('q')
        print(q)
        if q == 'time' or q == '':
            sorting_field = '-created_at'
        elif q == 'upvotes':
            sorting_field = '-upvotes'
        # sorting_field = self.sorting_field
        sort_descending = self.sorting_field[0] == '-'

        # Remove the '-' if sort descending
        if sort_descending:
            sorting_field = sorting_field[1:len(sorting_field)]

        return sorted(
            results,
            reverse=sort_descending,
            key=lambda datum: datum[sorting_field]
        )
kewal07 commented 6 years ago

Solved.:

def sort_results(self, results):
        """
        determing if sort is ascending or descending
        based on the presence of '-' at the beginning of the
        sorting_field attribute
        """
        q = self.request.query_params.get('q')
        if q == 'recent' or q == '':
            self.sorting_field = '-created_at'
        elif q == 'hot':
            self.sorting_field = '-upvotes'
        sorting_field = self.sorting_field
        sort_descending = self.sorting_field[0] == '-'

        # Remove the '-' if sort descending
        if sort_descending:
            sorting_field = sorting_field[1:len(sorting_field)]

        return sorted(
            results,
            reverse=sort_descending,
            key=lambda datum: datum[sorting_field]
        )
MattBroach commented 6 years ago

Hey @kewal07! Sorry I wasn't able to comment on this earlier, but it looks like everything worked out. Thanks for posting your solution -- I'm sure it will be helpful for others searching later!

kewal07 commented 6 years ago

Hey @MattBroach . My pleasure sir. This is a truly great project. More often than not we need to mix multiple models and query and this makes it a breeze to work with. Appreciate the effort. Kudos!