本文介绍了Django-rest-framework中的可写嵌套序列化器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 我的设计如下关于Django ModelSerializer。 有模型A和模型B。模型B具有模型A的外键字段。由于某些原因,我不能直接使用主键来序列化模型B。按照我的想法,我需要序列化其他两个字段(在模型A中唯一)。 我看到SlugRelatedField必须用于一个子字段。 我搜索了一个NaturalKeyField可以支持NaturalKeyField。但看起来它被django-rest-framework取代。但是我检查了django-rest-framework,根本没有这样的领域。 谁能帮忙?我该怎么办? 代码如下。 模型A class AssetModel(models.Model): org = models.ForeignKey(Org, related_name ='models') name = models.CharField(max_length = 128) model_type = models.SmallIntegerField(默认= 3,choices = MODEL_TYPE)目录= models.CharField(max_length = 128) ... class Meta: unique_together =('org','name',) 模型B class Dataitem(models.Model): mod = models.ForeignKey(AssetModel,related_name ='dataitems') name = models.CharField(max_length = 128) data_type = models.SmallIntegerField(default = 0,choices = DATAITEM_DATATYPE)。 .. 模型A的序列化器 类AssetModelSerializer(serializers.ModelSerializer): org = serializers.SlugRelatedField(queryset = Org.objects.all(),slug_field ='name')类元: 模型= AssetM odel fields =('org','name','model_type',.. 模型B的序列化器 类DataitemSerializer(serializers.ModelSerializer):类元:模型= Dataitem 字段=('mod','name','data_type'...) 模型A的主键只是一个Django自动添加的id。序列化模型B时,我需要获取模型A的组织和名称。读和写都需要。解决方案 嵌套序列化器 您可以执行以下操作,为 Dataitem 定义一个序列化器,该序列化器可以重用 AssetModel 模型 class AssetModelSerializer(serializers.ModelSerializer): class Meta: model = AssetModel #默认情况下将包含字段组织和AssetModel名称 class DataitemSerializer(serializers.ModelSerializer):类元:模型= Dataitem mod = AssetModelSerializer()#这是Dataitem.mod字段#这是AssetModel的FK,#现在将使用AssetModelSerializer #对其进行序列化,并包括AssetModelSerializer $ b $的组织和名称字段b 我更喜欢这种方法,因为使用我得到的控制。 如果您使用上述序列化,您将获得如下结构: data_item = {'name':.. 。,'mod':{'org':...,'name':...}} ^ | ___ AssetModel字段 或者,您也可以使用 depth = n 您还可以在 Dataitem depth = 1 pre> 类DataitemSerializer(serializers.ModelSerializer):类元:模型=数据项深度= 1#将包括相关模型的字段#例如将Mod FK转换为AssetModel 可写嵌套序列化器 由于嵌套创建和更新的行为可能含糊不清,可能需要相关模型之间的复杂依赖性,因此REST 框架3要求您始终明确地编写这些方法。 我们必须实现 create / update 才能使其按照 DRF的文档 类DataitemSerializer(serializers.ModelSerializer):类元:模型= Dataitem #嵌套序列化器 mod = AssetModelSerializer() #自定义create() def create(self,validated_data):#首先我们为AssetModel创建'mod'数据 mod_data = validated_data.pop('mod') asset_model = AssetModel.objects.create(** mod_data) #现在我们创建Dataitem并设置Dataitem.mod FK dataitem = Dataitem.objects.create(mod = asset_model,* * validated_data) #返回一个Dataitem实例返回一个dataitem My design is as following about Django ModelSerializer.There are model A and model B. Model B has a foreign key field of Model A. For some reasons, I can not use the primary key directly to serialize Model B. As my thought, what I need is to serialize two other fields(unique together in Model A).And I see the SlugRelatedField must be used for one slug field. I searched there is a NaturalKeyField can support NaturalKeyField. But it looks like it is superseeded by django-rest-framework. But I checked the django-rest-framework, there is no such field at all.Can anyone help?? What should I do?The code is as following.Model Aclass AssetModel(models.Model): org = models.ForeignKey(Org, related_name='models') name = models.CharField(max_length=128) model_type = models.SmallIntegerField(default = 3,choices = MODEL_TYPE ) directory = models.CharField(max_length = 128) ... class Meta: unique_together = ('org', 'name',)Model Bclass Dataitem(models.Model): mod = models.ForeignKey(AssetModel, related_name='dataitems') name = models.CharField(max_length=128) data_type = models.SmallIntegerField(default =0,choices = DATAITEM_DATATYPE) ...Serializer of model Aclass AssetModelSerializer(serializers.ModelSerializer): org = serializers.SlugRelatedField(queryset=Org.objects.all(), slug_field='name') class Meta: model = AssetModel fields = ('org', 'name', 'model_type',..Serializer of model Bclass DataitemSerializer(serializers.ModelSerializer): class Meta: model = Dataitem fields = ('mod', 'name','data_type'...)The primary key of Model A is just a id Django auto added. When serialize the model B, I need to get the org and name of model A. Both read and write are needed. 解决方案 Nested SerializerYou can do something like this, define a serializer for Dataitem that can reuse a serializer of the AssetModel modelclass AssetModelSerializer(serializers.ModelSerializer): class Meta: model = AssetModel # Fields org and name of AssetModel will be inlcuded by defaultclass DataitemSerializer(serializers.ModelSerializer): class Meta: model = Dataitem mod = AssetModelSerializer() # This is the Dataitem.mod field # which is a FK to AssetModel, # Now it'll be serilized using the AssetModelSerializer # and include the org and name fields of AssetModelSerializerI prefer this approach because of the control I get.If you serialize using the above you get a structure like this:data_item = {'name': ..., 'mod': {'org': ..., 'name': ...}} ^ |___ AssetModel fieldsAlternatively you can also use depth = nYou can also use depth = 1 in Dataitemclass DataitemSerializer(serializers.ModelSerializer): class Meta: model = Dataitem depth = 1 # Will include fields from related models # e.g. the mod FK to AssetModelWritable Nested Serializer Because the behavior of nested creates and updates can be ambiguous, and may require complex dependencies between related models, REST framework 3 requires you to always write these methods explicitly.We have to implement create/update to make this writable as per DRF's documentationclass DataitemSerializer(serializers.ModelSerializer): class Meta: model = Dataitem # Nested serializer mod = AssetModelSerializer() # Custom create() def create(self, validated_data): # First we create 'mod' data for the AssetModel mod_data = validated_data.pop('mod') asset_model = AssetModel.objects.create(**mod_data) # Now we create the Dataitem and set the Dataitem.mod FK dataitem = Dataitem.objects.create(mod=asset_model, **validated_data) # Return a Dataitem instance return dataitem 这篇关于Django-rest-framework中的可写嵌套序列化器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 10-10 00:40