Home > OS >  How do I edit my serializer create() method to make relationship to nested object in Django REST Fra
How do I edit my serializer create() method to make relationship to nested object in Django REST Fra

Time:06-12

In my app, Groups are created by Users

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ["user_id", "username"]


class GroupSerializer(serializers.ModelSerializer):
    owner = UserSerializer()

    class Meta:
        model = Group
        fields = ["name", "picture_url", "owner", "members"]

    def create(self, validated_data):
        owner_data = validated_data.pop("owner")
        user = User.objects.filter(user_id=owner_data.get("user_id"))
        instance = Group.objects.create(**validated_data)
        instance.owner = user
        instance.save
        return instance

I'm trying to have it so that I can create a Group object, which can only have an existing User as its owner (I need to do this by the user_id, which is separate from the id), but somehow when I post the following:

    "owner": {
        "user_id":6
    },
    "picture_url":"nothing",
    "name":"jazz club"
}

It returns this:

{
    "owner": {
        "user_id": [
            "user with this user id already exists."
        ],
        "username": [
            "This field is required."
        ]
    }
}

For context, my post method looks like this:

    def post(self, request):
        new_group = request.data
        new_group["members"] = []
        serializer = self.serializer_class(data=new_group)
        serializer.is_valid(raise_exception=True)
        serializer.save()

        return Response(serializer.data, status=status.HTTP_201_CREATED)

And my models look like this:

class User(models.Model):
    id = models.BigAutoField(primary_key=True, unique=True)
    user_id = models.BigIntegerField(unique=True)
    username = models.CharField(max_length=100)


class Group(models.Model):
    name = models.CharField(max_length=255, unique=True)
    picture_url = models.CharField(max_length=255)
    owner = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name="owned_groups",
        blank=True,
    )
    members = models.ManyToManyField(User, related_name="groups", blank=True)

What do I need to change to make this work? I've tried a lot of different stuff.

CodePudding user response:

I think you need to upload owner_id if it has only an existing user as the owner.

class GroupSerializer(serializers.ModelSerializer):
    owner = UserSerializer(read_only = True)
    user_id = serializers.IntegerField(write_only = True)

    class Meta:
        model = Group
        fields = ["name", "picture_url", "owner", "members", "user_id"]
    
    def create(self, validated_data):
        user_id = validated_data.pop("user_id")
        try:
            user = User.objects.get(user_id=user_id)
            instance = Group.objects.create(owner = user, **validated_data)
            return instance
        except User.DoesNotExist:
            raise serializers.ValidationError("Invalid user id")

And the payload should be,

{
    "user_id": 6,
    "picture_url":"nothing",
    "name":"jazz club"
}
  • Related