2016-02-12 105 views
0

當兩個串行類聲明具有相同名稱的SerializerMethodField,像這樣:Django的REST框架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) 

崩潰,並顯示以下追蹤:

Traceback (most recent call last): File "/home/ubuntu/venv/superhq_rest/lib/python3.4/site-packages/django/core/handlers/base.py", line 174, in get_response response = self.process_exception_by_middleware(e, request) File "/home/ubuntu/venv/superhq_rest/lib/python3.4/site-packages/django/core/handlers/base.py", line 172, in get_response response = response.render() File "/home/ubuntu/venv/superhq_rest/lib/python3.4/site-packages/django/template/response.py", line 160, in render self.content = self.rendered_content File "/home/ubuntu/venv/superhq_rest/lib/python3.4/site-packages/rest_framework/response.py", line 71, in rendered_content ret = renderer.render(self.data, media_type, context) File "/home/ubuntu/venv/superhq_rest/lib/python3.4/site-packages/rest_framework/renderers.py", line 675, in render context = self.get_context(data, accepted_media_type, renderer_context) File "/home/ubuntu/venv/superhq_rest/lib/python3.4/site-packages/rest_framework/renderers.py", line 618, in get_context raw_data_put_form = self.get_raw_data_form(data, view, 'PUT', request) File "/home/ubuntu/venv/superhq_rest/lib/python3.4/site-packages/rest_framework/renderers.py", line 540, in get_raw_data_form content = renderer.render(serializer.data, accepted, context) File "/home/ubuntu/venv/superhq_rest/lib/python3.4/site-packages/rest_framework/serializers.py", line 503, in data ret = super(Serializer, self).data File "/home/ubuntu/venv/superhq_rest/lib/python3.4/site-packages/rest_framework/serializers.py", line 239, in data self._data = self.to_representation(self.instance) File "/home/ubuntu/venv/superhq_rest/lib/python3.4/site-packages/rest_framework/serializers.py", line 472, in to_representation ret[field.field_name] = field.to_representation(attribute) File "/home/ubuntu/venv/superhq_rest/lib/python3.4/site-packages/rest_framework/fields.py", line 1645, in to_representation return method(value) File "/home/ubuntu/vhosts/superhq_backend/account/serializers.py", line 32, in get_image return self.request.build_absolute_uri(location=instance.image.url) AttributeError: 'NoneType' object has no attribute 'build_absolute_uri'

(我的第一個問題是:如何使痕跡更容易在減價中讀取? =))

這就像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) 

做工精細...

調試顯示調用了APIProfileSerializer和ProfileSerializer,並且致命get_imageProfileSerializer沒有通過request

因此,問題是:WTF ?!我沒有叫這個序列化器!我從來沒有在我的意見中提及它!如何和爲什麼被稱爲?

我堅持用後面的代碼來解決這個問題,但是這裏有一個更好的方法!有什麼建議麼?

回答

0

看來,如果request已經提供給串行背景DRF的ImageField的返回完整的URL,所以沒有必要明確的URL結構。清潔和優雅(需要來源學習 - 雖然官方文檔沒有提到這一點)

1

我還挺解決這樣的:

改變

if instance.image: 

if instance.image and self.request: 

所以這些在引擎罩get_image()調用沒有正確的self.request不會造成死機了。

不過,這將是巨大的,知道爲什麼所有的上述發生地