#31861: Model field for enumeration types
-------------------------------------+-------------------------------------
               Reporter:  George     |          Owner:  nobody
  Sakkis                             |
                   Type:  New        |         Status:  new
  feature                            |
              Component:  Database   |        Version:  3.1
  layer (models, ORM)                |
               Severity:  Normal     |       Keywords:  enumeration
           Triage Stage:             |      Has patch:  0
  Unreviewed                         |
    Needs documentation:  0          |    Needs tests:  0
Patch needs improvement:  0          |  Easy pickings:  0
                  UI/UX:  0          |
-------------------------------------+-------------------------------------
 The new enumeration types in Django 3.0 are a great addition and
 improvement over the previous choices. On the ORM layer however, only the
 enumeration values are represented, not the enumeration members. I'd like
 to suggest a new `EnumField` custom field that refers to the actual
 enumeration member, similar to how `ForeignKey` fields refers to the
 related model object instead of its primary key (or the `to_field` in
 general). Proposed usage for the
 [https://docs.djangoproject.com/en/3.1/ref/models/fields/#enumeration-
 types Student example]:

 {{{
 #!python
 from django.utils.translation import gettext_lazy as _

 class Student(models.Model):

     class YearInSchool(models.TextChoices):
         FRESHMAN = 'FR', _('Freshman')
         SOPHOMORE = 'SO', _('Sophomore')
         JUNIOR = 'JR', _('Junior')
         SENIOR = 'SR', _('Senior')
         GRADUATE = 'GR', _('Graduate')

     year_in_school = models.EnumField(YearInSchool,
 default=YearInSchool.FRESHMAN)

     def is_upperclass(self):
         return self.year_in_school in {
             self.YearInSchool.JUNIOR,
             self.YearInSchool.SENIOR,
         }
 }}}

 In this case, `Student.year_in_school` would be a `YearInSchool` member,
 not a two-letter string.

 The proposed signature is the following: `class EnumField(enum_type,
 field_type=None, **options)`
 - `enum_type` is the enumeration type, i.e. a `models.Choices` subclass.
 - `field_type` is the underlying ORM field type, e.g. `models.CharField`
 or `models.PositiveSmallIntegerField`.
    - In the simplest implementation, this is a required parameter to be
 provided by the caller.
    - Alternatively, it could be made optional and inferred based on either
 of the following:
      1. a new optional `field(**options)` staticmethod on the enumeration
 type, if present. For example:
       {{{
       #!python
       class YearInSchool(models.TextChoices):
           FRESHMAN = 'FR', _('Freshman')
           SOPHOMORE = 'SO', _('Sophomore')
           JUNIOR = 'JR', _('Junior')
           SENIOR = 'SR', _('Senior')
           GRADUATE = 'GR', _('Graduate')

           @staticmethod
           def field(**options):
               options.setdefault("max_length", 2)
               return models.Charfield(**options)
       }}}
      2. Automatically based on the type and values of the enumeration
 members:
       - For string values: a `CharField` with `max_length` the maximum
 length of the enumeration values.
       - For integer values: one of {`PositiveSmallIntegerField`,
 `SmallIntegerField`, `PositiveIntegerField`, `IntegerField`,
 `BigIntegerField`}, the smallest that can represent all the enumeration
 values.
       - And so on for other types where there is a natural python type <=>
 ORM field mapping, e.g. `DateField` for date values.
       - If the field type cannot be inferred, raise an appropriate
 exception.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/31861>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/050.a20e2e8cd3699ce6a35fc229b29228f7%40djangoproject.com.

Reply via email to