我必须创建一个类,其实例必须符合两个条件:
str
子类,以便可以传递给os.listdir()
mailing.conf.StrConfRef('another string')
以下是我尝试过的:
class StrConfRef(str):
def __new__(cls, name, within=None):
value = globals()[name]
if within:
value = within.format(value)
self = str.__new__(cls, value)
self.name = name
self.within = within
return self
def deconstruct(self):
return ('{}.{}'.format(__name__, self.__class__.__name__), (self.name,),
{'within': self.within})
第一点值得尊重os.listdir(StrConfRef(...))
。然而,它在迁移中仍然被评估为“标准字符串”。我检查了一下django.db.migrations.autodetector
,发现当代码执行时,StrConfRef 实例会到达这一行(这是预料之中的,应该意味着 StrConfRef 被正确解构了)。
所以我想知道为什么它在我的迁移中显示为字符串,而不是 mailing.conf.StrConfRef 实例。以及如何满足我的条件。
不幸的是,看起来具有deconstruct()
方法的对象并不比str
子类具有优先级。
您可以在这里使用django.db.migrations.writer.SettingsReference
看起来优先于的类str
。
我建议你创建一个自定义字段子类,默认为你的conf
字段值。例如,你Campaign.prefix_subject
可以是这个类的一个实例:
class PrefixSubject(models.BooleanField):
default_help_text = (
'Wheter to prefix the subject with "{}" or not.' % conf.SUBJECT_PREFIX
)
def __init__(self, *args, **kwargs):
kwargs.setdefault('help_text', default_help_text)
super().__init__(*args, **kwargs)
def deconstruct(self):
name, path, args, kwargs = super().deconstruct()
if kwargs['help_text'] == self.default_help_text:
kwargs.pop('help_text')
return name, path, args, kwargs