用户过滤反向关系,并在Django Rest Framework中只返回一个对象

时间:2017-02-13 11:26:26

标签: django django-rest-framework

鉴于这些模型:

class Product(models.Model):
    name = CharField(max_length=255)

class Order(models.Model):
    product = models.ForeignKey(Product)
    user = models.ForeignKey(User)
    quantity = models.PositiveIntegerField()

用户每个产品只能有一个Order对象。我想要一个API调用来显示产品列表,其中包含用户的订单。有没有办法做到这一点?

默认序列化列出order_set下的所有订单。我确实领先于用户进行过滤:

class FilteredOrderSerializer(serialisers.ListSerializer):
    def to_representation(self, data):
        data = data.filter(user=self.context['request'].user)
        return super(FilteredOrderSerializer, self).to_representation(data)


class OrderSerializer(serializers.ModelSerializer):
    class Meta:
        model = Order
        list_serializer_class = FilteredOrderSerializer


class ProductSerializer(serializers.ModelSerializer):
    order_set = OrderSerializer(many=True, read_only=True)

    class Meta:
        model = Product

所以现在它只显示经过身份验证的用户的订单,但生成的JSON看起来像

[
    {
        "name": "prod1",
        "order_set": [
            {
                "quantity": 4
            }
        ],
    }
]

即。该字段仍然被称为order_set并且它是一个列表,而我希望它被称为order并且可以是对象或null。所以我不确定应该在哪里进行过滤,也不确定如何定义字段。

编辑:我正在使用简单的视图集

class ProductViewSet(view sets.ReadOnlyModelViewSet):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer

1 个答案:

答案 0 :(得分:1)

您需要在订单中添加related_name字段,以便

product.orders.all()

然后这应该做。

class Order(models.Model):
    product = models.ForeignKey(Product, related_name='orders')
    user = models.ForeignKey(User)
    quantity = models.PositiveIntegerField()


class ProductSerializer(serializers.ModelSerializer):
    order = serializers.SerializerMethodField()

    class Meta:
        model = Product
        fields = ('name', 'order')

    def get_order(self, object):
        try:
            order = object.orders.get(user=self.context['request'].user)
            return SceneDetailSerializer(order).data
        except Order.DoesNotExist:
            return None

更新:您可以尝试序列化方法字段。不确定self是否包含上下文和用户引用。您需要从订单序列化程序中删除listfield。如果有效,请告诉我。