Django / DRF:为什么我的非模型序列化器会出现模型错误?

时间:2017-06-02 16:30:53

标签: django django-rest-framework

我有一个简单的API端点。它需要两个与我的系统中没有模型匹配的帖子参数:user_idcode

我的序列化器:

class ConfirmationCodeSerializer(serializers.Serializer):
    user_id = serializers.CharField(max_length=36)
    code = serializers.CharField(max_length=7)

    def validate(self, attrs):
        try:
            user = User.objects.get(pk=attrs['user_id'])
        except (ValidationError, User.DoesNotExist):
            raise serializers.ValidationError("invalid user_id")
        try:
            confirmation_code = SignupConfirmationCode.objects.get(
                    user_id=attrs['user_id'])
        except (ValidationError, SignupConfirmationCode.DoesNotExist):
            raise serializers.ValidationError("confirmation record not found")

        if confirmation_code.code != attrs['code']:
            raise serializers.ValidationError("incorrect user_id and/or code")

        if user.is_active:
            raise serializers.ValidationError("user already confirmed")

        return attrs

    def create(self, validated_data):
        print(validated_data)
        user = User.objects.get(pk=validated_data['user_id'])
        user.is_active = True
        user.save()
        confirmation_code = SignupConfirmationCode.objects.get(
            user_id=user.id)
        confirmation_code.delete()
        return user

我的观点:

class confirmation_code(APIView):
    """
    send confirmation code to validate and activate a new user
    account
    """
    permission_classes = ([AllowAny])

    def post(selfself, request, format=None):
        serializer = ConfirmationCodeSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

当它运行时 - 它完成它的工作,确认代码被删除,用户记录被更新,但我收到了这个错误:

AttributeError: Got AttributeError when attempting to get a value for field `user_id` on serializer `ConfirmationCodeSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `User` instance.
Original exception text was: 'User' object has no attribute 'user_id'.

我的问题是,为什么系统会尝试将user_id(我的帖子参数之一)强制转换为未在类元数据中定义的User模型,我该怎么办?它?

完整的Stacktrace:

internal Server Error: /int_api/v1/signup/confirmationcode/
Traceback (most recent call last):
  File "/Users/my_name/dev/my_app-t2/my_app_backend/venv/lib/python3.6/site-packages/rest_framework/fields.py", line 445, in get_attribute
    return get_attribute(instance, self.source_attrs)
  File "/Users/my_name/dev/my_app-t2/my_app_backend/venv/lib/python3.6/site-packages/rest_framework/fields.py", line 104, in get_attribute
    instance = getattr(instance, attr)
AttributeError: 'User' object has no attribute 'user_id'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/my_name/dev/my_app-t2/my_app_backend/venv/lib/python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "/Users/my_name/dev/my_app-t2/my_app_backend/venv/lib/python3.6/site-packages/django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/Users/my_name/dev/my_app-t2/my_app_backend/venv/lib/python3.6/site-packages/django/core/handlers/base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/my_name/dev/my_app-t2/my_app_backend/venv/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
    return view_func(*args, **kwargs)
  File "/Users/my_name/dev/my_app-t2/my_app_backend/venv/lib/python3.6/site-packages/django/views/generic/base.py", line 68, in view
    return self.dispatch(request, *args, **kwargs)
  File "/Users/my_name/dev/my_app-t2/my_app_backend/venv/lib/python3.6/site-packages/rest_framework/views.py", line 489, in dispatch
    response = self.handle_exception(exc)
  File "/Users/my_name/dev/my_app-t2/my_app_backend/venv/lib/python3.6/site-packages/rest_framework/views.py", line 449, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/Users/my_name/dev/my_app-t2/my_app_backend/venv/lib/python3.6/site-packages/rest_framework/views.py", line 486, in dispatch
    response = handler(request, *args, **kwargs)
  File "/Users/my_name/dev/my_app-t2/my_app_backend/v1_int_api/views.py", line 83, in post
    return Response(serializer.data, status=status.HTTP_200_OK)
  File "/Users/my_name/dev/my_app-t2/my_app_backend/venv/lib/python3.6/site-packages/rest_framework/serializers.py", line 534, in data
    ret = super(Serializer, self).data
  File "/Users/my_name/dev/my_app-t2/my_app_backend/venv/lib/python3.6/site-packages/rest_framework/serializers.py", line 263, in data
    self._data = self.to_representation(self.instance)
  File "/Users/my_name/dev/my_app-t2/my_app_backend/venv/lib/python3.6/site-packages/rest_framework/serializers.py", line 488, in to_representation
    attribute = field.get_attribute(instance)
  File "/Users/my_name/dev/my_app-t2/my_app_backend/venv/lib/python3.6/site-packages/rest_framework/fields.py", line 464, in get_attribute
    raise type(exc)(msg)
AttributeError: Got AttributeError when attempting to get a value for field `user_id` on serializer `ConfirmationCodeSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `User` instance.
Original exception text was: 'User' object has no attribute 'user_id'.

1 个答案:

答案 0 :(得分:0)

这是因为您使用create方法返回用户实例。 通过default to_representation方法尝试使用serilizer字段(在您的情况下为user_id和代码)序列化createupdate方法的结果。

要修复错误,请尝试定义to_representation,如下所示:

def to_representation(self, instance):
    serializer = UserSerializer(instance)
    return serializer.data