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='性别')

效果:

  1. 数据库存放的值为 ‘M'  'F'  'N/A'
  2. 业务逻辑中方便判断:User.objects.filter(sex=SexType.MALE)
  3. 序列化器方便返回字段的描述信息(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'

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值