Django:如何根据序列化器 to_representation 中生成的自定义字段进行过滤

问题描述 投票:0回答:1

我的额外操作视图中有一个自定义字段,它是通过覆盖序列化器中的

to_representation()
添加的。我想根据该值添加一个过滤器。我怎样才能实现这一目标?

views.py

class MyFiltersetclass(filters.Filterset):
  name = filters.CharFilter(lookup_expr="exact", field_name="name")
  
  class Meta:
     model= MyModel
     fields = ["name"]

class MyViewset():
   ....
   @action(detail=True, method=["get"], queryset=MyModel.objects.filter(type=1), serilizer=MyModelSerializer, filterset_class=MyFiltersetclass)
   def action(self, request, *args, **kwargs):
      qs = self.get_object()
      queryset = self.filter_queryset(queryset)

      page = self.paginate_queryset(queryset)
      if page:
         serializer = self.get_serializer(page, many=True)
      else:
         serializer = self.get_serializer(queryset, many=True)

    return self.get_paginated_response(serializer.data)

模型.py

class MyModel(models.Model):
    name = models.TextField(blank=True, null=True)
    summaries = models.JSONField(blank=True, null=True)

    @property
    def summary(self):
        if not self.summaries:
            return {}

        return custom_func(self.summaries)

    class Meta:
        db_table = "model_view_1"
        managed = False

序列化器.py

class MyModelSerializer(serializers.ModelSerializer):
    summary = serializers.ReadOnlyField()

    def to_representation(self, instance):
        data = super().to_representation(instance)
        summary = data.pop("summary")

        data["field_1"] = summary.get("field_1")

        return {**data}

    class Meta:
        model = MyModel
        exclude = ["summaries"]

现在我想添加一个可以基于

field_1
进行过滤的过滤器,就像我们在filterset类中为
name
添加过滤器一样。

python-3.x django filter django-rest-framework django-filter
1个回答
0
投票

您可以在

MyFiltersetclass
中创建自定义过滤器方法。但是,由于 field_1 不是数据库模型中的直接字段,而是从摘要属性派生的,因此您需要以不同的方式处理过滤逻辑。

class MyFiltersetclass(filters.Filterset):
    name = filters.CharFilter(lookup_expr="exact", field_name="name")
    field_1 = filters.CharFilter(method="filter_field_1")

    def filter_field_1(self, queryset, name, value):
        filtered_queryset = []
        for obj in queryset:
            serializer = MyModelSerializer(obj)
            if serializer.data.get("field_1") == value:
                filtered_queryset.append(obj)
        return filtered_queryset

    class Meta:
        model = MyModel
        fields = ["name", "field_1"]
© www.soinside.com 2019 - 2024. All rights reserved.