From 3c14118fd1a781db7bcde67e5f7fe060de16f455 Mon Sep 17 00:00:00 2001 From: Federico Bond Date: Mon, 6 Jan 2025 12:28:22 -0500 Subject: [PATCH] Add support for x-enumDescriptions extension --- drf_spectacular/plumbing.py | 3 +++ drf_spectacular/settings.py | 2 ++ tests/test_plumbing.py | 13 +++++++++++++ 3 files changed, 18 insertions(+) diff --git a/drf_spectacular/plumbing.py b/drf_spectacular/plumbing.py index eb4799fb..b37306b5 100644 --- a/drf_spectacular/plumbing.py +++ b/drf_spectacular/plumbing.py @@ -456,6 +456,9 @@ def build_choice_field(field) -> _SchemaType: if spectacular_settings.ENUM_GENERATE_CHOICE_DESCRIPTION: schema['description'] = build_choice_description_list(field.choices.items()) + if spectacular_settings.ENUM_GENERATE_X_ENUM_DESCRIPTIONS: + schema['x-enumDescriptions'] = dict(field.choices) + schema['x-spec-enum-id'] = list_hash([(k, v) for k, v in field.choices.items() if k not in ('', None)]) return schema diff --git a/drf_spectacular/settings.py b/drf_spectacular/settings.py index 075f3c20..ba384a6a 100644 --- a/drf_spectacular/settings.py +++ b/drf_spectacular/settings.py @@ -120,6 +120,8 @@ 'ENUM_ADD_EXPLICIT_BLANK_NULL_CHOICE': True, # Add/Append a list of (``choice value`` - choice name) to the enum description string. 'ENUM_GENERATE_CHOICE_DESCRIPTION': True, + # Add x-enumDescriptions extension field to enum schemas. + 'ENUM_GENERATE_X_ENUM_DESCRIPTIONS': False, # Optional suffix for generated enum. # e.g. {'ENUM_SUFFIX': "Type"} would produce an enum name 'StatusType'. 'ENUM_SUFFIX': 'Enum', diff --git a/tests/test_plumbing.py b/tests/test_plumbing.py index b1bdc63e..4c72454d 100644 --- a/tests/test_plumbing.py +++ b/tests/test_plumbing.py @@ -5,6 +5,7 @@ import typing from datetime import datetime from enum import Enum +from unittest import mock if sys.version_info >= (3, 8): from typing import TypedDict @@ -424,6 +425,18 @@ def test_choicefield_empty_choices(): assert schema['type'] == 'string' +@mock.patch('drf_spectacular.settings.spectacular_settings.ENUM_GENERATE_X_ENUM_DESCRIPTIONS', True) +def test_choicefield_x_enumdescriptions(): + schema = build_choice_field(serializers.ChoiceField( + [('bluepill', 'Blue Pill'), ('redpill', 'Red Pill')], + allow_null=True, allow_blank=True + )) + assert schema['x-enumDescriptions'] == { + 'bluepill': 'Blue Pill', + 'redpill': 'Red Pill', + } + + def test_safe_ref(): schema = build_basic_type(str) schema['$ref'] = '#/components/schemas/Foo'