在Django中如何把文件放在灯具中? [英] How do you put a file in a fixture in Django?

查看:110
本文介绍了在Django中如何把文件放在灯具中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以很容易地填写一个文件名为Django的FileField或ImageField,但该文件不存在,当我尝试测试我的应用程序时,该文件不存在。 p>

如何正确填充Django fixture中的FileField或Imagefield,以便文件本身也可用?

解决方案

我很担心简单的答案是你不能使用FileField或ImageField类来执行此操作;它们只存储文件路径,并且没有真正的文件实际数据概念。然而,长的答案是,如果您利用Django API编写自己的自定义模型字段



至少要实现 value_to_string 方法来转换序列化数据(上面链接的django文档中有一个例子)。请注意,上面的URL链接中的示例还包括提及子类化FileField和ImageField,这对您的情况有帮助!



您还必须确定数据是否因此应该存储在数据库或文件系统中。如果是前者,则必须将自定义类实现为Blob字段,包括您希望支持的每个DB的定制;当HTML请求.gif / .jpg / .png / .whatever url时,您还必须提供一些支持,以便如何将数据返回给数据库中的用户。如果后者是更智能的IMHO方式,则必须实现将二进制数据序列化到文件系统的方法。无论哪种方式,如果您将它们实现为FileField和ImageField的子类,那么您仍然可以使用管理工具和其他预期具有此类功能的模块。



如果只有当您选择使用更多涉及的blob方法时,以下是来自旧项目的代码片段(当我正在学习Django时),它处理MySQL和PostgreSQL的Blob;你可能可以找到一些改进,因为我没有碰到它,因为:-)虽然它不处理序列化,所以你必须使用上面的方法添加。

从django.db导入模型
从django.conf导入设置

类BlobValueWrapper(对象):
包装blob值,以便我们可以覆盖unicode方法
查询成功后,Django会尝试记录执行的最后一个查询
,在这一点上它试图强制查询字符串
到unicode这不适用于二进制数据并生成
未捕获的异常

def __init __(self,val):
self。 val = val

def __str __(self):
return'blobdata'

def __unicode __(self):
return u'blobdata'


class BlobField(models.Field):
我们支持的数据库中保留二进制数据的字段。
__metaclass__ = models.SubfieldBase

def db_type(self):
如果settings.DATABASE_ENGINE =='mysql':
return'LONGBLOB'
elif settings.DATABASE_ENGINE =='postgresql_psycopg2':
return'bytea'
else:
raise NotImplementedError

def to_python(self,value):
如果settings.DATABASE_ENGINE =='postgresql_psycopg2':
如果值为None:
返回值
返回str(值)
else:
返回值

def get_db_prep_save(self,value):
如果值为None:
return None
如果settings.DATABASE_ENGINE =='postgresql_psycopg2':
return psycopg2.Binary值)
else:
返回BlobValueWrapper(value)


I can easily fill the field of a FileField or ImageField in a Django fixture with a file name, but that file doesn't exist and when I try to test my application it fails because that file doesn't exist.

How do I correctly populate a FileField or Imagefield in a Django fixture so that the file itself is available too?

解决方案

I'm afraid the short answer is that you can't do this using the FileField or ImageField classes; they just store a file path and have no real concept of the file's actual data. The long answer, however, is that anything is possible if you leverage the Django API for writing your own custom model fields.

At a minimum, you'll want to implement the value_to_string method to convert the data for serialization (there's an example in the django docs at the link above). Note that the examples at the URL link above also include mention of subclassing FileField and ImageField, which is helpful for your situation!

You'll also have to decide if the data should therefore be stored in the database, or on the file system. If the former, you will have to implement your custom class as a Blob field, including customization for every DB you wish to support; you'll also have to provide some support for how the data should be returned to the user out of the database when the HTML requests a .gif/.jpg/.png/.whatever url. If the latter, which is the smarter way to go IMHO, you'll have to implement methods for serializing, de-serializing binary data to the filesystem. Either way, if you implement these as subclasses of FileField and ImageField, you should still be able to use the Admin tools and other modules that expect such django features.

If and only if you elect to use the more involved blob approach, here's a snippet of code from an old project of mind (back when I was learning Django) that handles blob for MySQL and PostgreSQL; you'll probably be able to find a number of improvements as I haven't touched it since :-) It does not handle serialization, though, so you'll have to add that using the method above.

from django.db import models
from django.conf import settings

class BlobValueWrapper(object):
    """Wrap the blob value so that we can override the unicode method.
    After the query succeeds, Django attempts to record the last query
    executed, and at that point it attempts to force the query string
    to unicode. This does not work for binary data and generates an
    uncaught exception.
    """
    def __init__(self, val):
        self.val = val

    def __str__(self):
        return 'blobdata'

    def __unicode__(self):
        return u'blobdata'


class BlobField(models.Field):
    """A field for persisting binary data in databases that we support."""
    __metaclass__ = models.SubfieldBase

    def db_type(self):
        if settings.DATABASE_ENGINE == 'mysql':
            return 'LONGBLOB'
        elif settings.DATABASE_ENGINE == 'postgresql_psycopg2':
            return 'bytea'
        else:
            raise NotImplementedError

    def to_python(self, value):
        if settings.DATABASE_ENGINE == 'postgresql_psycopg2':
            if value is None:
                return value
            return str(value)
        else:
            return value

    def get_db_prep_save(self, value):
        if value is None:
            return None
        if settings.DATABASE_ENGINE =='postgresql_psycopg2':
            return psycopg2.Binary(value)
        else:
            return BlobValueWrapper(value)

这篇关于在Django中如何把文件放在灯具中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