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

在使用Django静态框架和对象关系时,我经常遇到一些情况,我想根据调用序列化程序的上下文从序列化程序返回不同的字段。举个例子,假设我有一些代表歌手和专辑的模型

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,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')

对我的相册端点的请求可能会产生这样的对象

        "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"
                ]
            }
        ]

如您所见,使用嵌套序列化最终会为我提供在这种情况下实际需要的更多信息。例如,假设我有更多数据,那么当我查看歌手的信息时,我希望获得有关歌手制作的所有专辑的信息,但是当我查看专辑端点时,我宁愿没有包括这些信息,尤其是在这里,艺人唯一制作的专辑是我目前正在寻找的专辑。随着系统的变大,当我添加歌曲,播放列表等时,这个问题变得更加严重

我想做的是能够根据我调用该序列化程序的上下文来指定我想要的serialzier字段,而不是一次定义我的序列化程序,然后始终获取相同的信息,即使不需要。

我目前的解决方法是使用SerializerMethodField并将其添加到我的相册序列化器中

artiste = serializers.SerializerMethodField('get_artiste')

def get_artiste(self,obj):
         return [(i.id,i.name)for i in obj.artiste.all()]

这样做可以让我在专辑序列化程序的上下文中明确声明要返回的内容,但这使我的artiste字段为只读,这意味着在尝试创建专辑时,我无法指定该专辑所属的Artiste。 StringRelatedField等似乎也存在此问题。

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

很抱歉,这个冗长的,可能是愚蠢的问题,感谢您的帮助。

hangcoo 回答:如何动态指定用于嵌套序列化的字段

根据文档序列化程序类非常类似于常规的django表单类,因此您只需要指定要显示该序列化程序的字段即可,将在您的示例中完成:

time.AfterFunc

,现在此序列化器将仅显示给定演出者模型的相关“ id”和“ name”。 而且您可以在这里做更多的工作,例如特殊的 validate() { let username = this.state.username; let password = this.state.password; let userPassCombination = username + ':' + password; let encodedPass = base64.encode(userPassCombination); let headers = { 'Content-Type': 'text/json',Authorization: 'Basic ' + encodedPass,}; fetch(myConstants.URL + '/wp-json/',{ method: 'GET',headers: headers,}).then(responseData => { //console.log(JSON.stringify(responseData)); if (responseData.ok) { this.props.navigation.navigate('Profile',{ username: this.state.username,}); } else { alert('wrong information.'); } }); } 它会显示给定模型的所有字段,或者您可以使用class ArtisteSerializer(serializers.ModelSerializer): class Meta: model = Artiste fields = ('id','name') 来从序列化程序中删除这些字段,而不使用fields = '__all__'。 您也可以在这里使用django的模型关系。

更新:

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

fields
本文链接:https://www.f2er.com/2901683.html

大家都在问