How to Register Images using Django's ORM
How do you register an image file in a Django ImageField without using a form, and not copying any files?
I have several thousand JPGs located at /images, and I want to register them in an Image model similar to:
class Image(models.Model):
image = models.ImageField(upload_to='images', max_length=1000)
hash = models.CharField(max_length=1000, unique=True)
However, all the docs I can find on "loading" images into a Django project assume I'm doing so via a form, which also implies the image will be copied to MEDIA_ROOT. I'm not using a form, and I don't want to re-copy the several thousand JPGs, since they're already where they're supposed to be. I just want to create Image records that will store the filename of all the images I currently have. I've written a simple Python script to loop over each image, but I can't find how to properly create the Image record.
I also want to store a hash of the image content, to prevent duplicate records. e.g.
import hashlib
content = open(image_filename).read()
h = hashlib开发者_JS百科.sha512()
h.update(content)
imgobj.hash = h.hexdigest()
imgobj.save()
Would I override the default model.Model.save() method to do this?
If you have the script to loop over the images in your directory, you're nearly to a solution. Django will only store the path to the image in your Image.image field so basically all you need to do in your loop is:
#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)
That's a pretty easy way to build up only the unique records in your database without having to move the files, or use a form. You're either going to harmlessly return the image by the hash if it exists, or you're going to create a new record.
Hope that helps!
After digging through the code, and piecing together a few snippets I found, the following seems to work for me:
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()
精彩评论