如何解决Django:如何创建类的枚举以定义选择
如何对模型进行子类化。选择定义类的枚举?
以下代码引发TypeError:
from django.db.models import Choices
class DataTypes(type,Choices):
CHAR = str,_('Short string')
INTEGER = int,_('Integer')
错误消息:
dynamic_attributes = {k for c in enum_class.mro()
TypeError: descriptor 'mro' of 'type' object needs an argument
更新:
不使用mixin时,不会出现错误。但是,同样的,成员的值不能正确转换为所需的数据类型。
class DataTypes(Choices):
CHAR = str,_('Integer')
测试:
str in (DataTypes.CHAR,DataTypes.INTEGER) # False
解决方法
我在评论中同意威廉·范·昂森的观点。我认为无法将HTTP Server
用于类等数据类型。因此,我试图找到一种可以扩展其他类的方法。
也实现了定义选项的标签(就像Django Choices一样)。
models.Choices
现在,您可以创建Choices类,也可以将其子类化:
def _is_dunder(name):
"""
Stolen liberally from 'aenum'.
Returns True if a __dunder__ name,False otherwise.
"""
return (len(name) > 4 and
name[:2] == name[-2:] == '__' and
name[2] != '_' and
name[-3] != '_')
class ChoicesMeta(type):
def __new__(mcs,cls,bases,attrs):
# ignore any keys listed in _ignore_
ignore = attrs.setdefault('_ignore_',[])
ignore.append('_ignore_')
# save constant names into list.
names = [k for k in attrs if not(_is_dunder(k) or k in ignore)]
# save constant labels into list.
labels = []
for k in names:
value = attrs[k]
if (
isinstance(value,(list,tuple)) and
len(value) > 1 and
isinstance(value[-1],(Promise,str))
):
value,label = value
else:
label = k.replace('_',' ').title()
labels.append(label)
attrs[k] = value
new_cls = super().__new__(mcs,attrs)
new_cls.local_names = names
new_cls.local_labels = labels
return new_cls
@property
def names(cls):
names = []
for c in reversed(cls.__mro__):
names.extend(getattr(c,'local_names',[]))
return list(dict.fromkeys(names))
@property
def choices(cls):
empty = [(None,cls.__empty__)] if hasattr(cls,'__empty__') else []
return empty + [(getattr(cls,name),cls.labels[i]) for i,name in enumerate(cls.names)]
@property
def labels(cls):
labels = []
for c in reversed(cls.__mro__):
labels.extend(getattr(c,'local_labels',[]))
return list(dict.fromkeys(labels))
class Choices(metaclass=ChoicesMeta):
pass
测试:
class DataTypes(Choices):
CHAR = str,_('Short string')
INTEGER = int
class OtherTypes(DataTypes):
BOOLEAN = bool,_('Boolean (Either True or False)')
FLOAT = float,_('Floating point number')
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。