首页 > 解决方案 > How to change Representation of Many to Many related object in Django Rest Framework

问题描述

I want the complete related model on GET and use the id's on CREATE, UPDATE and DELETE. I try to use to_representation. So i want to create an array of dicts called users which should show the complete users.

But i get the error "unhashable type: 'ReturnDict'" when i add the dict in the object, it works fine if i would do it for a single user by writing to the array directly.

class CompanySerializer(serializers.ModelSerializer):
    #users = UserSerializer(many=True)
    created_at = serializers.DateTimeField()
    updated_at = serializers.DateTimeField()
    class Meta:
        model = Company
        fields = ['id', 'name', 'street', 'city', 'postal_code', 'state', 'company_form', 'users', 'created_at', 'updated_at']        

    def to_representation(self, instance):
        representation = super(CompanySerializer, self).to_representation(instance)
        representation['company_form'] = CompanyFormSerializer(instance.company_form).data
        representation['users'] = []
        for entry in instance.users.all():
            user = {UserSerializer(entry).data}
            representation['users'].extend(user)
        return representation

标签: pythondjangodjango-rest-framework

解决方案


无需手动执行此操作,您可以将序列化程序添加到您的序列化程序,例如:

class CompanySerializer(serializers.ModelSerializer):
    users = UserSerializer(read_only=True, many=True)
    company_form = CompanyFormSerializer()
    created_at = serializers.DateTimeField()
    updated_at = serializers.DateTimeField()

    class Meta:
        model = Company
        fields = ['id', 'name', 'street', 'city', 'postal_code', 'state', 'company_form', 'users', 'created_at', 'updated_at']

有关更多信息,请参阅Django REST 框架文档的处理嵌套对象部分

你的to_representation模型在两个部分是错误的:

  1. 您将结果包装.data在一个集合中,但正如您发现的那样,字典不能放在字典中,因为集合是可变的;和
  2. 你应该使用.append(..)而不是在.extend(..)这里。
def to_representation(self, instance):
    representation = super(CompanySerializer, self).to_representation(instance)
    representation['company_form'] = CompanyFormSerializer(instance.company_form).data
    representation['users'] = []
    for entry in instance.users.all():
        user = UserSerializer(entry).data
        representation['users'].append(user)
    return representation

但话虽如此,在我看来,旨在自己做这件事的糟糕的软件设计。Django 有很多工具可以通过 URI 等正确处理关系。


推荐阅读