Im using Django Rest Framework to create a view that verifies an otp. Currently, it works just fine. models.py
class User(AbstractUser):
phone_number = PhoneNumberField(blank=True)
def __str__(self) -> str:
return f"{self.username}"
views.py
class VerifyOTPCode(APIView):
permission_classes=[AllowAny]
def post(self, request):
serializer = UserOTPCodeSerializer(data=request.data)
if serializer.is_valid():
user = serializer.save()
return Response(serializer.validated_data, status=status.HTTP_201_CREATED)
return Response(serializer.errors)
serializers.py
class UserOTPCodeSerializer(serializers.ModelSerializer):
code = serializers.IntegerField()
class Meta:
model = User
fields = ("first_name", "last_name", "email", "phone_number", "code")
def validate(self, data):
code, phone_number = str(data['code']), data['phone_number']
if is_six_digits(code) and is_otp_approved(code, phone_number):
return data
raise serializers.ValidationError('Code was not approved')
def create(self, validated_data):
del validated_data['code']
return User.objects.create(**validated_data)
However, I want to use a generic for the view instead, so I tried refactoring it into the following
views.py
class VerifyOTPCode(generics.CreateAPIView):
permission_classes= [AllowAny]
serializer_class= UserOTPCodeSerializer
Now, when I try to hit the endpoint, I get an error at create
, that the User
object has no attribute code
, even though create
removes code
from validated_data
, and another thing is that even with the error, a User object still does get created. Why is this error occurring and how can I fix it?
Internal Server Error: /user/register/verify-otp/
Traceback (most recent call last):
File "C:\Users\61403\AppData\Local\Programs\Python\Python310\lib\site-packages\rest_framework\fields.py", line 457, in get_attribute
return get_attribute(instance, self.source_attrs)
File "C:\Users\61403\AppData\Local\Programs\Python\Python310\lib\site-packages\rest_framework\fields.py", line 97, in get_attribute
instance = getattr(instance, attr)
AttributeError: 'User' object has no attribute 'code'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\61403\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
response = get_response(request)
File "C:\Users\61403\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\handlers\base.py",
line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\61403\AppData\Local\Programs\Python\Python310\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "C:\Users\61403\AppData\Local\Programs\Python\Python310\lib\site-packages\django\views\generic\base.py",
line 70, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\61403\AppData\Local\Programs\Python\Python310\lib\site-packages\rest_framework\views.py", line
509, in dispatch
response = self.handle_exception(exc)
File "C:\Users\61403\AppData\Local\Programs\Python\Python310\lib\site-packages\rest_framework\views.py", line
469, in handle_exception
self.raise_uncaught_exception(exc)
File "C:\Users\61403\AppData\Local\Programs\Python\Python310\lib\site-packages\rest_framework\views.py", line
480, in raise_uncaught_exception
raise exc
File "C:\Users\61403\AppData\Local\Programs\Python\Python310\lib\site-packages\rest_framework\views.py", line
506, in dispatch
response = handler(request, *args, **kwargs)
File "C:\Users\61403\AppData\Local\Programs\Python\Python310\lib\site-packages\rest_framework\generics.py", line 190, in post
return self.create(request, *args, **kwargs)
File "C:\Users\61403\AppData\Local\Programs\Python\Python310\lib\site-packages\rest_framework\mixins.py", line 20, in create
headers = self.get_success_headers(serializer.data)
File "C:\Users\61403\AppData\Local\Programs\Python\Python310\lib\site-packages\rest_framework\serializers.py", line 555, in data
ret = super().data
File "C:\Users\61403\AppData\Local\Programs\Python\Python310\lib\site-packages\rest_framework\serializers.py", line 253, in data
self._data = self.to_representation(self.instance)
File "C:\Users\61403\AppData\Local\Programs\Python\Python310\lib\site-packages\rest_framework\serializers.py", line 509, in to_representation
attribute = field.get_attribute(instance)
File "C:\Users\61403\AppData\Local\Programs\Python\Python310\lib\site-packages\rest_framework\fields.py", line 490, in get_attribute
raise type(exc)(msg)
AttributeError: Got AttributeError when attempting to get a value for field `code` on serializer `UserOTPCodeSerializer`.
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 'code'.
Internal Server Error: /user/register/verify-otp/
Traceback (most recent call last):
File "C:\Users\61403\AppData\Local\Programs\Python\Python310\lib\site-packages\rest_framework\fields.py", line 457, in get_attribute
return get_attribute(instance, self.source_attrs)
File "C:\Users\61403\AppData\Local\Programs\Python\Python310\lib\site-packages\rest_framework\fields.py", line 97, in get_attribute
instance = getattr(instance, attr)
AttributeError: 'User' object has no attribute 'code'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\61403\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
response = get_response(request)
File "C:\Users\61403\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\handlers\base.py",
line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\61403\AppData\Local\Programs\Python\Python310\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "C:\Users\61403\AppData\Local\Programs\Python\Python310\lib\site-packages\django\views\generic\base.py",
line 70, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\61403\AppData\Local\Programs\Python\Python310\lib\site-packages\rest_framework\views.py", line
509, in dispatch
response = self.handle_exception(exc)
File "C:\Users\61403\AppData\Local\Programs\Python\Python310\lib\site-packages\rest_framework\views.py", line
469, in handle_exception
self.raise_uncaught_exception(exc)
File "C:\Users\61403\AppData\Local\Programs\Python\Python310\lib\site-packages\rest_framework\views.py", line
480, in raise_uncaught_exception
raise exc
File "C:\Users\61403\AppData\Local\Programs\Python\Python310\lib\site-packages\rest_framework\views.py", line
506, in dispatch
response = handler(request, *args, **kwargs)
File "C:\Users\61403\AppData\Local\Programs\Python\Python310\lib\site-packages\rest_framework\generics.py", line 190, in post
return self.create(request, *args, **kwargs)
File "C:\Users\61403\AppData\Local\Programs\Python\Python310\lib\site-packages\rest_framework\mixins.py", line 20, in create
headers = self.get_success_headers(serializer.data)
File "C:\Users\61403\AppData\Local\Programs\Python\Python310\lib\site-packages\rest_framework\serializers.py", line 555, in data
ret = super().data
File "C:\Users\61403\AppData\Local\Programs\Python\Python310\lib\site-packages\rest_framework\serializers.py", line 253, in data
self._data = self.to_representation(self.instance)
File "C:\Users\61403\AppData\Local\Programs\Python\Python310\lib\site-packages\rest_framework\serializers.py", line 509, in to_representation
attribute = field.get_attribute(instance)
File "C:\Users\61403\AppData\Local\Programs\Python\Python310\lib\site-packages\rest_framework\fields.py", line 490, in get_attribute
raise type(exc)(msg)
AttributeError: Got AttributeError when attempting to get a value for field `code` on serializer `UserOTPCodeSerializer`.
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 'code'.
CodePudding user response:
You have to use write_only=True
. Like this:
code = serializers.IntegerField(write_only=True)