【问题标题】:'Dynamic' fields in DRF serializersDRF 序列化程序中的“动态”字段
【发布时间】:2014-11-09 15:28:47
【问题描述】:

我的目标是建立一个端点,它可以使用 GenericForeignKey 创建模型对象。由于模型还包括 ContentType,因此我们将引用的模型的实际类型在对象创建之前是未知的。

我举个例子:

我有一个“Like”模型,它可以引用一组其他模型,例如“Book”、“Author”。

class Like(models.Model):
    created = models.DateTimeField()
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')

序列化器可能如下所示:

class LikeSerializer(serializers.ModelSerializer):

    class Meta:
        model = models.Like
        fields = ('id', 'created', )

我想要实现的是根据请求中传递的键来确定 Like 的类型。问题是如果没有在Serializer 字段中明确指定这些密钥,DRF 不会从请求中传递这些密钥。例如,POST 请求正文包含:

{
    "book":2
}

我想做下一步

def restore_object(self, attrs, instance=None)
    if attrs.get('book', None) is not None:
        # create Like instance with Book contenttype
    elif attrs.get('author', None) is not None:
        # create Like instance with Author contenttype

在这种情况下,将执行第一个 if 子句。 可以看到,根据请求传入的key确定的类型,没有指定特殊的Field。

有什么办法可以做到吗?

谢谢

【问题讨论】:

    标签: python django-rest-framework


    【解决方案1】:

    您可以尝试在调用视图时通过将其包装在一个函数中来实例化您的序列化程序(您创建了一个序列化程序工厂):

    def like_serializer_factory(type_of_like):
        if type_of_like == 'book':
            class LikeSerializer(serializers.ModelSerializer):
                class Meta:
                    model = models.Like
                    fields = ('id', 'created', )
                def restore_object(self, attrs, instance=None):
                    # create Like instance with Book contenttype
        elif type_of_like == 'author':
            class LikeSerializer(serializers.ModelSerializer):
                class Meta:
                    model = models.Like
                    fields = ('id', 'created', )
                def restore_object(self, attrs, instance=None):
                    # create Like instance with Author contenttype
        return LikeSerializer
    

    然后在你的视图中覆盖这个方法:

    def get_serializer_class(self):
        return like_serializer_factory(type_of_like)
    

    【讨论】:

      猜你喜欢
      • 2018-04-05
      • 1970-01-01
      • 1970-01-01
      • 2018-02-20
      • 2022-12-11
      • 1970-01-01
      • 1970-01-01
      • 2019-07-12
      • 1970-01-01
      相关资源
      最近更新 更多