2011-03-30 36 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()