Skip to content

Consider grouping the constants exported by django.db.models under enums #197

Description

@nessita

Code of Conduct

  • I agree to follow Django's Code of Conduct

Feature Description

Group the constants exported by django.db.models under enums, so that each set of accepted values for a given argument lives in one named place instead of the flat module namespace.

(We discussed the following idea during a Steering Council - Fellow monthly meeting, and after I created a ticket for it, the Fellows agreed that using this board first would be more appropriate, to ensure there is enough community support for the proposal before accepting it.)

Problem

The constants exported by django.db.models give no hint of where they apply. Names like SET, 1 SET_NULL, or DO_NOTHING` say what happens but not which argument accepts them, and unrelated groups sit next to each other in one namespace with nothing separating them. Reading code means knowing the convention already, and writing it means guessing or checking the docs.

The problem grows with every group added. django/django#21696 renames one constant to keep a new group from being confused with an existing one, which works but relies on prefixes holding up as more values arrive.

Request or proposal

proposal

Additional Details

Enums address this directly. The valid options for an argument become discoverable from a single object, membership is visible at the call site, and new groups cost nothing in namespace clarity. Django already applies the pattern inside the ORM with Deferrable, WindowFrameExclusion, the Choices classes and the internal OnConflict.

An enum was proposed during the review linked above. The Steering Council discussed it on 2026-08-03 and agreed the change makes sense across the exported constants rather than for one group in isolation, which is what this request covers.

Points that need working out:

  • The constants do not share a shape. Some are plain functions, some are class instances, and SET is a factory returning a configured callable. Plain functions assigned in an enum body become methods rather than members, so member values need a deliberate form. One option is to give every value the same shape, a small strategy instance, which is already how the fetch modes are built (thanks @jacobtylerwalls for that pointer).
  • SET takes an argument, so it cannot be a fixed member. It may fit as a staticmethod on the enum returning an object that implements the same protocol.
  • on_delete accepts user supplied callables, so an enum documents the built-in options rather than closing the set of accepted values.
  • Existing migration files reference the current import paths, so the module-level names have to keep resolving. enum.Enum is registered to EnumSerializer, and the autodetector deconstructs objects exposing deconstruct(), so newly written migrations are covered.
  • Naming, and whether the current names become permanent aliases or get a deprecation path.

Implementation Suggestions

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Django CoreThis idea is suitable for inclusion in Django itself.Models/ORM

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions