【问题标题】:Django Rest Ordering customDjango Rest 订购自定义
【发布时间】:2017-04-18 10:18:08
【问题描述】:

我正在使用 django rest 框架,我想使用自定义方法订购。

所以,当我调用这个网址时,例如:http://127.0.0.1:8000/api/sets/?ordering=partMissing

可以调用自定义方法,因为我想订购 sn-p 缺少的零件数量。我计算了多对多字段中部分的总和。

【问题讨论】:

    标签: python django python-3.x django-rest-framework


    【解决方案1】:

    我有非常简单的 POC,应该可以让您实施更复杂的解决方案。

    views.py:

    from rest_framework import viewsets
    
    from ordering_test.models import Test
    from ordering_test.ordering import MyCustomOrdering
    from ordering_test.serializers import TestSerializer
    
    class TestViewSet(viewsets.ModelViewSet):
        queryset = Test.objects.all()
        serializer_class = TestSerializer
        filter_backends = (MyCustomOrdering,)
    

    ordering.py:

    from rest_framework.filters import OrderingFilter
    
    class MyCustomOrdering(OrderingFilter):
    
        allowed_custom_filters = ['testMethod']
    
        def get_ordering(self, request, queryset, view):
            """
            Ordering is set by a comma delimited ?ordering=... query parameter.
    
            The `ordering` query parameter can be overridden by setting
            the `ordering_param` value on the OrderingFilter or by
            specifying an `ORDERING_PARAM` value in the API settings.
            """
            params = request.query_params.get(self.ordering_param)
    
            if params:
                fields = [param.strip() for param in params.split(',')]
                # care with that - this will alow only custom ordering!
                ordering = [f for f in fields if f in self.allowed_custom_filters]
                if ordering:
                    return ordering
    
            # No ordering was included, or all the ordering fields were invalid
            return self.get_default_ordering(view)
    
        def filter_queryset(self, request, queryset, view):
    
            ordering = self.get_ordering(request, queryset, view)
            if ordering:
                # implement a custom ordering here
                ordering = ['-id']
    
            if ordering:
                return queryset.order_by(*ordering)
    
            return queryset
    

    models.pyserializers.py 很简单,但我仍将它们包括在这里:

    models.py:

    from django.db import models
    
    class Test(models.Model):
        test = models.CharField(max_length=120)
        test1 = models.CharField(max_length=120)
    

    serializers.py:

    from rest_framework import serializers
    
    from ordering_test.models import Test
    
    class TestSerializer(serializers.ModelSerializer):
    
        class Meta:
            model = Test
            fields = ('test', 'test1')
    

    编码愉快!

    【讨论】:

    【解决方案2】:

    我认为 opalczynski 的解决方案更简单的方法是为自定义排序引入一个新字段:

    from django import forms
    
    import django_filters
    from rest_framework import serializers
    
    from .models import MyModel
    
    
    class MyModelSerializer(serializers.ModelSerializer):
    
        class Meta:
            model = MyModel
            fields = ('field1',)
    
    
    class CustomOrderingFilter(django_filters.FilterSet):
        order_by = django_filters.BooleanFilter(
            widget=forms.HiddenInput(),
            method='filter_order_by',
        )
    
        class Meta:
            model = MyModel
            fields = [
                'order_by'
            ]
    
        def filter_order_by(self, queryset, name, value):
            if value:
                return self.Meta.model.objects.filter(
                    id__in=queryset.values_list('id', flat=True)
                ).order_by(value)
    
            return queryset
    
    class TestViewSet(viewsets.ModelViewSet):
        queryset = MyModel.objects.all()
        serializer_class = MyModelSerializer
        filter_class = CustomOrderingFilter
    

    然后您可以轻松地按您想要的任何字段排序:example.com/api/mymodel/?order_by=partMissing

    在我的示例中,我使用了固定模型字段,但您可以在 CustomOrderingFilter 上的 filter_order_by 方法中更改您的排序方式。只需将其更改为您想要的逻辑,但请确保使用.filter(=queryset.values_list('id', flat=True)) 以确保正在使用设置的其他过滤器。

    【讨论】:

      猜你喜欢
      • 2017-08-13
      • 2013-04-13
      • 1970-01-01
      • 1970-01-01
      • 2022-01-10
      • 1970-01-01
      • 1970-01-01
      • 2021-01-06
      • 1970-01-01
      相关资源
      最近更新 更多