Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unexpected Enum Component Naming for SerializerMethodField with List[TextChoices] #1379

Open
zhuang42 opened this issue Feb 9, 2025 · 0 comments

Comments

@zhuang42
Copy link

zhuang42 commented Feb 9, 2025

When using a SerializerMethodField to describe a list of values from a Django TextChoices enum, drf‑spectacular generates the referenced enum component name based on the serializer field name rather than the underlying enum class. In our case, even though we use a ChoiceField with choices from the ModelAction enum, the generated OpenAPI schema refers to the component as AllowedActionsEnum (derived from the field name) instead of ModelActionEnum (which is expected from the enum’s class name).

Does this behavior work as intended, or is there a recommended way to override the enum naming?

Minimal Reproducible Example:

  1. model.py
class ModelAction(models.TextChoices):
    SEND = "send", _("Send")
    ACCEPT = "accept", _("Accept")

class ModelA(models.Model):
   

    def get_action(self) -> list[ModelAction]:
        return [ModelAction.SEND, ModelAction.ACCEPT]
  1. serializers.py
class ModelASerializer(serializers.ModelSerializer):
    allowed_actions = serializers.SerializerMethodField()

    @extend_schema_field(
        serializers.ListField(
            child=serializers.ChoiceField(choices=ModelAction.choices)
        )
    )
    def get_allowed_actions(self, obj) -> list[ModelAction]:
        return obj.get_action()

    class Meta:
        model = ModelA
        fields = ["allowed_actions"]

3. Generated OpenAPI Schema
The generated schema uses AllowedActionsEnum (derived from the serializer field name) with a definition similar to:

ModelA:
  type: object
  properties:
    allowed_actions:
      type: array
      items:
        $ref: '#/components/schemas/AllowedActionsEnum'
      readOnly: true

AllowedActionsEnum:
  type: string
  enum:
    - send
    - accept
  description: |-
    * `send` - send
    * `accept` - accept

4. Expected schema

I want to the enum should be referenced as ModelActionEnum (based on the TextChoices class name):

ModelA:
  type: object
  properties:
    allowed_actions:
      type: array
      items:
        $ref: '#/components/schemas/ModelActionEnum'
      readOnly: true

ModelActionEnum:
  type: string
  enum:
    - send
    - accept
  description: |-
    * `send` - send
    * `accept` - accept
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant