How to register users in Django REST framework? How to register users in Django REST framework? django django

How to register users in Django REST framework?


Django REST Framework 3 allow override create method in serializers:

from rest_framework import serializersfrom django.contrib.auth import get_user_model # If used custom user modelUserModel = get_user_model()class UserSerializer(serializers.ModelSerializer):    password = serializers.CharField(write_only=True)    def create(self, validated_data):        user = UserModel.objects.create_user(            username=validated_data['username'],            password=validated_data['password'],        )        return user    class Meta:        model = UserModel        # Tuple of serialized model fields (see link [2])        fields = ( "id", "username", "password", )

Serialized fields for classes inherited from ModelSerializer must be declared patently in Meta for Django Rest Framework v3.5 and newest.

File api.py:

from rest_framework import permissionsfrom rest_framework.generics import CreateAPIViewfrom django.contrib.auth import get_user_model # If used custom user modelfrom .serializers import UserSerializerclass CreateUserView(CreateAPIView):    model = get_user_model()    permission_classes = [        permissions.AllowAny # Or anon users can't register    ]    serializer_class = UserSerializer


I went ahead and made my own custom view for handling registration since my serializer doesn't expect to show/retrieve the password. I made the url different from the /users resource.

My url conf:

url(r'^users/register', 'myapp.views.create_auth'),

My view:

@api_view(['POST'])def create_auth(request):    serialized = UserSerializer(data=request.DATA)    if serialized.is_valid():        User.objects.create_user(            serialized.init_data['email'],            serialized.init_data['username'],            serialized.init_data['password']        )        return Response(serialized.data, status=status.HTTP_201_CREATED)    else:        return Response(serialized._errors, status=status.HTTP_400_BAD_REQUEST)

I may be wrong, but it doesn't seem like you'll need to limit permissions on this view since you'd want unauthenticated requests ...


The simplest solution, working in DRF 3.x:

class UserSerializer(serializers.ModelSerializer):    class Meta:        model = User        fields = ('id', 'username', 'password', 'email', 'first_name', 'last_name')        write_only_fields = ('password',)        read_only_fields = ('id',)    def create(self, validated_data):        user = User.objects.create(            username=validated_data['username'],            email=validated_data['email'],            first_name=validated_data['first_name'],            last_name=validated_data['last_name']        )        user.set_password(validated_data['password'])        user.save()        return user

No need for other changes, just make sure that unauthenticated users have the permission to create a new user object.

write_only_fields will make sure passwords (actually: their hash we store) are not displayed, while the overwritten create method ensures that the password is not stored in clear text, but as a hash.