gpt4 book ai didi

python - Django Rest Framework 使用 filterset_fields 在 ViewSet 中过滤计算出的 SerializerMethodField()

转载 作者:行者123 更新时间:2023-12-05 04:51:49 24 4
gpt4 key购买 nike

我有一个 SerializerMethodField 计算下一个执行日期加上上次执行时间的小时数

简化代码,有这个模型:

class Activity(BaseModel):
name = models.CharField(max_length=250)
last_execution = models.DateTimeField()

def __str__(self):
return self.name

class Meta:
ordering = ('name',)

为了在下一次执行时发送到前端,我的 Serializer 中有这个 SerializerMethodField()

class ActivitySerializer(serializers.ModelSerializer):
next_execution = serializers.SerializerMethodField('get_next_execution')

class Meta:
model = Activity
fields = ('id', 'name', 'last_execution', 'next_execution',)

def get_next_execution(self, data):
# last = ActivityExecute.objects.filter(activity_id=data.id).order_by('-executed_at').first()
# time = data.periodicity_type.time_in_hour
# if last:
# if data.equipment.hour_meter > -1:
# return last.executed_at + timedelta(hours=time - (data.equipment.hour_meter - last.hour_meter))
# return last.executed_at + timedelta(hours=time)
#
# return data.equipment.created_at + timedelta(hours=time)
return data.last_execution + timedelta(hours=24)

但是当我尝试像这样将计算字段添加到 filterset_fields 时:

class ActivityViewSet(viewsets.ModelViewSet):
permission_classes = (IsAuthenticated,)

serializer_class = ActivitySerializer
filter_backends = (filters.DjangoFilterBackend,)
filterset_fields = {
'id': ['exact'],
'name': ['icontains', 'exact'],
'last_execution': ['exact'],
'next_execution': ['exact'],
}

def get_object(self):
return super(ActivityViewSet, self).get_object()

def get_queryset(self):
return Activity.objects.all()

我遇到了这个错误:'Meta.fields' 不得包含非模型字段名称:next_execution

有一种方法可以将 SerializerMethodField() 添加到 filterset_fields 中吗?使用方法 get_queryset 将使我在该计算字段(注释)中的所有逻辑都被复制。该字段工作正常,问题只是前端使用查询参数过滤值。

最佳答案

如果您可以将一个包添加到您的项目中,那么 django-property-filter 会很容易

只需将您的序列化程序代码转换为如下属性:

class Activity(BaseModel):
name = models.CharField(max_length=250)
last_execution = models.DateTimeField()

def __str__(self):
return self.name

class Meta:
ordering = ('name',)

@property
def next_execution(self):
# all your logic in comment can be pasted here
return self.last_execution + timedelta(hours=24)

serializer 中删除您的 SerializerMethodField()def get_next_execution 但将其保留在字段列表中,此属性将列为字段还有

class ActivitySerializer(serializers.ModelSerializer):

class Meta:
model = Activity
fields = ('id', 'name', 'last_execution', 'next_execution',)

现在,在 View 中,从您的 ViewSet 中删除 filterset_fields,我们将把它添加到 FilterSet 类中...

为您的 ViewSet 创建一个 FilterSet

from django_property_filter import PropertyFilterSet, PropertyDateFilter

class ActivityFilterSet(PropertyFilterSet):
next_execution = PropertyDateFilter(field_name='next_execution', lookup_expr='exact') # this is the @property that will be filtered as a DateFilter, you can change the variable name, just keep the `field_name` right

class Meta:
model = Activity
fields = { # here is the filterset_fields property
'id': ['exact'],
'name': ['icontains', 'exact'],
'last_execution': ['exact'],
}

然后,只需将这个 FilterSet 添加到您的 ViewSet 中,奇迹就会发生

class ActivityViewSet(viewsets.ModelViewSet):
permission_classes = (IsAuthenticated,)

serializer_class = ActivitySerializer
filter_backends = (filters.DjangoFilterBackend,)
filterset_class = ActivityFilterSet

def get_object(self):
return super(ActivityViewSet, self).get_object()

def get_queryset(self):
return Activity.objects.all()

关于python - Django Rest Framework 使用 filterset_fields 在 ViewSet 中过滤计算出的 SerializerMethodField(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66769946/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com