【问题标题】:Rest Framework Serializer MethodRest Framework 序列化器方法
【发布时间】:2013-02-02 00:18:43
【问题描述】:

我有以下使用Django REST Framework 的序列化程序。

这就是我目前所拥有的......

serializer.py

class ProductSerializer(serializers.ModelSerializer):

    score = serializers.SerializerMethodField('get_this_score')

    class Meta:
        model = Product
        fields = ('id', 'title', 'active', 'score')

    def get_this_score(self, obj):

        profile = Profile.objects.get(pk=19)
        score = [val for val in obj.attribute_answers.all() if val in profile.attribute_answers.all()]
        return (len(score))

urls.py

 url(r'^products/(?P<profile_id>.+)/$', ProductListScore.as_view(), name='product-list-score'),

这段代码的 sn-p 存在一些问题。

1) 婴儿车 pk=19 是硬编码的,它应该是 self.kwargs['profile_id']. 我已经尝试过并尝试过,但我不知道如何将 kwarg 传递给方法并且无法让 profile_id 工作。即我无法从 url 获取它。

2) 这些代码是否应该在模型中?我已经尝试添加到模型,但再次可以传递参数。

models.py 即方法类

     def get_score(self, profile):

        score = [val for val in self.attribute_answers.all() if val in 
profile.attribute_answers.all()]
            return len(score)

【问题讨论】:

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


    【解决方案1】:

    序列化器被传递一个上下文字典,其中包含视图实例,因此您可以通过执行以下操作来获取 profile_id:

    view = self.context['view']
    profile_id = int(view.kwargs['profile_id'])
    

    但是在这种情况下,我认为您不需要这样做,因为在任何情况下都会将“obj”设置为配置文件实例。

    是的,您可以将“get_this_score”方法放在模型类上。您仍然需要“SerializerMethodField”,但它会简单地调用“return obj.get_this_score(...)”,从序列化程序上下文中设置任何参数。

    请注意,序列化程序上下文还将包含“请求”,因此您还可以根据需要访问“请求.用户”。

    【讨论】:

    • 我喜欢在模型中加入这个的想法。但是使用 source= 的 SerializerMethodField 不允许我通过参数。你能给我一个使用 SerializerMethodField 并将请求参数和对象传递给模型方法的例子吗?这真的有助于我理解。谢谢你。
    • 我加入@jason的问题
    • However in this case I don't think you need to do that as 'obj' will in any case be set to the profile instance 中你的意思是Product 实例吗?
    【解决方案2】:

    要回答 jason 对 Tom 的回答的问题,您可以像这样通过相同的上下文机制访问请求对象。您从 ModelMethod 定义中引用请求对象,而不是传递它们。我可以使用它来访问当前的 request.user 对象,如下所示:

    class ProductSerializer(serializers.ModelSerializer):
        score = serializers.SerializerMethodField('get_this_score')
    
        class Meta:
            model = Product
            fields = ('id', 'title', 'active', 'score')
    
        def get_this_score(self, obj):
    
            profile = self.context['request'].user
            score = [val for val in obj.attribute_answers.all() if val in profile.attribute_answers.all()]
            return (len(score))
    

    【讨论】:

    • 当我将此序列化程序与 CBV 一起使用时,它工作正常,但当我将此序列化程序与 FBV return Response({'data':ProductSerializer(user_profiles,many=True).data}) 一起使用时,我收到了 keyerror 请求
    猜你喜欢
    • 2015-09-25
    • 2018-10-18
    • 2015-06-29
    • 2016-04-10
    • 1970-01-01
    • 2015-10-14
    • 1970-01-01
    • 2017-07-28
    • 2018-06-23
    相关资源
    最近更新 更多