Django模型CharField字段类型定义更为优雅的Choice
官方推荐的一种写法:
class SexType(objects):
    MALE = 'M'
    FEMALE = 'F'
    UNKNOWN = 'N/A'
 
    CHOICES = (
        (MALE, '男'),
        (FEMALE, '女'),
        (UNKNOWN, u'未知'),
    )
 
 
class User(models.Model):
    username = models.CharField(max_length=20, unique=True, verbose_name='名称')
    sex = models.CharField(max_length=3, default=SexType.UNKNOWN, choices=SexType.CHOICES, verbose_name='性别')
效果:
数据库存放的值为 ‘M'  'F'  'N/A'
业务逻辑中方便判断:User.objects.filter(sex=SexType.MALE)
序列化器方便返回字段的描述信息(label值):
class UserSerializer(serializers.ModelSerializer):
    sex_t = serializers.CharField(source='get_sex_display', read_only=True, required=False)
    #source='get_sex_display' 固定写法get_xxx_display
    class Meta:
        model = User
        fields = ('id', 'name', 'sex', 'sex_t')
 
序列化结果:
[
    {"id": 1,
     "name": "小明",
     "sex": "M",
     "sex_t": "男"
    },
    {"id": 2,
     "name": "小王",
     "sex": "F",
     "sex_t": "女"
    }
]
Django3.0以后更建议使用Field.choices枚举类型定义choices选项
from django.db import models
class Status(models.TextChoices):
    UNPUBLISHED = 'UN', 'Unpublished'
    PUBLISHED = 'PB', 'Published'
 
 
class Book(models.Model):
    status = models.CharField(
        max_length=2,
        choices=Status.choices,
        default=Status.UNPUBLISHED,
    )
 
 
class Pamphlet(models.Model):
    status = models.CharField(
        max_length=2,
        choices=Status.choices,
        default=Status.PUBLISHED,
    )
数据库存储的值为UN、PB
查询时:
unpublished_books = Book.objects.filter(status=Status.UNPUBLISHED)
还可以轻松将值转换为label:
In [2]: book = Book.objects.latest('id')
 
In [3]: Status(book.status)
Out[3]: <Status.UNPUBLISHED: 'UN'>
 
In [4]: Status(book.status).label
Out[4]: 'Unpublished'

 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号