Django Rest Framework,模型序列化器,处理只读数据

Posted

技术标签:

【中文标题】Django Rest Framework,模型序列化器,处理只读数据【英文标题】:Django Rest Framework, model serializer, working with read only data 【发布时间】:2017-10-29 00:36:17 【问题描述】:

我有一个这样的端点:'host.com/questions/123/vote'。前端可以向该端点发送投票类型为“上”或“下”的帖子请求。 在后端,投票是这样的:

class Vote(models.Model):
UP = 'UP'
DOWN = 'DOWN'
CHOICE = ((UP, 'upvote'), (DOWN, 'downvote'))
post_content_type = models.ForeignKey(ContentType,
                                      on_delete=models.CASCADE)
post_id = models.PositiveIntegerField()
post = GenericForeignKey('post_content_type', 'post_id')
voter = models.ForeignKey(to=settings.AUTH_USER_MODEL,
                          related_name='votes')
type = models.CharField(choices=CHOICE, max_length=8)

class Meta:
    unique_together = ('post_content_type', 'post_id', 'voter')

我使用通用 fk,因为除了 Question 之外,您也可以投票给不同的模型实例。

现在我使用 DRF 的 CreateAPIView 创建了这个 api 端点。

这是我的问题:

我如何从两个来源传递数据:request.data(投票类型在哪里)和 kwargs(问题 ID 和内容类型“问题”在哪里)。

我试过了:

    将 kwargs 传递给 self.get_serializer_context 并通过 SerializerMethodField 获取,不起作用 直接将 kwrags 传递给 perform_create,但这会通过 drf 端的验证。

【问题讨论】:

【参考方案1】:

您需要为 post_content_type 和 post_id 指定一些 write_only 字段。

class VoteSerializer(serializers.Serializer):
    post_content_type_id = serializers.PrimaryKeyRelatedField(write_only=True)
    post_id = serializers.IntegerField(write_only=True)
    type = serializers.CharField()
    ## your other fields ...

如果您对如何输出通用关系的不同表示感到好奇,请查看 DRF 文档的这一部分:http://www.django-rest-framework.org/api-guide/relations/#generic-relationships。

【讨论】:

那么我如何将数据从 url 提供给序列化程序?【参考方案2】:

我最终覆盖了序列化程序中的to_internal 函数,并通过覆盖CreateAPIView 中的get_serializer_context 来传递url 数据,并在to_internal 函数中使用self.context 获取数据

【讨论】:

以上是关于Django Rest Framework,模型序列化器,处理只读数据的主要内容,如果未能解决你的问题,请参考以下文章

Django Rest Framework:非模型服务

django-rest-framework 是不是提供管理站点来管理模型?

django-rest-framework、多表模型继承、ModelSerializers 和嵌套序列化器

Django - Rest Framework 多个模型

Django Rest Framework 过滤计算模型属性

Django Rest Framework 中的模型翻译