Django - creating a new object in the serializer but leaving some params from validated_data out

I'm using a ManyToManyField in my model:

class CustomUser(AbstractUser):
...
    roles = models.ManyToManyField(Role, blank=True)

And in the serializer I want to create a new object of the CustomUser

class CustomUserSerializer(serializers.ModelSerializer):

     def create(self, validated_data):
             user = CustomUser.objects.create_user(**validated_data)

But off course Django complains about that: Direct assignment to the forward side of a many-to-many set is prohibited. Use roles.set() instead.

How could I create new CustomUser object from all the params contained in validated_data, but leaving 'roles' alone?

Is there an elegant way to do that?

I'd say pop roles out, but I think validated_data immutable in that situation.. So instead I would make a copy and then pop it out or just list comprehension to create a new one dict and use that

Copy + Pop

class CustomUserSerializer(serializers.ModelSerializer):

    def create(self, validated_data):
        create_data = validated_data
        create_data.pop('roles')
        user = CustomUser.objects.create_user(**create_data)

List Comprehension

class CustomUserSerializer(serializers.ModelSerializer):

    def create(self, validated_data):
        user = CustomUser.objects.create_user(**{k:v for k,v in validated_data.items() if k != 'roles'})

Ok, so what you want to do is to remove the field you want out of the validated data and store it in a variable, which you can later get and perform the action you need.

class CustomUserSerializer(serializers.ModelSerializer):

    def create(self, validated_data):
        # pop returns the item being popped so you can store the returned item in a variable
        roles = validated_data.pop("roles")
        user = CustomUser.objects.create_user(**validated_data)
        # If needed
        user.roles.set(roles)
        return user
Back to Top