Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在子类化django';s模型文件字段_Python_Django_Django Models - Fatal编程技术网

Python 在子类化django';s模型文件字段

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

我试图对Django的
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元组,以重新创建字段:

  • 模型上字段的名称
  • 字段的导入路径(例如“django.db.models.IntegerField”)。这应该是最便携的 版本,所以不太具体可能更好
  • 位置参数的列表
  • 一组关键字参数
  • 因此,您需要重写此方法并将自己的kwarg传递给它,以便可以序列化字段:

    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元组,以重新创建字段:

  • 模型上字段的名称
  • 字段的导入路径(例如“django.db.models.IntegerField”)。这应该是最便携的 版本,所以不太具体可能更好
  • 位置参数的列表
  • 一组关键字参数
  • 因此,您需要重写此方法并将自己的kwarg传递给它,以便可以序列化字段:

    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秒左右