【问题标题】:Dynamical serialization with Django REST使用 Django REST 进行动态序列化
【发布时间】:2024-05-18 17:00:02
【问题描述】:

我有一个Person 模型和Address 模型。一个person 可以有多个地址,所以Address 模型看起来像:

Address(models.Model):
    person = models.ForeignKey(Person, related_name="addresses")
    ...

我想序列化一个person 实例,我做最简单的事情:

PersonSerializer(serializers.ModelSerializer):
    class Meta:
        fields = (..., "addresses", ...)

但是,假设我想根据当前的request.user序列化addresses,让不同的当前users查看不同的地址集,我应该如何修改代码?

【问题讨论】:

    标签: django serialization django-rest-framework


    【解决方案1】:

    如果您为详细视图执行此操作,您也应该为地址模型实现一个序列化程序。有关嵌套序列化程序关系,请参阅 this example。另外,在您的 api 视图中,您必须根据 request.user 进行查询。

    如果您为列表视图执行此操作,PersonSerializer 应该有一个 SerializerMethodField。这样,用户将能够看到自己的地址,而无法看到其他人的地址。

    class PersonSerializer(serializers.ModelSerializer):
        addresses = serializers.SerializerMethodField('get_addresses')
    
        class Meta:
            fields = (..., "addresses", ...)
    
        def get_addresses(self, obj):
            if obj.pk != self.context['request'].user.pk:
                return ""
            else:
                return obj.addresses
    

    P.S:我假设您的自定义用户模型是 Person,因为您没有提供太多信息。

    【讨论】:

    • 请记住,序列化程序在设计上也应该在请求/响应周期之外工作。它并不总是有可用的请求对象。
    • 完美,SerializerMethodField 是我想要的。
    【解决方案2】:

    我假设您想要一个像 /user/current/ 这样的静态端点,它为您提供当前请求用户的 Person 对象 + 关联的地址记录。添加这样的视图:

    class CurrentUser(GenericAPIView):
        model = Person
        serializer_class = PersonSerializer
        permission_classes = (permissions.IsAuthenticated,)
    
        def get(self, request):
            return Response(self.get_serializer(request.user).data)
    

    只有在用户不是匿名的情况下才能访问它,并且将使用您的 PersonSerializer 转储出请求用户。如果您相应地设置“地址”序列化器字段,则相关的地址记录会随心所欲地出现,如下所述:

    http://www.django-rest-framework.org/api-guide/relations/#nested-relationships

    【讨论】:

      最近更新 更多