2011-03-30 40 views
0

如何在不使用表单的情况下在Django ImageField中注册图像文件,而不是复制任何文件?如何使用Django的ORM注册图像

我必须位于/图像几千JPG文件,我想类似的图像模型来注册它们:

class Image(models.Model): 
    image = models.ImageField(upload_to='images', max_length=1000) 
    hash = models.CharField(max_length=1000, unique=True) 

但是,所有的文档我可以找到关于“加载”图像变成一个Django项目假设我是通过表单进行的,这也意味着图像将被复制到MEDIA_ROOT。我没有使用表单,并且我不想重新复制数千个JPG,因为它们已经是它们应该存在的地方。我只是想创建图像记录,将存储我目前所有图像的文件名。我已经编写了一个简单的Python脚本来遍历每个图像,但我找不到如何正确创建图像记录。

我还希望存储图像内容的散列,以防止重复记录。例如

import hashlib 
content = open(image_filename).read() 
h = hashlib.sha512() 
h.update(content) 
imgobj.hash = h.hexdigest() 
imgobj.save() 

我会重写默认的model.Model.save()方法来做到这一点吗?

回答

1

如果您有脚本来遍历目录中的图像,那么您几乎可以找到解决方案。 Django会只存储路径图像在你Image.image字段,因此基本上所有你需要在你的循环要做的是:

#pseudo-code 
for image_file in image_files: 
    image, created = Image.objects.get_or_create(hash=the_hash, \ 
     defaults={'image' : 'path/to/image', 'hash' : the_hash) 

这是建立在只有数据库中的唯一记录,而不一个非常简单的方法必须移动文件或使用表单。如果它存在,你要么通过哈希无害地返回图像,要么创建新的记录。

希望有帮助!

+0

谢谢,这很方便。唯一的缺点是我希望哈希值是透明的,所以我不必在模型之外明确产生哈希值。但我看到这会如何简化事情。 – Cerin 2011-03-30 16:14:58

+0

我刚刚注意到,Django似乎会自动修改图像路径,以确保它是唯一的,这在我的情况下会导致存储不正确的路径。例如如果我尝试并保存image ='myimage.jpg',它实际上存储'myimage_1.jpg'。你知道如何禁用它吗?我一直在研究FileField属性的代码,但是我无法找到完成的地方。 – Cerin 2011-03-30 17:18:43

+0

嗯。我不知道如何禁用自动重命名。使用get_or_create并检查散列*应该*防止重复的文件被保存。如果不是这样,我需要通过一些实际的代码来了解为什么它不能按预期工作。 – Brandon 2011-03-30 18:52:31

1

通过代码挖掘,以及一些片段,我发现拼凑后,以下似乎为我工作:

models.py

import os, hashlib 
from django.db import models 

class Image(models.Model): 
    image = models.ImageField(upload_to=IMAGE_UPLOAD_TO, max_length=1000) 
    hash = models.CharField(max_length=1000, unique=True) 

    def save(self, *args, **kwargs): 
     # Update image hash to ensure uniqueness. 
     h = hashlib.sha512() 
     h.update(self.image.read()) 
     self.hash = h.hexdigest() 
     return models.Model.save(self, *args, **kwargs) 

import_images.py

import os 
from django.conf import settings 
from django.core.files import File 
from myapp import models 

fn = os.path.join(settings.MEDIA_ROOT, 'images', 'mytestimage.jpg') 
img = models.Image() 
img.image.save(fn, File(open(fn, 'r'))) 
img.save()