How to create django user using DRF ModelSerializer

In django, user creation has a different and unique thread from a regular instance of a model instance. You need to call create_user() , which is the BaseUserManager method.

Since the django REST framework thread must do restore_object() and then save_object() , it’s not possible to simply create users using ModelSerializer at the common endpoint of the authoring API without hacking you.

What will be a clean way to solve this problem? or at least make it work using the django built-in pipeline?

Edit:

It’s important to note that what specifically doesn’t work is that after trying to authenticate the created user instance with django.contrib.auth.authenticate it fails if the instance was just created using User.objects.create() , not .create_user() .

+7
python django django-rest-framework
source share
4 answers

In the end, I redefined the serializer restore_object method and made sure that the password I sent was then processed using instance.set_password(password) , for example:

 def restore_object(self, attrs, instance=None): if not instance: instance = super(RegisterationSerializer, self).restore_object(attrs, instance) instance.set_password(attrs.get('password')) return instance 

Thank you all for your help!

+2
source share

Another way to fix this is to overwrite the pre_save(self, obj) method in the viewsets.GenericViewSet extension as follows:

 def pre_save(self, obj): """ We have to encode the password in the user object that will be saved before saving it. """ viewsets.GenericViewSet.pre_save(self, obj) # Password is raw right now, so set it properly (encoded password will # overwrite the raw one then). obj.user.set_password(obj.user.password) 

Edit:

Note that obj in the above code contains an instance of the User class. If you use the Django model class directly, replace obj.user with obj in the code (last line in 2 places).

+1
source share

I work with DRF. And this is how I create users:

I have a Serializer with a canceled save method:

 def save(self, **kwargs ): try: user = create_new_user(self.init_data) except UserDataValidationError as e: raise FormValidationFailed(e.form) self.object = user.user_profile return self.object 

create_new_user is just my function to create a user, and in the view I just:

 def post(self, request, *args, **kwargs): return self.create(request, *args, **kwargs) 
0
source share

It seems that you should override restore_object() in your serializer, not save() . This will allow you to create your object correctly.

However, it looks like you are trying to abuse the wireframe - you are trying to create one create() to create two objects (user and profile). I am not a DRF expert, but I suspect that this may cause some problems.

You would probably do better using a custom model (which would also include the profile in the same object).

0
source share

All Articles