一个自定义django字段,可以使用python内部“enum”类的子类作为选择

django-enum-choices的Python项目详细描述


django枚举选项

与python枚举一起使用的自定义django选项字段。

pypi version

目录

安装

pip install django-enum-choices

基本用法

fromenumimportEnumfromdjango.dbimportmodelsfromdjango_enum_choices.fieldsimportEnumChoiceFieldclassMyEnum(Enum):A='a'B='b'classMyModel(models.Model):enumerated_field=EnumChoiceField(MyEnum)

模型创建

instance=MyModel.objects.create(enumerated_field=MyEnum.A)

更改枚举值

instance.enumerated_field=MyEnum.Binstance.save()

过滤

MyModel.objects.filter(enumerated_field=MyEnum.A)

选择生成器

EnumChoiceField扩展CharField并在内部生成选项。每个选项都是使用名为"选项生成器"的东西生成的。

choice builder函数如下:

defchoice_builder(enum:Enum)->Tuple[str,str]:# Some implementation

如果将choice\u builder参数传递给模型的enumchoicefield,则django\u enum\u choice s将使用它生成选项。 选项生成器必须是可调用的,它接受枚举选项并返回元组, 包含要保存的值和可读值。

默认情况下,django_enum_choices使用django_enum_choices.choice_builders中定义的四个选项生成器之一,命名为value

它返回包含枚举值的元组两次:

fromdjango_enum_choices.choice_buildersimportvalue_valueclassMyEnum(Enum):A='a'B='b'print(value_value(MyEnum.A))# ('a', 'a')

您可以使用四个符合您需要的默认选项之一:

    <李>数值
  • 属性值
  • 值属性
  • 属性

例如:

fromdjango_enum_choices.choice_buildersimportattribute_valueclassMyEnum(Enum):A='a'B='b'classCustomReadableValueEnumModel(models.Model):enumerated_field=EnumChoiceField(MyEnum,choice_builder=attribute_value)

枚举字段的结果选择是('a','a'),('b','b'))

您还可以定义自己的选择生成器:

classMyEnum(Enum):A='a'B='b'defchoice_builder(choice:Enum)->Tuple[str,str]:returnchoice.value,choice.value.upper()+choice.valueclassCustomReadableValueEnumModel(models.Model):enumerated_field=EnumChoiceField(MyEnum,choice_builder=choice_builder)

这将导致以下选择:(('a','aa'),('b','bb'))

choice\u buildertuple返回的值将在使用前转换为字符串。

管理面板中的用法

定义为enumChoiceField的模型字段几乎可以与所有管理面板的 标准功能。

一个例外是它们在列表过滤器中的用法

如果您需要EnumChoiceFieldModelAdmin列表过滤器中,可以使用以下命令 选项:

  • 将列表过滤器中的条目定义为一个元组,其中包含字段名和django_enum_choices.admin.enumChoiceListFilter
pip install django-enum-choices
0
  • 将设置中的django_enum_choices_register_list_filter设置为true,这将自动将enumChoiceListFilter类设置为all 列表过滤器枚举字段的实例的字段。这样,它们可以直接在列表过滤器中声明
pip install django-enum-choices
1

与窗体一起使用

