Django Rest Framework registrations

2019-08-24 04:02发布

I have a custom user model

class User(AbstractUser):

    username = None    
    email = models.EmailField( unique=True)    
    phone = models.CharField( max_length=15) 
    is_pro = models.BooleanField(default=False)    

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['phone']

    objects = UserManager()

    @property
    def token(self):
    """
    Allows us to get a user's token by calling `user.token` instead of
        `user.generate_jwt_token().

    The `@property` decorator above makes this possible. `token` is called
    a "dynamic property".
    """
        return self._generate_jwt_token()

    def _generate_jwt_token(self):
        """
        Generates a JSON Web Token that stores this user's ID and has an expiry
        date set to 60 days into the future.
        """
        import jwt
        from datetime import datetime, timedelta
        from django.conf import settings
        dt = datetime.now() + timedelta(days=60)

        token = jwt.encode({
            'id': self.pk,
            'exp': int(dt.strftime('%s'))
        }, settings.SECRET_KEY, algorithm='HS256')

        return token.decode('utf-8')

Now I try make SignIn API with Django Rest Framework using this tutorial https://thinkster.io/tutorials/django-json-api/authentication

serializer.py

class RegistrationSerializer(serializers.ModelSerializer):

    password = serializers.CharField(
        max_length=128,
        min_length=8,
        write_only=True
    )


    token = serializers.CharField(max_length=255, read_only=True)

    class Meta:
        model = User

        fields = ['email', 'phone', 'password', 'token']

    def create(self, validated_data):
        # Use the `create_user` method we wrote earlier to create a new user.
        return User.objects.create_user(**validated_data)

views.py

class RegistrationAPIView(APIView):
    # Allow any user (authenticated or not) to hit this endpoint.
    permission_classes = (AllowAny,)    
    serializer_class = RegistrationSerializer

    def post(self, request):
        user = request.data.get('user', {})

        serializer = self.serializer_class(data=user)
        serializer.is_valid(raise_exception=True)
        serializer.save()

        return Response(serializer.data, status=status.HTTP_201_CREATED)

Then I create a new user an error occured "This field is required." for all my User fields, like email, phone, password. Screenshot picture http://joxi.ru/12MOMkZt4eeBEr

1条回答
做自己的国王
2楼-- · 2019-08-24 04:53

This is because you set this fields not nullable and required inside User model. To fix it you can add blank=True arguments to the fields which may be blank, like phone:

class User(AbstractUser):

    username = None    
    email = models.EmailField(unique=True)    
    phone = models.CharField(max_length=15, blank=True) 
    is_pro = models.BooleanField(default=False)    

After this run makemigrations and migrate to apply changes at DB level.

UPD

In view you need to get data from request.data directly:

def post(self, request):
    serializer = self.serializer_class(data=request.data)
    serializer.is_valid(raise_exception=True)
    serializer.save()

    return Response(serializer.data, status=status.HTTP_201_CREATED)

request.data doesn't contain user key, so request.data.get('user', {}) return empty dict.

查看更多
登录 后发表回答