Serializer with m2m field with through model. Got AttributeError

Viewed 31

I have User model with m2m field with through arg:

class User(AbstractBaseUser, PermissionsMixin):
    ...
    organizations = models.ManyToManyField(OrganizationV1, blank=True, through="UserOrganizationRole")
    ...

class UserOrganizationRole(models.Model):

    user = models.ForeignKey(User, on_delete=models.CASCADE)
    role = models.ForeignKey(Role, on_delete=models.CASCADE)
    organization = models.ForeignKey(OrganizationV1, on_delete=models.CASCADE)
    is_main_organization = models.BooleanField(default=False)

And following serializers:

class UserOrganizationRoleSerializer(serializers.ModelSerializer):

    class Meta:
        model = UserOrganizationRole
        fields = ("user", "organization", "role", "is_main_organization")

class CreateUserSerializer(serializers.ModelSerializer):
    
    organizations = UserOrganizationRoleSerializer(many=True)

    def create(self, validated_data):
        organizations_data = validated_data.pop("organizations")

        user = User.objects.create_user(**validated_data)

        for organization in organizations_data:
            UserOrganizationRole.objects.create(
                user=user,
                organization=organization["organization"],
                role=organization["role"],
                is_main_organization=organization["is_main_organization"]
            )
        return user

    class Meta:
        model = User
        fields = ('organizations', ...)

After POST request i got a User and UserOrganizationRole instances, but server response throw an error:

Got AttributeError when attempting to get a value for field `user` on serializer `UserOrganizationRoleSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `OrganizationV1` instance.
Original exception text was: 'OrganizationV1' object has no attribute 'user'.

If i specify write_only=True in UserOrganizationRoleSerializer all work correct with 201 response, so the problem with data representation. I don't understand what i'm doing wrong. Can anyone help with that?

1 Answers

Problem is solved.
By default field organizations represented as a list of OrganizationV1 instances, but we need to work with UserOrganizationRole.
So we have to explicitly specify source attribute like this:

organizations = UserOrganizationRoleSerializer(many=True, source="userorganizationrole_set")
Related