有两条经验法则:

  1. 如果您使用modelform,一切都将自动处理。
  2. 如果使用表单,则需要考虑正在使用的enumchoice\u builder
  3. < > >

    django.forms.modelform一起使用
    pip install django-enum-choices
    
    2

    django.forms.form一起使用

    如果您使用的是默认的value\u valuechoice builder,您可以这样做:

    pip install django-enum-choices
    
    3

    如果要传递另一个choice生成器,则还必须将其传递到表单字段:

    pip install django-enum-choices
    
    4

    与django filter一起使用

    与表单一样,有两个一般的经验法则:

    1. 如果您在给定的元模型的元字段中声明了一个枚举字段,那么您需要在筛选器类中继承枚举字段,所有事情都将自动处理。
    2. 如果声明的是显式字段,而没有模型,则需要指定enumclass&;如果使用自定义字段,则需要指定choice\u builder
    3. < > >

      通过使用一个内部类并从EnumchoiceFiltermixin继承
      pip install django-enum-choices
      
      5

      显式使用该字段时,choice\u builder参数也可以传递给django\u enum\u choices.filters.enumchoicefilter。当使用EnumChoiceFilterSetMixin时,选项生成器由模型字段确定,用于在内部类中定义的字段。

      pip install django-enum-choices
      
      6

      通过在FilterSet

      上显式声明字段
      pip install django-enum-choices
      
      7

      Postgres ArrayField用法

      您可以将EnumChoiceField用作PostgresArrayField的子字段

      pip install django-enum-choices
      
      8

      模型创建

      pip install django-enum-choices
      
      9

      更改枚举值

      fromenumimportEnumfromdjango.dbimportmodelsfromdjango_enum_choices.fieldsimportEnumChoiceFieldclassMyEnum(Enum):A='a'B='b'classMyModel(models.Model):enumerated_field=EnumChoiceField(MyEnum)
      0

      与django rest framework一起使用

      与窗体和筛选器一样,有两个一般经验法则:

      1. 如果您使用的是ModelSerializer并且继承了EnumChoiceModelSerializerMixin,则将自动处理所有问题。
      2. 如果您使用的是序列化程序,则需要将enumclass&;code>choice\u builder带入一个帐户。
      3. < > >

        序列化程序.modelserializer枚举选项一起使用emodelSerializerMixin

        fromenumimportEnumfromdjango.dbimportmodelsfromdjango_enum_choices.fieldsimportEnumChoiceFieldclassMyEnum(Enum):A='a'B='b'classMyModel(models.Model):enumerated_field=EnumChoiceField(MyEnum)
        1

        默认情况下,modelserializer.build_standard_field强制具有模型字段的任何字段选择choicefield直接返回值。

        由于枚举值类似于enumclass.enum_instance它们在传递给响应时将无法由jsonencoder编码

        这就是我们需要混音的原因。

        EnumChoiceModelSerializerMixin与DRF的Serializer.ModelSerializer一起使用时,Choice\u Builder将自动从模型字段传递到序列化器字段。

        使用serializers.modelserializer而不使用EnumChoiceModelSerializerMixin

        fromenumimportEnumfromdjango.dbimportmodelsfromdjango_enum_choices.fieldsimportEnumChoiceFieldclassMyEnum(Enum):A='a'B='b'classMyModel(models.Model):enumerated_field=EnumChoiceField(MyEnum)
        2

        如果您使用的是自定义的选择生成器,则也需要传递它。

        fromenumimportEnumfromdjango.dbimportmodelsfromdjango_enum_choices.fieldsimportEnumChoiceFieldclassMyEnum(Enum):A='a'B='b'classMyModel(models.Model):enumerated_field=EnumChoiceField(MyEnum)
        3

        使用serializer.serializer的子类
        fromenumimportEnumfromdjango.dbimportmodelsfromdjango_enum_choices.fieldsimportEnumChoiceFieldclassMyEnum(Enum):A='a'B='b'classMyModel(models.Model):enumerated_field=EnumChoiceField(MyEnum)
        4

        如果您使用的是自定义的选择生成器,则也需要传递它。

        序列化PostgreSQL阵列字段

        django enum choices公开可用于序列化枚举数组的multipleEnumChoiceField

        使用serializer.serializer的子类

        fromenumimportEnumfromdjango.dbimportmodelsfromdjango_enum_choices.fieldsimportEnumChoiceFieldclassMyEnum(Enum):A='a'B='b'classMyModel(models.Model):enumerated_field=EnumChoiceField(MyEnum)
        5

        使用serializer.modelserializer的子类

        fromenumimportEnumfromdjango.dbimportmodelsfromdjango_enum_choices.fieldsimportEnumChoiceFieldclassMyEnum(Enum):A='a'B='b'classMyModel(models.Model):enumerated_field=EnumChoiceField(MyEnum)
        6

        如果在序列化程序类上显式定义了枚举字段,则不需要使用EnumchoiceModelSerializerMixin

        实施细节

        • EnumChoiceFieldCharField的子类
        • 只有枚举的子类才是有效的参数。
        • max_length如果通过,将被忽略。最大长度由最长的选项自动计算。
        • 选项是使用特殊的选项生成器函数生成的,该函数接受枚举并返回2个项的元组。
          • 四个choice builder函数在django enum choices.choice builders中定义
          • 默认情况下,使用value\u value选项生成器。它从枚举类中的值生成选项,如(enumeration.value,enumeration.value)
          • choice\u builder可以通过向enumchoicefieldchoice\u builder关键字参数传递一个可调用函数来重写
          • 生成选项时,从选项生成器返回的所有值都将转换为字符串。

        例如,让我们有以下情况:

        fromenumimportEnumfromdjango.dbimportmodelsfromdjango_enum_choices.fieldsimportEnumChoiceFieldclassMyEnum(Enum):A='a'B='b'classMyModel(models.Model):enumerated_field=EnumChoiceField(MyEnum)
        7

        我们将有以下服务:

        • somemodel.enumerated_field.choices==("1","1"),("b","b"))
        • somemodel.enumerated_field.max_length==3

        使用python的enum.auto

        枚举自动可用于简写枚举定义:

        fromenumimportEnumfromdjango.dbimportmodelsfromdjango_enum_choices.fieldsimportEnumChoiceFieldclassMyEnum(Enum):A='a'B='b'classMyModel(models.Model):enumerated_field=EnumChoiceField(MyEnum)
        8

        这将导致以下结果:

        • somemodel.enumerated_field.choices==("1"、"1"),("2"、"2"))

        覆盖自动行为auto创建的枚举的自定义值可以由 子类化定义生成下一个值的枚举

        fromenumimportEnumfromdjango.dbimportmodelsfromdjango_enum_choices.fieldsimportEnumChoiceFieldclassMyEnum(Enum):A='a'B='b'classMyModel(models.Model):enumerated_field=EnumChoiceField(MyEnum)
        9

        上面将把字典中映射的值作为值赋给customautoenum中的属性

        开发

        先决条件

        • sqlite3
        • PostgreSQL服务器
        • python>;=3.5虚拟环境
        instance=MyModel.objects.create(enumerated_field=MyEnum.A)
        0

        整理和运行测试:

        instance=MyModel.objects.create(enumerated_field=MyEnum.A)
        1

        欢迎加入QQ群-->: 979659372 Python中文网_新手群

        推荐PyPI第三方库


热门话题
内存Java正在运行。jar heapdump错误   java如何在安卓画布中弯曲文本区域?   java如何在Gdx 安卓游戏编程中获得矩形的真实触碰位置?   找不到java Spring MVC控制器   在Java中使用双重检查锁定单例扩展类   java在高效的时间和内存中动态执行insert(索引、数据)、delete(索引)、getAt(索引)操作。   java 安卓 Toast和视图帮助   java协议缓冲区:从文件中读取所有序列化消息   java如何在Jackson中为参数化接口类型执行通用自定义反序列化程序   与简单的空检查相比,使用(平面)映射的java优势是什么?   异步方法seam中的java Get contextparam   jar使用相同的java运行时运行另一个java程序   java访问Spring批处理中的作业参数   java给定字符串为空或null   在h2数据库1.4中找不到java类“org.h2.fulltext.FullTextLucene”。*不适用于Lucene Core 4*   java Spring Boot在使用@enableSync时不响应任何请求   java错误:在bash上找不到或加载主类pj2   “返回对象”和“返回(对象)”之间的Java差异   java Android开发:如何使用onKeyUp?