1

I am trying to get django rest framework user registration working and I am stuck. I have a custom user that adds a field to the django auth user and I am following the first answer on this link but it's giving me a 'KeyError' and I don't really know how to solve it. Any help is appreciated!

Here is my Model:

class CustomUser(models.Model):
    user = models.OneToOneField(User, on_delete = models.CASCADE)
    birthday = models.DateField()

Here the Serializer:

class CustomUserSerilizer(serializers.Serializer):
    birthday = serializers.DateField()

    class Meta:
        model = CustomUser
        fields = ('birthday')

class UserSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True)
    custUser = CustomUserSerilizer(required=False)


    class Meta:
        model = User
        fields = ('username', 'first_name', 'last_name', 'email', 'password', 'custUser')

    def create(self, validated_data):
        profile_data = validated_data.pop('custUser')
        user = User.objects.create(**validated_data)
        user.set_password(validated_data['password'])
        user.save()
        Customer.objects.update_or_create(user=user,**profile_data)
        return user

And the Views:

@api_view(['POST'])
def create_auth(request):
    serialized = UserSerializer(data=request.data)
    if serialized.is_valid():
        serialized.save()
        return Response(serialized.data, status=status.HTTP_201_CREATED)
    else:
        return Response(serialized._errors, status=status.HTTP_400_BAD_REQUEST)

Traceback:

File "C:\Users\admin\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\handlers\exception.py" in inner
  35.             response = get_response(request)

File "C:\Users\admin\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\handlers\base.py" in _get_response
  128.                 response = self.process_exception_by_middleware(e, request)

File "C:\Users\admin\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\handlers\base.py" in _get_response
  126.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "C:\Users\admin\AppData\Local\Programs\Python\Python36\lib\site-packages\django\views\decorators\csrf.py" in wrapped_view
  54.         return view_func(*args, **kwargs)

File "C:\Users\admin\AppData\Local\Programs\Python\Python36\lib\site-packages\django\views\generic\base.py" in view
  69.             return self.dispatch(request, *args, **kwargs)

File "C:\Users\admin\AppData\Local\Programs\Python\Python36\lib\site-packages\rest_framework\views.py" in dispatch
  494.             response = self.handle_exception(exc)

File "C:\Users\admin\AppData\Local\Programs\Python\Python36\lib\site-packages\rest_framework\views.py" in handle_exception
  454.             self.raise_uncaught_exception(exc)

File "C:\Users\admin\AppData\Local\Programs\Python\Python36\lib\site-packages\rest_framework\views.py" in dispatch
  491.             response = handler(request, *args, **kwargs)

File "C:\Users\admin\AppData\Local\Programs\Python\Python36\lib\site-packages\rest_framework\decorators.py" in handler
  53.             return func(*args, **kwargs)

File "C:\Projects\djangoproject\app\test\views.py" in create_auth
  46.         serialized.save()

File "C:\Users\admin\AppData\Local\Programs\Python\Python36\lib\site-packages\rest_framework\serializers.py" in save
  214.             self.instance = self.create(validated_data)

File "C:\Projects\djangoproject\app\test\serializers.py" in create
  27.         profile_data = validated_data.pop('custUser')

Exception Type: KeyError at /users/register
Exception Value: 'custUser'
Adrian
  • 198
  • 4
  • 16

1 Answers1

0
custUser = CustomUserSerilizer(required=False)

So, user may or may not pass field custUser as payload. As it is required=False it simply pass the is_valid() but in profile_data = validated_data.pop('custUser') raise KeyError because the payload does not contains any field custUser. To avoid this error apply check in def create(self, validated_data). Something like that

if custUser in validated_data:
     profile_data = validated_data.pop('custUser')

However, From your model definition (CustomUser) birthday should be a mandatory field. But I don't know why in Serializer you have kept that birthday. I hope by making required=False will solve your problem.

Saiful Azad
  • 1,823
  • 3
  • 17
  • 27
  • OK, I get what you say now. The thing is the field has to be compulsory. When I do required=True and I pass this json `{"username":"something","password":"pass","first_name":"Test","last_name":"Testing","email":"a@a.com","birthday":"2011-01-01"}` I get `"custUser": [ "This field is required." ]` Let me modify my question – Adrian Apr 16 '18 at 17:11
  • Your payload is not correct. It should be `{"username":"something","password":"pass","first_name":"Test","last_name":"Testing","email":"a@a.com","custUser":{"birthdate":"2011-01-01"}}` – Saiful Azad Apr 16 '18 at 17:17
  • Then I deserve an acceptance and upvote. It encourages the user more. – Saiful Azad Apr 17 '18 at 02:33
  • Can you update your answer to include the right payload? – Adrian Apr 17 '18 at 09:36