web-dev-qa-db-fra.com

Comment créer un nouvel utilisateur avec Django repos framework et modèle d'utilisateur personnalisé

J'ai un modèle d'utilisateur personnalisé et j'utilise Django-rest-framework pour créer une API

models.py:

class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(
        unique=True,
        max_length=254,
    )
    first_name = models.CharField(max_length=15)
    last_name = models.CharField(max_length=15)
    mobile = models.IntegerField(unique=True)
    date_joined = models.DateTimeField(default=timezone.now)
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)

serializers.py:

class UserSerializer(serializers.ModelSerializer):
    password1 = serializers.CharField(write_only=True)
    password2 = serializers.CharField(write_only=True)

    class Meta:
        model = User
        fields = ('first_name', 'last_name', 'email', 'mobile', 'password1', 'password2')

views.py:

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

Cependant, lorsque j'essaie de créer un nouvel utilisateur, j'obtiens cette erreur:

Vous avez un TypeError lors de l'appel de User.objects.create(). Cela peut être dû au fait que vous avez un champ accessible en écriture sur la classe sérialiseur qui n'est pas un argument valide pour User.objects.create(). Vous devrez peut-être rendre le champ en lecture seule ou remplacer la méthode UserSerializer.create () pour gérer cela correctement.

Cela peut être dû au fait qu'il n'y a pas de champs password1 ou password2 dans le modèle utilisateur. Mais alors, comment puis-je créer une API pour créer un nouvel utilisateur en utilisant Django-rest-framework?

13
Aamu

Je pense qu'un champ de mot de passe suffit. Si vous souhaitez vérifier que le mot de passe saisi deux fois par l'utilisateur est le même, faites-le dans le frontal. Vous pouvez remplacer une méthode create du sérialiseur comme suit.

from rest_framework import serializers

class UserSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True)

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

    def create(self, validated_data):
        user = super(UserSerializer, self).create(validated_data)
        user.set_password(validated_data['password'])
        user.save()
        return user

views.py

from rest_framework import generics
from rest_framework.permissions import AllowAny
from .models import User
from .serializers import UserSerializer

class UserCreateAPIView(generics.CreateAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = (AllowAny,)
27
Xiao