Django rest framework create user with password

Using django-rest-framework 3 and django 1.8

I am trying to create a user using django-rest-framework ModelViewSerializer. the problem is that the default objects.create method used by DRF leaves the password as plain text.

The problem is that the DRF serial file creation method uses the objects.create querysets / # create method instead of using the objects.create_user method.

serializers.py code line 775

 instance = ModelClass.objects.create(**validated_data) 

What is the best solution for this? I can override the serializer.create method to use objects.user_create instead of objects.create, but it doesn't look like the right solution.

rest of code:

 from django.contrib.auth.models import User from rest_framework import viewsets class UserSerializer(serializers.ModelSerializer): class Meta: model = User fields = ('username', 'email','password') write_only_fields = ('password',) class UserViewSet(viewsets.ModelViewSet): queryset = User.objects.all() serializer = UserSerializer() 
+11
source share
3 answers

you can override create in UserSerilizer:

 class UserSerializer(serializers.ModelSerializer): # .... def create(self, validated_data): user = User.objects.create_user(**validated_data) return user 

other solutions can override perform_create in the ViewSet class, or you can write your own create method in your view class

 class UserViewSet(viewsets.ModelViewSet): def create(self, request, format=None): # create user here # do not call seriailzer.save() 

UPDATE: after @freethebees comment, perform_create override is also canceled, so here is the code snippet:

 class UserViewSet(viewsets.ModelViewSet, mixins.CreateModelMixin): def perform_create(self, serializer): # use User.objects.create_user to create user pass 

Note : this answer gives 3 solutions, choose the one that you think best fits your needs and the ecosystem of your project.

NOTE 2 I personally prefer to override create in a UserViewSet (second code snippet), because you can simply return your custom Response (for example, return a user profile after logging in)

+17
source

There is an even better option for password verification in serializer

 from django.contrib.auth.hashers import make_password class UserSerializer(serializers.ModelSerializer): def validate_password(self, value: str) -> str: return make_password(value) 
+6
source

In addition to @aliva's answer, where you are missing functionality in serializers.Modelserializer.create() (which would be nice to keep, for example, handles many-to-many relationships), there is a way to keep this.

Using the user.set_password() method, the password can also be set correctly, for example:

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

This has the advantage of retaining the functionality of the superclass, but is the disadvantage of additional writing to the database. Decide which tradeoff is more important to you :-).

Edit: Fix syntax error

+5
source

Source: https://habr.com/ru/post/985510/


All Articles