django - 在 drf-yasg OpenAPI 和 Swagger 视图中显示 SlugRelatedField 的可能值(选择)
问题描述
我有几个用作枚举的模型(基本上,模型只是一个名称和一个蛞蝓),如货币和国家等,我试图在 drf-yasg 中显示可用的选择但没有成功。我最后一次尝试是将它添加到序列化程序的 Meta 类中:
swagger_schema_fields = {
'currency': {'enum': list(Currency.objects.values_list('slug', flat=True))}
}
但是当然它失败了——它不仅没有显示枚举值,而且还破坏了序列化程序(因为它使用字符串而不是实际模型)。
有没有办法做到这一点?
解决方案
最终,我添加了一个新的字段类,它完全符合我的需要。我不能保证这是解决这个问题的最有效方法(检索 swagger 页面似乎需要更长的时间),但它可以完成工作:
# choices_slug_field.py
from drf_yasg.inspectors import RelatedFieldInspector
from rest_framework.metadata import SimpleMetadata
from rest_framework.relations import SlugRelatedField
from rest_framework.serializers import ManyRelatedField, RelatedField
class ShowChoicesMetadata(SimpleMetadata):
def get_field_info(self, field):
field_info = super().get_field_info(field)
if (not field_info.get('read_only') and
isinstance(field, (ManyRelatedField, RelatedField)) and
hasattr(field, 'choices') and
getattr(field, 'show_choices', False)):
field_info['choices'] = [
{
'value': choice_value,
'display_name': str(choice_name)
}
for choice_value, choice_name in field.choices.items()
]
return field_info
class ShowChoicesMixin:
show_choices = True
class ChoicesSlugRelatedField(ShowChoicesMixin, SlugRelatedField):
pass
class ShowChoicesFieldInspector(RelatedFieldInspector):
def field_to_swagger_object(self, field, swagger_object_type, use_references, **kwargs):
dataobj = super().field_to_swagger_object(field, swagger_object_type, use_references, **kwargs)
if (isinstance(field, ChoicesSlugRelatedField) and hasattr(field, 'choices')
and getattr(field, 'show_choices', False) and 'enum' not in dataobj):
dataobj['enum'] = [k for k, v in field.choices.items()]
return dataobj
推荐阅读
- postgresql - 为什么 Postgres 在仅索引扫描中花费这么多时间
- python - 如何使用 PIL、Python 将多个输出图像保存在一个文件夹中
- oracle-apex - 标记重复项目的最佳实践
- angular - 在新的 Angular 11 项目上测试缓慢并崩溃
- javascript - 如何在未聚焦时从父项中隐藏元素之前单击它
- javascript - 如何让谷歌表单自动填写
- java - 我想通过单击另一个音乐按钮来停止音乐,并从中开始播放新音乐
- python - DRF 不支持具有多部分/表单数据请求的嵌套序列化程序吗?
- gradle - 将自定义任务的执行限制为 bootBuildImage 的执行
- python - ansible/yaml : 从 dict 获取值作为字符串