Python django rest框架中的可写嵌套序列化程序?

Python django rest框架中的可写嵌套序列化程序?,python,django,rest,Python,Django,Rest,关于Django ModelSerializer,我的设计如下。 有模型A和模型B。模型B有一个模型A的外键字段。由于某些原因,我不能直接使用主键来序列化模型B。正如我所想,我需要的是序列化另外两个字段(在模型A中是唯一的) 我看到SlugRelatedField必须用于一个slug字段。 我搜索了一个可以支持NaturalKeyField的NaturalKeyField。但它似乎被django rest框架取代了。但是我检查了django rest框架,根本没有这样的字段。 有人能帮忙吗??我

关于Django ModelSerializer,我的设计如下。 有模型A和模型B。模型B有一个模型A的外键字段。由于某些原因,我不能直接使用主键来序列化模型B。正如我所想,我需要的是序列化另外两个字段(在模型A中是唯一的)

我看到SlugRelatedField必须用于一个slug字段。 我搜索了一个可以支持NaturalKeyField的NaturalKeyField。但它似乎被django rest框架取代了。但是我检查了django rest框架,根本没有这样的字段。 有人能帮忙吗??我该怎么办

代码如下。 模型A

模型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的序列化程序

class AssetModelSerializer(serializers.ModelSerializer):
    org =  serializers.SlugRelatedField(queryset=Org.objects.all(), slug_field='name')
    class Meta:
        model = AssetModel
        fields = ('org', 'name', 'model_type',..
模型B的序列化程序

class DataitemSerializer(serializers.ModelSerializer):
    class Meta:
        model = Dataitem
        fields = ('mod', 'name','data_type'...)
模型A的主键只是一个自动添加的id Django。序列化模型B时,我需要获取模型A的组织和名称。需要读和写。

嵌套序列化程序 您可以这样做,为
Dataitem
定义一个序列化程序,它可以重用
AssetModel
模型的序列化程序

class AssetModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = AssetModel

    # Fields org and name of AssetModel will be inlcuded by default

class 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 AssetModelSerializer
我更喜欢这种方法,因为我有控制权。 如果使用上述方法进行序列化,则会得到如下结构:

data_item = {'name': ..., 'mod': {'org': ..., 'name': ...}}
                          ^
                          |___ AssetModel fields
或者,您也可以使用
depth=n
您还可以在
Dataitem

class DataitemSerializer(serializers.ModelSerializer):
        class Meta:
            model = Dataitem
            depth = 1 # Will include fields from related models
                      # e.g. the mod FK to AssetModel
可写嵌套序列化程序 因为嵌套创建和更新的行为可能不明确, 并且可能需要相关模型之间的复杂依赖关系,REST 框架3要求您始终显式地编写这些方法

我们必须实现
create/update
,以便按照


似乎有一个图书馆能做到这一点

它处理这些类型的创建和序列化

  • OneToOne(直接/反向)
  • 外键(直接/反向)
  • 许多(直接/反向,不包括通过模型的m2m关系)
  • 一般关系(总是相反)

我认为更好的问题是发布您的模型并解释您想要实现的目标,而不是询问您想到的解决方案,或者AssetModel中的其他字段,我不想序列化它们。要使用嵌套序列化程序,我是否必须定义一个只包含组织和名称字段的新序列化程序?是的,只需像您所做的那样使用
字段=(…)
。但是看起来mod字段的写入会失败。没问题!我会尝试获取最新版本的DRF,并阅读这篇关于可写嵌套序列化程序@ThomasLiu的文章,不客气。我添加了一个示例,这样您就可以关联到您的模型。请注意,此示例适用于1嵌套模型,但如果AssetModel本身需要FK密钥,则必须从
validated\u data
中解压缩更多数据,并创建对象、链接FK等。我建议您首先使用简单的1嵌套模型来实践此操作。我希望这能让你走上正轨。如果答案对你有帮助,请投票/接受!非常感谢。
class DataitemSerializer(serializers.ModelSerializer):
        class Meta:
            model = Dataitem
            depth = 1 # Will include fields from related models
                      # e.g. the mod FK to AssetModel
class 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