Python 在子类化django';s模型文件字段
我试图对Django的Python 在子类化django';s模型文件字段,python,django,django-models,Python,Django,Django Models,我试图对Django的models.FileField进行子类化,但在某些地方,实例化出了很大的问题 这是我的密码: 类DatafileObjectField(models.FileField): def uuu init uuuu(self,source_key=None,**kwargs): 打印('SOURCE KEY为:',SOURCE_KEY) 源=设置。数据源[源\键] kwargs[“存储”]=导入字符串(源[“存储”])(**源[“存储设置”]) 超级() 类MyModel(mo
models.FileField
进行子类化,但在某些地方,实例化出了很大的问题
这是我的密码:
类DatafileObjectField(models.FileField):
def uuu init uuuu(self,source_key=None,**kwargs):
打印('SOURCE KEY为:',SOURCE_KEY)
源=设置。数据源[源\键]
kwargs[“存储”]=导入字符串(源[“存储”])(**源[“存储设置”])
超级()
类MyModel(models.Model):
#这是我整个代码库中对该字段的唯一引用
#然而,不知何故,django在没有source_键参数的情况下实例化了该字段
file=DatafileObjectField(source\u key='my-data-source',help\u text=“上传包含mast时间序列的数据文件”)
当我这样做时:
python mange.py makemigrations
该打印声明发布了两次:
SOURCE KEY IS: my-data-source
<output from checks>
SOURCE KEY IS: None
django到底在干什么?为什么不总是传递源密钥?模型/模型字段需要可序列化才能在迁移系统中使用。Django对类使用
deconstruct
方法使它们可序列化。该方法符合以下要求:
返回具有足够信息的4元组,以重新创建字段:
class DatafileObjectField(models.FileField):
def __init__(self, source_key=None, **kwargs):
print('SOURCE KEY IS:', source_key)
source = settings.DATA_SOURCES[source_key]
kwargs["storage"] = import_string(source["storage"])(**source["storage_settings"])
super().__init__(**kwargs)
def deconstruct(self):
name, path, args, kwargs = super().deconstruct()
kwargs['source_key'] = get_source_key_from_storage(self.storage) # Somehow get source key here?
return name, path, args, kwargs
注意:我使用了一些不存在的函数
从存储中获取\u source\u key\u
,因为您没有在字段实例上设置它。您可以以某种方式获取源密钥,也可以在实例上设置源密钥并在此处使用。模型/模型字段需要可序列化才能在迁移系统中使用。Django对类使用deconstruct
方法使它们可序列化。该方法符合以下要求:
返回具有足够信息的4元组,以重新创建字段:
class DatafileObjectField(models.FileField):
def __init__(self, source_key=None, **kwargs):
print('SOURCE KEY IS:', source_key)
source = settings.DATA_SOURCES[source_key]
kwargs["storage"] = import_string(source["storage"])(**source["storage_settings"])
super().__init__(**kwargs)
def deconstruct(self):
name, path, args, kwargs = super().deconstruct()
kwargs['source_key'] = get_source_key_from_storage(self.storage) # Somehow get source key here?
return name, path, args, kwargs
注意:我使用了一些不存在的函数
从存储中获取\u source\u key\u
,因为您没有在字段实例上设置它。您可以以某种方式获取源密钥,或者在实例上设置源密钥并在此处使用。好的,找到它。我在中看到了解构
方法的提到,但没有完全理解它的目的
基本上,字段被实例化(正确地说,这是问题中的第一个打印输出),然后makemigrations
使用其解构方法来确定迁移中需要保存哪些信息
它告诉迁移实际存储的重要内容
因此,在我的例子中,我需要将storage\u键kwarg添加到deconstruct()
方法返回的值中(这意味着将其保存在模型上)
在这个特定的用例中,因为我要确定在实例化时要使用什么存储类,所以我不需要序列化存储
kwarg,所以我将其删除
工作解决方案:
类DatafileObjectField(models.FileField):
def uuu init uuuu(self,source_key=None,**kwargs):
self.source\u key=source\u key
源=设置。八位数据源[源\键]
kwargs[“存储”]=导入字符串(源[“存储”])(**源[“存储设置”])
超级()
def解构(自我):
名称、路径、参数、kwargs=super().deconstruct()
#确保迁移知道实例化需要此设置键
kwargs[“源密钥”]=self.source\u密钥
#删除不再需要的此键(在初始化期间计算)
kwargs.pop(“存储”)
返回名称、路径、参数、kwargs
好的,算了。我在中看到了解构
方法的提到,但没有完全理解它的目的
基本上,字段被实例化(正确地说,这是问题中的第一个打印输出),然后makemigrations
使用其解构方法来确定迁移中需要保存哪些信息
它告诉迁移实际存储的重要内容
因此,在我的例子中,我需要将storage\u键kwarg添加到deconstruct()
方法返回的值中(这意味着将其保存在模型上)
在这个特定的用例中,因为我要确定在实例化时要使用什么存储类,所以我不需要序列化存储
kwarg,所以我将其删除
工作解决方案:
类DatafileObjectField(models.FileField):
def uuu init uuuu(self,source_key=None,**kwargs):
self.source\u key=source\u key
源=设置。八位数据源[源\键]
kwargs[“存储”]=导入字符串(源[“存储”])(**源[“存储设置”])
超级()
def解构(自我):
名称、路径、参数、kwargs=super().deconstruct()
#确保迁移知道实例化需要此设置键
kwargs[“源密钥”]=self.source\u密钥
#删除不再需要的此键(在初始化期间计算)
kwargs.pop(“存储”)
返回名称、路径、参数、kwargs
啊,你比我快了5秒左右