Using django-rest-framework 3 and django 1.8
I am trying to create a user using django-rest-framework ModelViewSerializer. problem is that the default objects.create method used by DRF leave the password as plain text.
The problem is that DRF serialzer create method is using objects.create
querysets/#create method instead of using objects.create_user
method.
code from serializers.py 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 does not feel 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()
Here we will use a library called django-rest-passwordreset for creating Reset or Forgot Password API using Django Rest Framework. In models.py add following signal for sending email. Now copy that token which comes in email and and post token and password to /api/password_reset/confirm/ api url.
Programmatically, you can create / save a new User without a password argument, and it will not raise any exceptions. In fact, you can even create a user without any arguments.
you can override create
in UserSerializer:
class UserSerializer(serializers.ModelSerializer):
# ....
def create(self, validated_data):
user = User.objects.create_user(**validated_data)
return user
other solutions can be overriding perform_create
in ViewSet class or you can write your own create
method in your viewset class
class UserViewSet(viewsets.ModelViewSet):
def create(self, request, format=None):
# create user here
# do not call seriailzer.save()
UPDATE: after @freethebees commented, overriding perform_create
also works, 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 you think it better fits your needs and your project's ecosystem
NOTE 2
I personally prefer overriding create
in UserViewSet
(second code snippet) because there you can simply return your custom Response
(for example return user profile after login)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With