In django, creating a User has a different and unique flow from the usual Model instance creation. You need to call create_user()
which is a method of BaseUserManager
.
Since django REST framework's flow is to do restore_object()
and then save_object()
, it's not possible to simply create Users using a ModelSerializer
in a generic create API endpoint, without hacking you way through.
What would be a clean way to solve this? or at least get it working using django's built-in piping?
Edit:
Important to note that what's specifically not working is that once you try to authenticate the created user instance using django.contrib.auth.authenticate
it fails if the instance was simply created using User.objects.create()
and not .create_user()
.
Another way to fix this is to overwrite
pre_save(self, obj)
method in your extension ofviewsets.GenericViewSet
like so:Edit:
Note that the obj in the code above contains the instance of User class. If you use Django's user model class directly, replace
obj.user
withobj
in the code (the last line in 2 places).It seems like you should be overriding
restore_object()
in your serializer, notsave()
. This will allow you to create your object correctly.However, it looks like you are trying to abuse the framework -- you are trying to make a single
create()
create two objects (the user and the profile). I am no DRF expert, but I suspect this may cause some problems.You would probably do better by using a custom user model (which would also include the profile in the same object).
Eventually I've overridden the serializer's
restore_object
method and made sure that the password being sent is then processes usinginstance.set_password(password)
, like so:Thanks everyone for help!
I'm working with DRF. And here is how I create users:
I have a Serializer with overrided save method:
create_new_user is just my function for user creation and in the view, I just have: