Custom OrderingFilter Django REST + Vue

130 Views Asked by At

I'm working on backend part of project (Django REST). I have a task - to do sorting for the front (Vue). The frontend sends a key for sorting and a parameter for sorting.

Example:

GET /api/v1/stocks/?sort_key=FBS&sort_type=ascending
GET /api/v1/stocks/?sort_key=FBS&sort_type=descending

I guess it can be done with OrderingFilter and DjangoFilterBackend. Any suggestions will be helpful.

my models.py

class Stock(models.Model):
    class Meta:
        verbose_name_plural = "Stocks"
        verbose_name = "Stock"
        ordering = ("-present_fbs",)

    store = models.ForeignKey(Store, on_delete=models.CASCADE, null=True, verbose_name="Store")
    fbs = models.PositiveIntegerField(default=0, verbose_name="FBS")

my views.py

class StocksApi(ListModelMixin, GenericViewSet):
    serializer_class = StocksSerializer
    permission_classes = (IsAuthenticated,)
    pagination_class = StocksDefaultPagination

    def get_queryset(self):
        return Stock.objects.filter(store__user_id=self.request.user.pk).order_by("-fbs")
2

There are 2 best solutions below

1
weAreStarsDust On BEST ANSWER

You can get the sort parameters in get_queryset with self.request.query_params.get and then sort queryset as needed.

    def get_queryset(self):
        queryset = Stock.objects.filter(store__user_id=self.request.user.pk)
        sort_key = self.request.query_params.get('sort_key', None)
        sort_type = self.request.query_params.get('sort_type', None)
        if sort_key:
            if sort_type == 'ascending':
                queryset = queryset.order_by(sort_key)
            elif sort_type == 'descending':
                queryset = queryset.order_by('-' + sort_key)
        return queryset
0
Irina_Xena On

So, I rewrote a get_queryset() method and added a serializer. It works, but I'm still looking for a method to solve this problem via OrderingFilter.

views.py

class StocksApi(CreateModelMixin, ListModelMixin, GenericViewSet):
serializer_class = StocksSerializer
permission_classes = (IsAuthenticated,)

def get_queryset(self):
    queryset = Stock.objects.filter(store__user_id=self.request.user.pk)
    sort_key = self.request.query_params.get("sort_key", None)
    sort_type = self.request.query_params.get("sort_type", None)
    serializer = StocksSortingSerializer(data={"sort_key": sort_key})
    serializer.is_valid(raise_exception=True)
    if sort_type == "ascending":
        queryset = queryset.order_by(serializer.validated_data["sort_key"])
    elif sort_type == "descending":
        queryset = queryset.order_by("-" + serializer.validated_data["sort_key"])
    return queryset

serializers.py

class StocksSortingSerializer(serializers.Serializer):
sort_key = serializers.IntegerField(required=True)

def to_internal_value(self, sort_key):
    if sort_key.get("sort_key", None) == "FBS":
        sort_key = "fbs"
    return {"sort_key": sort_key}