Django的REST框架SerializerMethodField怪异行为
当两个串行类声明具有相同名称的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_image
在ProfileSerializer
没有通过request
它
因此,问题是:WTF ?!我没有叫这个序列化器!我从来没有在我的意见中提及它!如何和为什么被称为?
我坚持用后面的代码来解决这个问题,但是这里有一个更好的方法!有什么建议么?
看来,如果request
已经提供给串行背景DRF的ImageField的返回完整的URL,所以没有必要明确的URL结构。清洁和优雅(需要来源学习 - 虽然官方文档没有提到这一点)
我还挺解决这样的:
改变
if instance.image:
到
if instance.image and self.request:
所以这些在引擎罩get_image()
调用没有正确的self.request
不会造成死机了。
不过,这将是巨大的,知道为什么所有的上述发生地