【问题标题】:Django filter out on related fieldDjango过滤掉相关领域
【发布时间】:2021-07-26 02:09:16
【问题描述】:

我有三个模型,其中两个通过外键链接到第三个,如下:

class A(models.Model):
    sku = models.ForeignKey("SKU", on_delete=models.PROTECT)
    production_start = models.DateField(blank=True, null=True)
    production_end = models.DateField(blank=True, null=True)

class B(models.Model):
    date = models.DateField()
    sku = models.ForeignKey("SKU", on_delete=models.PROTECT)
    quantity = models.PositiveIntegerField()
    last_modified = models.DateTimeField(auto_now=True)

class SKU(models.Model):
    product = models.CharField(max_length=64)
    design = models.CharField(max_length=64)

我想以 有效 的方式过滤可以在 A 响应中返回的外键,例如通过在端点参数上定义日期范围过滤器(例如 /A /?from_date=2021-01-01&to_date=2021-01-02),对于生产日期在该范围内的A 的所有元素,我希望它返回包含B 元素的对象A 相同SKUdate 与特定日期匹配。

例子:

"data"=[
    {
        "sku": 7,
        "production_start": "2021-01-01",
        "production_end": "2021-01-07",
        "b": [
            {
                "date": "2021-01-01",
                "quantity": 100
            },
            {
                "date": "2021-01-02",
                "quantity": 200
            }
        ]
    },
    ...
]

到目前为止,我已经尝试将过滤器从 django-filters 添加到我的 views.py

class AViewSet(viewsets.ReadOnlyModelViewSet):
    class AFilterSet(django_filters.FilterSet):
        from_date = django_filters.DateFilter(field_name="sku__b__date", lookup_expr="gte")
        to_date = django_filters.DateFilter(field_name="sku__b__date", lookup_expr="lte")

        class Meta:
            model = models.A
            fields = []


    queryset = models.A.objects.all()
    serializer_class = serializers.ASerializer
    filterset_class = AFilterSet

还有我的serializers.py

class BSerializer(serializers.Serializer):
    date = serializers.DateField()
    quantity = serializers.IntegerField()


class ASerializer(serializers.ModelSerializer):
    b = BSerializer(many=True, source="sku.b_set")

    class Meta(ASerializer.Meta):
        fields = "__all__"

但是,这种方法仍然返回与对象A 相关的每个对象B,而不是过滤掉超出范围过滤器的日期。

【问题讨论】:

    标签: python django django-models django-rest-framework django-filter


    【解决方案1】:

    class Meta 中添加变量depth 如下,reference:

    class AccountSerializer(serializers.ModelSerializer):
        class Meta:
            model = Account
            fields = ['id', 'account_name', 'users', 'created']
            depth = 1
    

    【讨论】: