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
Code of Conduct
Feature Description
Group the constants exported by
django.db.modelsunder 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.modelsgive no hint of where they apply. Names likeSET, 1 SET_NULL, orDO_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, theChoicesclasses and the internalOnConflict.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:
SETis 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).SETtakes 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_deleteaccepts user supplied callables, so an enum documents the built-in options rather than closing the set of accepted values.enum.Enumis registered toEnumSerializer, and the autodetector deconstructs objects exposingdeconstruct(), so newly written migrations are covered.Implementation Suggestions
No response