使用Django REST框架在序列化中嵌套字段

使用Django REST框架在序列化中嵌套字段,django,django-rest-framework,Django,Django Rest Framework,考虑到我有这样一个模型: class Case(models.Model): opened = models.DateTimeField(auto_now_add=True) client_first_name = models.CharField(max_length=50) client_last_name = models.CharField(max_length=50) { "opened": "2014-10-05T19:30:48.667Z",

考虑到我有这样一个模型:

class Case(models.Model):
    opened = models.DateTimeField(auto_now_add=True)
    client_first_name = models.CharField(max_length=50)
    client_last_name = models.CharField(max_length=50)
{
    "opened": "2014-10-05T19:30:48.667Z",
    "client": {
        "first_name": "John",
        "last_name": "Doe"
    }
}
class CaseSerializer(serializers.ModelSerializer):
    client = serializers.SerializerMethodField('client')

    class Meta:
        model = Case
        fields = ('opened', 'client')

    def client(self, obj):
        client_fields = {}
        client_fields['first_name'] = obj.client_first_name
        client_fields['last_name'] = obj.client_last_name
        return client_fields
我想对
client.*
字段进行分组,以便序列化的JSON如下所示:

class Case(models.Model):
    opened = models.DateTimeField(auto_now_add=True)
    client_first_name = models.CharField(max_length=50)
    client_last_name = models.CharField(max_length=50)
{
    "opened": "2014-10-05T19:30:48.667Z",
    "client": {
        "first_name": "John",
        "last_name": "Doe"
    }
}
class CaseSerializer(serializers.ModelSerializer):
    client = serializers.SerializerMethodField('client')

    class Meta:
        model = Case
        fields = ('opened', 'client')

    def client(self, obj):
        client_fields = {}
        client_fields['first_name'] = obj.client_first_name
        client_fields['last_name'] = obj.client_last_name
        return client_fields
我尝试了以下内容,但不起作用,因为
client
不是实际字段:

class ClientSerializer(serializers.ModelSerializer):

    class Meta:
        model = Case
        fields = ('client_first_name', 'client_last_name')


class CaseSerializer(serializers.ModelSerializer):
    client = ClientSerializer()

    class Meta:
        model = Case
        fields = ('opened', 'client')
除了完全手动序列化之外,我还有哪些选项?我不想为
客户机
创建单独的模型,因为这些数据实际上属于
案例
。只读还不够好。

您可以这样尝试:

class Case(models.Model):
    opened = models.DateTimeField(auto_now_add=True)
    client_first_name = models.CharField(max_length=50)
    client_last_name = models.CharField(max_length=50)
{
    "opened": "2014-10-05T19:30:48.667Z",
    "client": {
        "first_name": "John",
        "last_name": "Doe"
    }
}
class CaseSerializer(serializers.ModelSerializer):
    client = serializers.SerializerMethodField('client')

    class Meta:
        model = Case
        fields = ('opened', 'client')

    def client(self, obj):
        client_fields = {}
        client_fields['first_name'] = obj.client_first_name
        client_fields['last_name'] = obj.client_last_name
        return client_fields

虽然没有完全奏效,但我有了这个想法。不幸的是,它本质上是只读的,我需要完整的CRUD支持!我忘了。是,SerializerMethodField是只读的。我已经大量使用了它,但是对于只读web服务,所以我没有立即想到您还需要post和put方法。有一个答案@brawaga这不是一个真正的答案,因为它是“完全手动序列化”,我写道,我正在寻找其他选项。无论如何,谢谢你;很高兴有作者的意见。@Dien,不是基于答案,而是基于底部的顶部更新,您可以构建一个不违反DRY的解决方案,这不是完全的,而是半手动序列化,因为解决方案是操作已验证的_数据和实例,可能还有更多。而且它是双向的。@brawage,啊,你说得对——我对“答案”的理解太字面了。里面可能有东西。尽管我同意汤姆的观点,他的版本更具可读性。