Django 如何动态指定嵌套序列化的字段

Django 如何动态指定嵌套序列化的字段,django,serialization,django-rest-framework,Django,Serialization,Django Rest Framework,在使用Django rest框架和对象关系时,我经常会遇到这样的情况:根据调用序列化程序的上下文,我希望从序列化程序返回不同的字段。举个例子,假设我有一些代表艺人和专辑的模型 class Artiste(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) name = models.CharField(max_length=30) songs = mo

在使用Django rest框架和对象关系时,我经常会遇到这样的情况:根据调用序列化程序的上下文,我希望从序列化程序返回不同的字段。举个例子,假设我有一些代表艺人和专辑的模型

class Artiste(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(max_length=30)
    songs = models.ManyToManyField(Song, related_name='artiste')
    albums = models.ManyToManyField(Album, related_name='artiste')

class Album(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(max_length=30)
    description = models.TextField(blank=True, null=True)
这些模型由这些序列化程序序列化,其中包括多对多关系中的字段

class AlbumSerializer(serializers.ModelSerializer):
    artiste = ArtisteSerializer(many=True)
    class Meta:
        model = Album
        fields = ('id','title','description','artiste')

class ArtisteSerializer(serializers.ModelSerializer):
    class Meta:
        model = Artiste
        fields = ('id', 'name', 'albums')
对my album端点的请求可能会生成如下对象

        "id": "5807bd12-254f-4508-b76f-02dc0740e809",
        "title": "Test",
        "description": "",
        "artiste": [
            {
                "id": "31f09ef0-50ce-48b1-96a6-a6c234930ce5",
                "name": "Alec Benjamin",
                "albums": [
                    "5807bd12-254f-4508-b76f-02dc0740e809"
                ]
            }
        ]
正如您所看到的,使用嵌套序列化最终为我提供了在此上下文中实际需要的更多信息。例如,考虑到我有更多的数据,当我查看艺人的信息时,我希望获得艺人制作的所有专辑的相关信息,但当查看我的专辑端点时,我不希望包含这些信息,特别是在这里,这位艺人制作的唯一一张专辑就是我目前正在看的那张。随着系统变得越来越大,这个问题变得更糟,因为我包括歌曲,播放列表等

我想做的是,能够根据调用序列化程序的上下文指定所需的序列化程序字段,而不是只定义一次序列化程序,然后即使在不需要时也始终获得相同的信息

我目前的做法是使用SerializerMethodField并将其添加到我的相册序列化程序中

artiste = serializers.SerializerMethodField('get_artiste')

def get_artiste(self, obj):
         return [(i.id ,i.name)for i in obj.artiste.all()]
这样做允许我在我的相册序列化程序的上下文中显式地声明我想要返回的内容,但这会使我的Artister字段只读,这意味着在尝试创建相册时,我无法指定它所属的Artister。
StringRelatedField
等的情况似乎也是如此

您的嵌套序列化方法是什么?是否有任何方法可以指定在特定情况下序列化应返回哪些字段,而无需重写序列化程序或使字段为只读


对于这个冗长、可能愚蠢的问题,我深表歉意,并感谢您的帮助。

根据文档,序列化程序类与常规django表单类非常相似,因此您只需指定希望序列化程序显示的字段,并在您的示例中完成以下操作:

class ArtisteSerializer(serializers.ModelSerializer):
类元:
模特=艺人
字段=('id','name')
现在,这个序列化程序将只显示给定艺人模型的相关“id”和“name”。 在这里,你可以做更多的事情,比如特殊的
字段='\uuuuuu all'
它将显示给定模型的所有字段,或者不使用
字段
,您可以使用
排除=('album',)
从序列化程序中删除这些字段。 您也可以在这里使用django的模型关系

更新:

为了能够在不同的端点中使用这些序列化程序,最好使用python类继承创建一个基序列化程序,并在child上使用不同的属性

class BaseArtisteSerializer(serializers.ModelSerializer):
类元:
模特=艺人
字段=('id','name','artist')
类ArtisteSerializer(BaseArtisteSerializer):
类Meta(BaseArtisteSerializer.Meta):
字段=('id','name')

当我指定这些字段时,它们将在hte类的每个实例中返回。换句话说,每次调用Artiste serializer时,我都会得到我在Artiste serializer中指定的所有字段。我想做的是根据不同的情况对不同的字段进行序列化。更具体一点,请问这些情况是什么?不同的端点和用例或基于用户身份验证级别或其他内容的过滤?例如,当我转到artiste endpoint时,我可能需要模型上的所有字段,但当我查看唱片集endpoint时,我可能只需要artiste提供的几个特定相关字段。不同的端点/上下文返回不同的信息是im所追求的。