好吧,我几乎什么都试过了,但我不能让它工作。

我有一个带有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()

当前回答

我用uuid在django 2 python 3中保存图像,因为这是django如何做的:

import uuid   
from django.core.files import File 
import urllib

httpUrl = "https://miimgeurl/image.jpg"
result = urllib.request.urlretrieve(httpUrl)            
mymodel.imagefield.save(os.path.basename(str(uuid.uuid4())+".jpg"),File(open(result[0], 'rb')))
mymodel.save()

其他回答

就说一点。答案是可行的,但是,如果你在windows上工作,你可能想用'rb'打开()文件。是这样的:

class CachedImage(models.Model):
    url = models.CharField(max_length=255, unique=True)
    photo = models.ImageField(upload_to=photo_path, blank=True)

    def cache(self):
        """Store image locally if we have a URL"""

        if self.url and not self.photo:
            result = urllib.urlretrieve(self.url)
            self.photo.save(
                    os.path.basename(self.url),
                    File(open(result[0], 'rb'))
                    )
            self.save()

否则文件将在第一个0x1A字节处被截断。

工作! 您可以使用FileSystemStorage保存映像。 检查下面的示例

def upload_pic(request):
if request.method == 'POST' and request.FILES['photo']:
    photo = request.FILES['photo']
    name = request.FILES['photo'].name
    fs = FileSystemStorage()
##### you can update file saving location too by adding line below #####
    fs.base_location = fs.base_location+'/company_coverphotos'
##################
    filename = fs.save(name, photo)
    uploaded_file_url = fs.url(filename)+'/company_coverphotos'
    Profile.objects.filter(user=request.user).update(photo=photo)

在Django 3中, 用这样一个模型:

class Item(models.Model):
   name = models.CharField(max_length=255, unique=True)
   photo= models.ImageField(upload_to='image_folder/', blank=True)

如果图片已经上传,我们可以直接做:

Item.objects.filter(...).update(photo='image_folder/sample_photo.png')

or

my_item = Item.objects.get(id=5)
my_item.photo='image_folder/sample_photo.png'
my_item.save()
class Pin(models.Model):
    """Pin Class"""
    image_link = models.CharField(max_length=255, null=True, blank=True)
    image = models.ImageField(upload_to='images/', blank=True)
    title = models.CharField(max_length=255, null=True, blank=True)
    source_name = models.CharField(max_length=255, null=True, blank=True)
    source_link = models.CharField(max_length=255, null=True, blank=True)
    description = models.TextField(null=True, blank=True)
    tags = models.ForeignKey(Tag, blank=True, null=True)

    def __unicode__(self):
        """Unicode class."""
        return unicode(self.image_link)

    def save(self, *args, **kwargs):
        """Store image locally if we have a URL"""
        if self.image_link and not self.image:
            result = urllib.urlretrieve(self.image_link)
            self.image.save(os.path.basename(self.image_link), File(open(result[0], 'r')))
            self.save()
            super(Pin, self).save()

如果你使用admin.py你可以解决这个问题(django上的doc):

def save_model(self, request, obj, form, change):
    obj.image_data = bytes(obj.image_name.read())
    super().save_model(request, obj, form, change)

models.py:

image_name = models.ImageField()
image_data = models.BinaryField()