'manager_method() argument after ** must be a mapping, not str' when overloading nested ModelSerialiver.create(...)

Viewed 43

I want to overload a ModelSerializer create() method in a generic way using Django RestFramework inspection functions. for the purpose of testing the concept on a related_name of a ForeingKey i have the following models and corresponding serializer.

models.py

class Country(models.Model):
    pass

class People(models.Model):
    country = models.ForeignKey(
        to="myapp.Country",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="country_people"
        )

serializer.py

class PeopleSerializer(serializers.ModelSerializer):
    class Meta:
        fields= "__all__"
        model = People

class CountrySerializer(serializers.ModelSerializer):
    country_people = PeopleSerializer(many=True)
    
    def create(self, validated_data):
        country_people_data = validated_data.pop("country_people", [])
        instance = super().create(validated_data)
        
        for cp_data in country_people_data:
            cp_data["country"] = instance
            self.get_fields()["country_people"].create(cp_data)
    class Meta:
        fields= "__all__"
        model = Country

example of data

# json data for country serializer
{
    ...,
    "country_people":[
        {...},
        {...}
    ]
}

When calling CountrySerializer.save() the CountrySerializer.create() will be called and it will save also nested data on People table. The issue is that I got the following error

ModelClass._default_manager.create(**validated_data) TypeError: django.db.models.manager.BaseManager._get_queryset_methods.<locals>.create_method.<locals>.manager_method() argument after ** must be a mapping, not str

using People.create(**cp_data) is working but it is not the solution in my context I want to solve it using self.get_fields because I want it to be generic and because PeopleSerializer could nest another serializer so back and so forth

0 Answers
Related