Rest Framework Serializer方法

jas*_*son 10 django django-models django-rest-framework

我有以下使用Django REST Framework的 Serializer .

这就是我到目前为止......

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))
Run Code Online (Sandbox Code Playgroud)

urls.py

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

这段代码存在一些问题.

1)pram pk = 19是硬编码的应该是self.kwargs['profile_id'].我尝试过但尝试过,但我不知道如何将kwarg传递给方法并且无法使profile_id工作.即我无法从网址获取.

2)这些代码中是否有任何代码?我已经尝试添加模型,但再次可以通过args.

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)
Run Code Online (Sandbox Code Playgroud)

Tom*_*tie 21

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

view = self.context['view']
profile_id = int(view.kwargs['profile_id'])
Run Code Online (Sandbox Code Playgroud)

但是在这种情况下,我不认为你需要这样做,因为'obj'在任何情况下都会被设置为配置文件实例.

是的,您可以将'get_this_score'方法放在模型类上.你仍然需要'SerializerMethodField',但它只是调用'return obj.get_this_score(...)',从序列化器上下文设置任何参数.

请注意,序列化程序上下文还将包含"请求",因此您还可以根据需要访问"request.user".


Eme*_*eka 7

要回答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))
Run Code Online (Sandbox Code Playgroud)