枚举类型-Django3.0

6,417 阅读1分钟

MedusaSorcerer的博客


Django-3.0版本中, 优化之一既是枚举类型(choices)的更好体现的方式, 官方也给出了一个案例:

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.CharField(
        max_length=2,
        choices=YearInSchool.choices,
        default=YearInSchool.FRESHMAN,
    )

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

在3.0版本中, 官方更加推荐你使用这样的方式创建枚举:

#!/usr/bin/env python
# _*_ coding: UTF-8 _*_
from django.db import models


class Medusa(models.Model):

    ON = '1'
    OFF = '0'

    STATUS_CHOICES = [
        (ON, 'online'),
        (OFF, 'offline'),
    ]

    status = models.CharField(
        max_length=1,
        choices=STATUS_CHOICES,
        default=ON,
        help_text='status code'
    )

使用的枚举值可以通过Medusa.objects.filter(status=Medusa.ON)来获取数据, 当然了, 看到此处是不是有疑问: "1""0"为何不用int类型? 因为刚刚只是个CharField的例子, 我们再看看int类型的枚举:

from django.db import models


class Card(models.Model):
    class Suit(models.IntegerChoices):
        DIAMOND = 1
        SPADE = 2
        HEART = 3
        CLUB = 4

    suit = models.IntegerField(choices=Suit.choices)

那么在很多时候存在公用的枚举关系该怎么处理呢?

#!/usr/bin/env python
# _*_ coding: UTF-8 _*_
from django.db import models


class BaseChoices(models.TextChoices):
    INFO = ('200', 'info')
    WARNING = ('300', 'warning')
    ERROR = ('400', 'error')
    DEBUG = ('500', 'debug')


class Medusa(models.Model):
    status = models.CharField(
        max_length=3,
        choices=BaseChoices.choices,
        default=BaseChoices.INFO,
    )

这样的枚举方式更加有利于代码封装和阅读, 快去查阅官方文档看看吧!