2016-02-12 6 views
0

Когда два класса Serializer объявить SerializerMethodField с таким же названием, как это:Джанго рамки остальное 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:

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'

(мой первый вопрос: как сделать traceback более читаемым в уценке? =))

Это как request не был принят в Serializer

однако это

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) 

отлично работает ...

Debugging покажите, что BOTH APIProfileSerializer и ProfileSerializer вызываются, и авария вызвана вызовом get_image в ProfileSerializer без пропуска request к нему

Итак, вопрос: WTF ?! Я не назвал этот сериализатор! Я даже не упоминал об этом в своих взглядах! Как и по какой причине это называется?

Я придерживаюсь последней части кода, чтобы решить эту проблему, но должен быть лучший способ! Какие-либо предложения?

ответ

0

Оказывается, что ImageField ФПИ возвращает полный URL, если request был предоставлен контекст сериализатора, поэтому нет необходимости в явном построении URL. Чистый и элегантный (требует изучения источника, хотя - в официальной документации это не упоминается)

1

я вроде решил так:

изменил

if instance.image: 

в

if instance.image and self.request: 

поэтому они под капотом get_image() звонки без надлежащего self.request не вызывают аварий больше.

Тем не менее, это было бы здорово, чтобы узнать, почему все вышеперечисленное имеет место

Смежные вопросы