如何修复以下 Django 错误:“类型:IOError”“值:[Errno 13] 权限被拒绝”

Posted

技术标签:

【中文标题】如何修复以下 Django 错误:“类型:IOError”“值:[Errno 13] 权限被拒绝”【英文标题】:How do you fix the following Django Error: "Type: IOError" "Value: [Errno 13] Permission denied" 【发布时间】:2011-05-06 18:24:49 【问题描述】:

我正在关注 Django 教程,一旦图像保存在管理员中,您需要构建一些图像缩略图。我也在使用 Python 的 tempfile 模块来保存临时文件名。

但是我一直遇到以下错误:

"Type: IOError" "Value: [Errno 13] Permission denied: 'c:\\docume~1\\myname\\locals~1\\temp\\somefilename'"

这是我正在使用的代码

设置

MEDIA_ROOT = '/home/myname/projectname/media/'
MEDIA_URL = 'http://127.0.0.1:8000/media/'enter code here

models.py

from string import join
import os
from PIL import Image as PImage
from settings import MEDIA_ROOT
from os.path import join as pjoin
from tempfile import *
from string import join
from django.db import models
from django.contrib.auth.models import User
from django.contrib import admin
from django.core.files import File

class Image(models.Model):
    title = models.CharField(max_length=60, blank=True, null=True)
    image = models.FileField(upload_to="images/")
    thumbnail = models.ImageField(upload_to="images/", blank=True, null=True)
    tags = models.ManyToManyField(Tag, blank=True)
    albums = models.ManyToManyField(Album, blank=True)
    created = models.DateTimeField(auto_now_add=True)
    rating = models.IntegerField(default=50)
    width = models.IntegerField(blank=True, null=True)
    height = models.IntegerField(blank=True, null=True)
    user = models.ForeignKey(User, null=True, blank=True)
    thumbnail2 = models.ImageField(upload_to="images/", blank=True, null=True)

def save(self, *args, **kwargs):
    #Save image dimensions
    super(Image, self).save(*args, **kwargs)
    im = PImage.open(pjoin(MEDIA_ROOT, self.image.name))
    self.width, self.height = im.size

    # large thumbnail
    fn, ext = os.path.splitext(self.image.name)
    im.thumbnail((128,128), PImage.ANTIALIAS)
    thumb_fn = fn + "-thumb2" + ext
    tf2 = NamedTemporaryFile()
    im.save(tf2.name, "JPEG")
    self.thumbnail2.save(thumb_fn, File(open(tf2.name)), save=False)
    tf2.close()

    # small thumbnail
    im.thumbnail((40,40), PImage.ANTIALIAS)
    thumb_fn = fn + "-thumb" + ext
    tf = NamedTemporaryFile()
    im.save(tf.name, "JPEG")
    self.thumbnail.save(thumb_fn, File(open(tf.name)), save=False)
    tf.close()

    super(Image, self).save(*args, **kwargs)

def size(self):
    """Image size."""
    return "%s x %s" % (self.width, self.height)

def __unicode__(self):
    return self.image.name

def tags_(self):
    lst = [x[1] for x in self.tags.values_list()]
    return str(join(lst, ', '))

def albums_(self):
    lst = [x[1] for x in self.albums.values_list()]
    return str(join(lst, ', '))

def thumbnail_(self):
    return """<a href="/media/%s"><img border="0"  src="/media/%s" /></a>""" % (
                                                        (self.image.name, self.thumbnail.name))
thumbnail.allow_tags = Trueenter code here

管理员

class ImageAdmin(admin.ModelAdmin):
    # search_fields = ["title"]
    list_display = ["__unicode__", "title", "user", "rating", "size",  "tags_","albums_",
    "thumbnail", "created"]
list_filter = ["tags", "albums", "user"]

def save_model(self, request, obj, form, change):
    obj.user = request.user
    obj.save()

我知道在 Django 中使用图像缩略图有很多更有效的方法,但是我想知道为什么在以这种方式使用缩略图时我总是收到此权限错误。

非常感谢所有帮助。谢谢。

【问题讨论】:

【参考方案1】:

我认为这取决于NamedTemporaryFile 在 Windows 上的行为。来自the documentation:

这个函数的运行方式完全一样 TemporaryFile() 可以,除了 文件保证有一个可见的 文件系统中的名称(在 Unix 上, 目录条目未取消链接)。那 可以从名称中检索名称 文件对象的成员。 是否 名称可用于打开文件 第二次,而命名的临时 文件仍然打开,因人而异 平台(它可以在 Unix 上如此使用; 它不能在 Windows NT 或更高版本上)。

(强调我的)

在行中:

im.save(tf2.name, "JPEG")

save 可能会尝试打开文件以便写入。

从PIL docs 你可以传递save 一个文件对象而不是文件名,因此将上面的替换为

im.save(tf2, "JPEG")

可能有帮助。

【讨论】:

您的建议似乎不起作用,但您说的很对。我确信它不起作用,因为我在其他地方犯了一个错误,但你给我指出了正确的方向,我会修复它。谢谢。【参考方案2】:

我很遗憾,但 mikej 的回答根本不是解决方案,因为 PIL 支持这两个语法示例。可能,我从某个地方复制了同一个软件,它在我的 linux 机器上完美运行,但在 windows 7 上却不行。原因不在图像保存命令中,而是在下面的命令中。命令...

self.thumbnail.save(thumb_fn, File(open(tf.name)), save=False)

... 导致权限被拒绝错误,因为该文件仍处于打开状态并且至少不能在 Windows 上打开两次。可以模拟同样的错误

copyfile(tf2.name,"some-new-filepath")

适当的解决方法是

    创建关闭时不删除的临时文件 保存并关闭缩略图 手动删除临时文件

无论您如何保存缩略图,这都有效。

tf = NamedTemporaryFile(delete=False)
im.save(tf.name, "PNG")
#im.save(tf, "PNG")
tf.close()
copyfile(tf.name,"some-new-filepath")
os.remove(tf.name)

【讨论】:

以上是关于如何修复以下 Django 错误:“类型:IOError”“值:[Errno 13] 权限被拒绝”的主要内容,如果未能解决你的问题,请参考以下文章

如何修复 django 错误 MultiValueDictKeyError

如何修复 Django“NoReverseMatch”错误

如何修复 NoReverseMatch Django 错误?

如何修复 Django Rest API 错误?

如何修复 Reactjs、Django、Django Rest Frame 工作项目中的“net::ERR_CONNECTION_REFUSED 和错误:网络错误”错误

加载 Django runserver 提供的静态文件时如何修复 cors 错误