首页 > 解决方案 > 如何解决 /api/register/ 处的 TypeError 禁止直接赋值给多对多集合的前端。改用 groups.set()

问题描述

class PersonSerializer(serializers.ModelSerializer):
    class Meta:
        model = Person
        # fields = '__all__'

        fields = ('id', 'username', 'email', 'password', 'is_active', 'is_staff', 'is_superuser'
                  , 'Designation', 'Address', 'groups', 'profile')

    def create(self, validated_data, ):
        user = Person.objects.create(
            username=validated_data['username'],
            email=validated_data['email'],
            password=validated_data['password'],
            Designation=validated_data['Designation'],
            is_active=validated_data['is_active'],
            is_staff=validated_data['is_staff'],
            is_superuser=validated_data['is_superuser'],
            Address=validated_data['Address'],
            profile=validated_data['profile'],
            groups=validated_data['groups']

        )

        user.set_password(make_password(validated_data['password']))
        user.save()
        return user

如何解决以下错误:

TypeError at /api/register/ Direct assignment to the forward side of a many-to-many set is prohibited. Use groups.set() instead

标签: djangodjango-rest-framework

解决方案


groups创建时不能填充Person,因为那时Person还没有主键,因此该主键不能用于多对多关系的联结表。

def create(self, validated_data):
    user = Person.objects.create(
        username=validated_data['username'],
        email=validated_data['email'],
        password=validated_data['password'],
        Designation=validated_data['Designation'],
        is_active=validated_data['is_active'],
        is_staff=validated_data['is_staff'],
        is_superuser=validated_data['is_superuser'],
        Address=validated_data['Address'],
        profile=validated_data['profile'],
        # no groups=…
    )
    # add groups to the user ↓
    user.groups.add(*validated_data['groups'])
    user.set_password(make_password(validated_data['password']))
    user.save()
    return user

可以通过以下方式缩短逻辑:

def create(self, validated_data):
    groups = validated_data.pop('groups', ())
    user = Person.objects.create(
        **validated_data
    )
    # add groups to the user ↓
    user.groups.add(*groups)
    user.set_password(make_password(validated_data['password']))
    user.save()
    return user

推荐阅读