0

使用手动文件上传时,我是否需要先将文件放在最终位置,然后再将其保存到模型中?或者,模型是否会在某个时候移动文件?如果我确实需要自己放置它,为什么我需要upload_to模型字段中的参数?这似乎我必须与upload_to参数和我用来复制它的逻辑保持一致。

我想我只是很困惑。有人可以帮我做到这一点吗?

我的表单从网上获取图片网址:

class ProductForm(ModelForm):    
    main_image_url = forms.URLField()
    # etc...

我的视图检索它,检查它,并制作一个缩略图:

main_img_temp = NamedTemporaryFile(delete=True)
main_img_temp.write(urllib2.urlopen(main_image_url).read())
main_img_temp.flush()

img_type = imghdr.what(main_img_temp.name)
if not img_type:
    errors = form._errors.setdefault("main_image_url", ErrorList())
    errors.append(u"Url does not point to a valid image")
    return render_to_response('add_image.html', {'form':form}, context_instance=RequestContext(request))

# build a temporary path name
filename = str(uuid.uuid4())
dirname  = os.path.dirname(main_img_temp.name)
full_size_tmp  = os.path.join(dirname, filename+'_full.jpg')
thumb_size_tmp = os.path.join(dirname, filename+'_thumb.jpg')

shutil.copy2(main_img_temp.name, full_size_tmp)
shutil.copy2(main_img_temp.name, thumb_size_tmp)

# build full size and thumbnail
im = Image.open(full_size_tmp)
im.thumbnail(full_image_size, Image.ANTIALIAS)
im.save(full_size_tmp, "JPEG")

im = Image.open(thumb_size_tmp)
im.thumbnail(thumb_image_size, Image.ANTIALIAS)
im.save(thumb_size_tmp, "JPEG")

# close to delete the original temp file
main_img_tmp.close()


### HERE'S WHERE I'M STUCK. This doesn't move the file... ####
main_image = UploadedImage(image=full_size_tmp, thumbnail=thumb_size_tmp)
main_image.save()

在我的模型中,我有一个 UploadedImage 模型,它具有以下基本字段:

class UploadedImage(models.Model):
    image = models.ImageField(upload_to='uploads/images/%Y/%m/%d/full')
    thumbnail = models.ImageField(upload_to='uploads/images/%Y/%m/%d/thumb/')
4

2 回答 2

0

通常,当您保存模型时,它会将文件写入指向upload_to. 它自行处理,因此您无需手动操作。

在这里,您正在将文件写入临时文件,之后移动它以及许多可以自动完成的事情。检查这个问题的答案,他还urllib用来获取图像并将其保存到数据库中。

请注意,您可以在内存中传递一个缓冲区来创建一个FileFieldImageField适合为缩略图执行逻辑的。您也可以考虑将django-thumbnails其用于此目的。这是一个很好的图书馆。

希望这可以帮助!

于 2013-05-23T17:59:35.710 回答
0

回答了我自己的问题...

当我将路径传递给模型中的 ImageField 时,我只是给它一个路径。我现在看到,要调用 Django 内置的所有存储处理,你必须给它一个File对象。这足以让它复制到upload_to路径:

from django.core.files import File

main_image = UploadedImage(image=File(open(full_size_tmp)), thumbnail=File(open(thumb_size_tmp)), creator=request.user)
main_image.save()
于 2013-05-23T18:26:43.497 回答