Python Django Rest订购定制

Python Django Rest订购定制,python,django,python-3.x,django-rest-framework,Python,Django,Python 3.x,Django Rest Framework,我使用的是django rest框架,我希望使用自定义方法订购 例如,当我调用此url时: 可以调用自定义方法,因为我希望按代码段中缺少的零件数量排序。我计算了多对多字段中部分的数量之和 提前感谢您的回答。我有一个非常简单的POC,可以让您实现更复杂的解决方案 views.py: from rest_framework import viewsets from ordering_test.models import Test from ordering_test.ordering import

我使用的是django rest框架,我希望使用自定义方法订购

例如,当我调用此url时:

可以调用自定义方法,因为我希望按代码段中缺少的零件数量排序。我计算了多对多字段中部分的数量之和


提前感谢您的回答。

我有一个非常简单的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,)
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
from rest_framework import serializers

from ordering_test.models import Test

class TestSerializer(serializers.ModelSerializer):

    class Meta:
        model = Test
        fields = ('test', 'test1')
ordering.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,)
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
from rest_framework import serializers

from ordering_test.models import Test

class TestSerializer(serializers.ModelSerializer):

    class Meta:
        model = Test
        fields = ('test', 'test1')
models.py
serializers.py
很简单,但我仍将在这里介绍它们:

models.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,)
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
from rest_framework import serializers

from ordering_test.models import Test

class TestSerializer(serializers.ModelSerializer):

    class Meta:
        model = Test
        fields = ('test', 'test1')
来自django.db导入模型的

类别测试(models.Model):
测试=型号.CharField(最大长度=120)
test1=models.CharField(最大长度=120)
serializers.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,)
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
from rest_framework import serializers

from ordering_test.models import Test

class TestSerializer(serializers.ModelSerializer):

    class Meta:
        model = Test
        fields = ('test', 'test1')

快乐编码

我认为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\u by=partMissing

在我的示例中,我使用了一个固定的模型字段,但是您可以通过
CustomOrderingFilter
上的
方法更改在
filter\u order\u中的订购方式。只需将其更改为所需的逻辑,但确保使用
.filter(=queryset.values\u list('id',flat=True))
以确保正在使用其他已设置的过滤器