django rest framework SerializerMethodField离奇行为

时间:2016-02-12 15:02:57

标签: django django-rest-framework

当两个序列化程序类声明具有相同名称的SerializerMethodField时,如下所示:

class APIProfileSerializer(serializers.ModelSerializer):
    def __init__(self, *args, **kwargs):

        super(APIProfileSerializer, self).__init__(*args, **kwargs)
        self.request = request

    def get_image(self, instance):

        if instance.image:
            return self.request.build_absolute_uri(location=instance.image.url)
        return None

    image = serializers.SerializerMethodField()

    # other ProfileSerializer fields

    class Meta:
        model = User
        fields = ('image')



class ProfileSerializer(serializers.ModelSerializer):
    def __init__(self, *args, **kwargs):

        super(ProfileSerializer, self).__init__(*args, **kwargs)
        self.request = request

    def get_image(self, instance):

        if instance.image:
            return self.request.build_absolute_uri(location=instance.image.url)
        return None

    image = serializers.SerializerMethodField()

    # other ProfileSerializer fields

    class Meta:
        model = User
        fields = ('image')

代码

serializer = APIProfileSerializer(instance=request.user, request=request)
return Response(data=serializer.data)

使用以下回溯崩溃:

  

追踪(最近一次通话):     文件" /home/ubuntu/venv/superhq_rest/lib/python3.4/site-packages/django/core/handlers/base.py" ;,第174行,在get_response中       response = self.process_exception_by_middleware(e,request)     文件" /home/ubuntu/venv/superhq_rest/lib/python3.4/site-packages/django/core/handlers/base.py" ;,第172行,在get_response中       response = response.render()     文件" /home/ubuntu/venv/superhq_rest/lib/python3.4/site-packages/django/template/response.py" ;,第160行,渲染       self.content = self.rendered_content     文件" /home/ubuntu/venv/superhq_rest/lib/python3.4/site-packages/rest_framework/response.py",第71行,在rendered_content中       ret = renderer.render(self.data,media_type,context)     文件" /home/ubuntu/venv/superhq_rest/lib/python3.4/site-packages/rest_framework/renderers.py" ;,第675行,渲染       context = self.get_context(data,accepted_media_type,renderer_context)     文件" /home/ubuntu/venv/superhq_rest/lib/python3.4/site-packages/rest_framework/renderers.py",第618行,在get_context中       raw_data_put_form = self.get_raw_data_form(数据,视图,' PUT',请求)     文件" /home/ubuntu/venv/superhq_rest/lib/python3.4/site-packages/rest_framework/renderers.py",第540行,在get_raw_data_form中       content = renderer.render(serializer.data,accepted,context)     文件" /home/ubuntu/venv/superhq_rest/lib/python3.4/site-packages/rest_framework/serializers.py" ;,第503行,数据       ret = super(Serializer,self).data     文件" /home/ubuntu/venv/superhq_rest/lib/python3.4/site-packages/rest_framework/serializers.py" ;,第239行,数据       self._data = self.to_representation(self.instance)     文件" /home/ubuntu/venv/superhq_rest/lib/python3.4/site-packages/rest_framework/serializers.py" ;,第472行,在to_representation中       ret [field.field_name] = field.to_representation(属性)     文件" /home/ubuntu/venv/superhq_rest/lib/python3.4/site-packages/rest_framework/fields.py" ;,第1645行,在to_representation中       返回方法(值)     文件" /home/ubuntu/vhosts/superhq_backend/account/serializers.py",第32行,在get_image中       return self.request.build_absolute_uri(location = instance.image.url)   AttributeError:' NoneType'对象没有属性' build_absolute_uri'

(我的第一个问题是:如何在markdown中使追溯更具可读性?=))

就像request没有传递给序列化程序

但是,这个

serializer = ProfileSerializer(instance=request.user, request=request)
return Response(data=serializer.data)

和这个

serializer = APIProfileSerializer(instance=request.user,request=request)
_data = serializer.data,
return Response(data=_data)

工作得很好......

调试显示调用BOTH APIProfileSerializer和ProfileSerializer,并且get_image中调用ProfileSerializer而不将request传递给它

导致崩溃

所以,问题是:WTF?!我没有打电话给这个序列化器!我从未在我的观点中提到它!如何以及为什么被称为是什么原因?

我坚持使用后一个代码来解决这个问题,但必须有更好的方法!有什么建议吗?

2 个答案:

答案 0 :(得分:1)

我有点像这样解决了:

改变

  SELECT Count(*) AS answered, 
DATE_ADD(MAKEDATE(Year(score_datetime), 1), INTERVAL Week(score_datetime) WEEK) AS week, 
       Year(score_datetime) AS year 
    FROM   development.score 
    WHERE  score_datetime IS NOT NULL 
    GROUP  BY Week(score_datetime) 
    ORDER  BY answered DESC 
    LIMIT  5;

if instance.image:

所以这些没有正确的if instance.image and self.request: 的{​​{1}}调用不会导致崩溃。

但是,知道为什么会发生以上所有事情会很棒

答案 1 :(得分:0)

如果已向序列化程序上下文提供request,则DRF的ImageField似乎返回完整的URL,因此不需要显式URL构造。干净优雅(需要来源研究 - 官方文档没有提到这一点)