首页 > 解决方案 > Django Rest Framework:按序列化程序方法字段排序

问题描述

我目前正在使用 Django REST framework 3.11.0 和 Django 3.0.6。我对 DRF 还是很陌生,我不知道如何解决这个问题。我正在尝试将排序应用于 SerializerMethodField 和枚举。我能够找到一些说明我可以制作自己的 OrderFilter 但我不知道如何制作的文档。有什么我可以使用的例子吗?这是我的代码。

看法

from rest_framework import generics
from V1.assets.models.asset_main import Asset
from V1.assets.serializers.asset_serializer import AssetSerializer
from rest_framework import filters
from django_filters.rest_framework import DjangoFilterBackend

class AssetsView(generics.ListCreateAPIView):
    queryset = Asset.objects.all()
    serializer_class = AssetSerializer
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filter_fields = ['asset_type']
    search_fields = ['asset_type', 'asset_properties', 'current_employee_name'] 

模型

class AssetType(models.TextChoices):
    LAPTOP = 'LPT', _('Laptop')
    MOUSE = 'MSE', _('Mouse')
    MONITOR = 'MTR', _('Monitor')
    AC_ADAPTER = 'ADR', _('AC Adapter')
    TELEPHONE = 'TLP', _('Telephone')
    LOCK = 'LCK', _('Lock')
    HEADSET = 'HDS', _('Headset')

class Asset(CreatedModified):

    asset_type = models.CharField(
        max_length=3,
        choices=AssetType.choices,
        default=None
    )
    asset_properties = JSONField(default=dict)
    current_employee = models.ForeignKey(
        Employee,
        related_name='assets_current_employees', 
        related_query_name='assets_current_employee',
        default=None,
        on_delete=models.CASCADE,
        null=True,
        blank=True
    )

    class Meta:
        app_label = 'assets'
        default_related_name = 'assets'

    def __str__(self):
        return self.asset_type

串行器

from V1.general.enums import AssetStatus, AssetType
from V1.accounts.models.employee_main import Employee

class AssetSerializer(serializers.ModelSerializer):

    current_employee_name = serializers.SerializerMethodField('get_full_name_from_employee')
    asset_type = serializers.CharField(source='get_asset_type_display')

    class Meta:
        model = Asset
        fields = (
            'id',
            'asset_type',
            'asset_properties',
            'current_employee',
            'current_employee_name'
        )
        extra_kwargs = {
            'asset_type': {
                'required': True, 
                'allow_blank': False
            }
        }

    def get_full_name_from_employee(self, asset):
        current_employee_name = asset.current_employee.first_name + ' ' + asset.current_employee.last_name
        return current_employee_name

我似乎无法按current_employee_nameor订购asset_type。我应该怎么做才能允许对这两个字段进行排序?

标签: pythondjangodjango-rest-framework

解决方案


据我从您的问题中了解到,您想按当前员工姓名订购资产。让我们以几个名字为例:

  • Jean d'Artagnan(名字:Jean,姓氏:d'Artagnan)
  • 乔管道工(名字:乔,姓:管道工)
  • 乔纳斯·迈耶(名字:乔纳斯,姓氏:迈耶)

first_name如果我们先排序,再排序,可以实现相同的排序last_name。如果有多个条目相同first_name,则排序将是last_name.

为此,您可以简单地ordering_fields在视图中指定:

class AssetsView(generics.ListCreateAPIView):
    filters = [filters.OrderingFilter]
    ordering_fields = ['current_employee.first_name', 'current_employee.last_name']

推荐阅读