好吧,我几乎什么都试过了,但我不能让它工作。
我有一个带有ImageField的Django模型
我有通过HTTP下载图像的代码(测试和工作)
图像直接保存到'upload_to'文件夹中(upload_to是在ImageField中设置的)
我所需要做的就是将已经存在的图像文件路径与ImageField关联起来
我用六种不同的方式写了这段代码。
The problem I'm running into is all of the code that I'm writing results in the following behavior:
(1) Django will make a 2nd file, (2) rename the new file, adding an _ to the end of the file name, then (3) not transfer any of the data over leaving it basically an empty re-named file. What's left in the 'upload_to' path is 2 files, one that is the actual image, and one that is the name of the image,but is empty, and of course the ImageField path is set to the empty file that Django try to create.
如果你不清楚,我将尝试说明:
## Image generation code runs....
/Upload
generated_image.jpg 4kb
## Attempt to set the ImageField path...
/Upload
generated_image.jpg 4kb
generated_image_.jpg 0kb
ImageField.Path = /Upload/generated_image_.jpg
我怎样才能做到这一点而不让Django重新存储文件呢?我真正想要的是这样的东西……
model.ImageField.path = generated_image_path
...当然这是行不通的。
是的,我已经看了这里的其他问题,比如这个问题,以及django doc on File
更新
经过进一步的测试,它只有在Windows Server上的Apache下运行时才会执行此行为。当在XP的“runserver”下运行时,它不会执行此行为。
我被难住了。
下面是在XP上成功运行的代码…
f = open(thumb_path, 'r')
model.thumbnail = File(f)
model.save()
我所做的是创建我自己的存储,只是不会将文件保存到磁盘:
from django.core.files.storage import FileSystemStorage
class CustomStorage(FileSystemStorage):
def _open(self, name, mode='rb'):
return File(open(self.path(name), mode))
def _save(self, name, content):
# here, you should implement how the file is to be saved
# like on other machines or something, and return the name of the file.
# In our case, we just return the name, and disable any kind of save
return name
def get_available_name(self, name):
return name
然后,在我的模型中,对于我的ImageField,我使用了新的自定义存储:
from custom_storage import CustomStorage
custom_store = CustomStorage()
class Image(models.Model):
thumb = models.ImageField(storage=custom_store, upload_to='/some/path')
下面是一个工作良好的方法,允许您将文件转换为某种格式(以避免“不能将模式P写入JPEG”错误):
import urllib2
from django.core.files.base import ContentFile
from PIL import Image
from StringIO import StringIO
def download_image(name, image, url):
input_file = StringIO(urllib2.urlopen(url).read())
output_file = StringIO()
img = Image.open(input_file)
if img.mode != "RGB":
img = img.convert("RGB")
img.save(output_file, "JPEG")
image.save(name+".jpg", ContentFile(output_file.getvalue()), save=False)
这里的image是django的ImageField还是your_model_instance.image
下面是一个用法示例:
p = ProfilePhoto(user=user)
download_image(str(user.id), p.image, image_url)
p.save()
希望这能有所帮助
我所做的是创建我自己的存储,只是不会将文件保存到磁盘:
from django.core.files.storage import FileSystemStorage
class CustomStorage(FileSystemStorage):
def _open(self, name, mode='rb'):
return File(open(self.path(name), mode))
def _save(self, name, content):
# here, you should implement how the file is to be saved
# like on other machines or something, and return the name of the file.
# In our case, we just return the name, and disable any kind of save
return name
def get_available_name(self, name):
return name
然后,在我的模型中,对于我的ImageField,我使用了新的自定义存储:
from custom_storage import CustomStorage
custom_store = CustomStorage()
class Image(models.Model):
thumb = models.ImageField(storage=custom_store, upload_to='/some/path')