django-rest-swagger与modelserializers兼容吗?

13 投票
3 回答
3497 浏览
提问于 2025-04-18 10:31

我一直在参考django-rest-swagger的文档,特别是里面有一部分叫做“它是如何工作的”。这部分说明了你可以为你的REST API定义自己的参数,并让这些参数在你的swagger文档页面上显示出来。

文档中的注释示例大概是这样的:

"""    
This text is the description for this API    
param1 -- A first parameter    
param2 -- A second parameter    
"""    

我能让这个工作,但我遇到的问题是如何指定变量是否是必需的、它的参数类型和数据类型。GitHub页面上有一张示例图片,展示了你的swagger文档可能的样子,里面包含了我刚才提到的信息。但是当我像示例那样注释我的自定义参数时,我的参数只显示为参数类型:“query”,数据类型是空的,并且没有显示“必需”。

我找到的最接近答案的地方是在这个StackOverflow问题中。看起来有个回答者说django-rest-swagger通过自动检查你的序列化器来生成文档(这没问题),但是modelserializers没有足够的信息让django-rest-swagger正确推导出我刚才提到的标准。我明白它无法弄清楚这些标准,但我肯定有办法手动指定这些信息。

我理解的意思是,如果我把modelserializers重写成普通的序列化器,django-rest-swagger才会显示我想要的内容吗?难道我没有办法手动告诉django-rest-swagger一个参数的参数类型和数据类型应该是什么,以及它是否是必需的吗?

我知道我一定是漏掉了什么。我使用的类视图和modelserializers几乎和django-rest-framework教程中的示例一模一样。看起来我只是对这个上下文中的“参数类型”理解得不够。我的API运行得很好,我不想为了获得更好的自动文档而把modelserializers重写成序列化器。

3 个回答

0

在你的代码中:

"""
这段文字是这个API的描述
param1 -- 第一个参数
param2 -- 第二个参数
"""

试试这样:

""" 这段文字是这个API的描述
param1 -- 第一个参数
param2 -- 第二个参数
"""

我发现一些Python和/或Django的插件需要文档字符串的第一行,也就是开头的三个双引号那一行,作为文档的开始。你甚至可以试试在最后一个双引号和字母T之间不留空格。

1

在大多数情况下,ModelSerializer 是你需要的工具,因为它可以根据你的需求进行很大的自定义。理想情况下,你应该在模型类中定义所有的约束,比如字段的 required 属性,但有时候从架构上来说,这样做是不可能的。这时,你可以在 ModelSerializer 的子类中重写这样的字段:

from django.contrib.auth import get_user_model
from rest_framework import serializers


class UserSerializer(serializers.ModelSerializer):
    first_name = serializers.CharField(required=True)
    last_name = serializers.CharField(required=True)

    class Meta:
        model = get_user_model()

在上面的例子中,我对 Django 的标准用户模型进行了序列化,并重写了 required 属性,这样 first_namelast_name 就变成了必填项。

当然,也有一些情况是使用 ModelSerializer 很困难或者不可能,这时你可以选择使用 Serializer 的子类。

2

ModelSerializers 是使用 DR-Swagger 的正确方法。不过,搞清楚不同的 Swagger 字段是从哪里来的有点棘手。我经常需要通过逐步调试页面渲染过程,来弄明白这些东西的来源。

具体来说:

“Required?” 这个字段是来自 Field.required 参数(可以在模型或 Serializer 字段上设置)。

描述信息则来自 Field.help_text 参数。

在新的 DRF 序列化方式中,描述文本是来自 ViewSet 的文档字符串。如果你想要针对某个方法的具体文档,你需要为每个方法重写文档字符串,比如 retrieve 方法:

def retrieve(self, request, *args, **kwargs):
    """Retrieve a FooBar"""
    return super().retrieve(request, *args, **kwargs)

需要注意的是,DR-Swagger 在 2.0 版本(对应 DRF 3.5 版本)中迁移到了新的 DRF 架构逻辑,这里还有一些不太完善的地方。我建议使用 DR-Swagger 的 0.3.x 版本,虽然这个版本已经不再维护,但它的功能更多,而且根据我的经验,序列化的可靠性更高。

撰写回答