在Django Rest Framework中更新嵌套的PrimaryKeyRelatedField

时间:2019-04-23 13:16:28

标签: python django django-rest-framework

我正在尝试为我的其中一个序列化程序创建一个更新功能,该功能表示一个Company,其中某些人(我的应用程序的用户)是admin。但是,当我向Postman请求更新我的Company对象时,看来我的序列化程序没有在我的API中获得所有数据PUT

我试图在我的公司序列化器中使用完整的用户对象序列化器,但是在这种情况下,我必须指定不需要的数据,甚至不起作用。

当我PUT时,公司名称如下:

{
    "id": 1,
    "admins": [
        5,
        6,
        7,
        9,
        11
    ],
    "name": "Mon entreprise"
}

我的api对此进行了响应(使用管理面板添加了ID为6和11的用户):

{
    "name": "Mon entreprise",
    "logo": "http://localhost:8000/api/companies/1/mwe.jpg",
    "admins": [
        6,
        11
    ]
}

我尝试这样做是为了查看通过API传递了哪些数据

    def update(self, instance, validated_data):
        print (validated_data)

输出为:

{'name': "Mon entreprise"}

我的序列化器:

class CompanySerializer(serializers.ModelSerializer):
    admins      = serializers.PrimaryKeyRelatedField(many=True, read_only=True)

    class Meta:
        model = Company
        fields = ('name', 'logo', 'admins',)

    def update(self, instance, validated_data):
        print (validated_data)
        instance.logo = validated_data.get('logo', instance.logo)
        instance.name = validated_data.get('name', instance.name)
        instance.save()
        admin_list = validated_data.get('admins')
        print (admin_list)



        return instance

我的模特:

class Company(models.Model):
    admins          = models.ManyToManyField(User, related_name='admins')
    logo            = models.ImageField(blank=True)
    name            = models.CharField(max_length=200)

我不明白为什么我只为{'name': "Mon entreprise"}请求在json中添加了admins字段,为什么只有PUT

1 个答案:

答案 0 :(得分:0)

我遇到了同样的问题。 PrimaryKeyRelatedField似乎无法与many=True一起正常写作。在我的团队中,我们提出了以下临时解决方案,直到我们有时间深入研究为什么此方法无法按预期进行:

class PrimaryKeyRelatedListField(serializers.ListField):
    def __init__(self, queryset=None, **kwargs):
        assert queryset is not None, 'queryset must be specified for PrimaryKeyRelatedListField'
        self.child = serializers.PrimaryKeyRelatedField(queryset=queryset)
        super().__init__(**kwargs)

    def get_value(self, dictionary):
        dictionary = dictionary.copy()

        keys = []
        for k, _ in dictionary.items():
            if k.startswith(f'{self.field_name}['):
                keys.append(k)
        for k in keys:
            dictionary.appendlist(self.field_name, dictionary.getlist(k)[0])

        return super().get_value(dictionary)

    def to_representation(self, data):
        return super().to_representation(data.all())

希望这对您有所帮助。

好吧,所以我已经阅读了您的问题,并且您已经将read_only=True设置为admins字段,这将使DRF忽略正在发送的任何数据...因此这些数据不会到达序列化器的update()方法。