Django Serializer create(**validated_data) 질문

24.01.28 20:47 작성 조회수 107

0

class SignUpSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('__all__')
        extra_kwargs = {"password": {"write_only":True}}

    def create(self, validated_data):
        user = User.objects.create(**validated_data)
        user.set_password(validated_data['password'])
        user.save()

        return user

저는 위와 같이 회원가입 API를 만들었는데

Direct assignment to the forward side of a many-to-many set is prohibited. Use groups.set() instead.

이런 오류가 뜹니다...

다른 방식으로

def create(self, validated_data):

        if User.objects.filter(username=validated_data['username']).exists() or User.objects.filter(email=validated_data['email']).exists():
            raise serializers.ValidationError('username 존재 or email 존재')


        else:
            user = User.objects.create(
                username=validated_data['username'],
                nickname=validated_data['nickname'],
                email=validated_data['email'],
                gender=validated_data['gender'],
                age=validated_data['age']
            )
            user.set_password(validated_data['password'])
            user.save()
            return user

이렇게 만들었더니 오류가 안뜨더라구요.

 

두 차이가 뭔지 궁금합니다.

ManytoManyfield는 사용하지도 않았는데 저런 이유가 뜨는 이유도 모르겠습니다...ㅜ

답변 1

답변을 작성해보세요.

0

인프런 AI 인턴님의 프로필

인프런 AI 인턴

2024.01.29

안녕하세요, 인프런 AI 인턴입니다. 최유미님, 질문해주셔서 감사합니다.

첫 번째 코드에서 User.objects.create(**validated_data)를 사용하면 validated_data에 있는 모든 필드에 대해 직접 할당을 시도합니다. 여기서 User 모델에 ManyToMany 관계를 가진 필드가 있고, validated_data가 해당 필드를 포함하고 있다면 Django에서는 해당 필드에 직접 객체를 할당하는 것을 허용하지 않습니다. 그 대신 set(), add() 같은 메소드를 사용해야 합니다.

두 번째 코드에서는 create() 메소드 안에서 개별 필드를 명시적으로 나열하는 방식으로 객체를 생성하고 있습니다. 이때 ManyToMany 필드가 포함되지 않았기 때문에, 해당 오류가 발생하지 않습니다.

오류 메시지 “Direct assignment to the forward side of a many-to-many set is prohibited”는 User 모델의 ManyToMany 필드에 직접적으로 값을 할당하려고 할 때 뜨는 메시지입니다.

이 문제를 해결하려면, ManyToMany 관계의 필드를 validated_data에서 제거한 후에 create() 메소드를 사용하여 User 인스턴스를 생성하고, 이 후에 ManyToMany 필드를 갱신하는 과정이 필요합니다. 예를 들어:

def create(self, validated_data):
    groups_data = validated_data.pop('groups', None)  # ManyToManyField 이름이 'groups'라고 가정
    user = User.objects.create(**validated_data)
    if groups_data:
        user.groups.set(groups_data)
    user.set_password(validated_data['password'])
    user.save()
    return user

위 코드는 ManyToManyField를 다루는 예시이며, 실제로 사용하시는 User 모델의 ManyToMany 필드명에 맞춰 groups를 적절한 필드명으로 변경해야 할 수도 있습니다.

이와 같은 오류가 발생하지 않는 경우는 User 모델에 ManyToMany 관계를 맺는 필드가 없거나, 해당 필드가 validated_data에 포함되지 않았을 때입니다. 오류 메시지와 관련이 없는 경우는 이 메시지를 무시하고, 모델의 필드를 정확하게 이해하고 사용하는 것이 중요합니다.