Как исправить следующую ошибку Django: «Type: IOError» «Значение: [Errno 13] Отказано в доступе» - PullRequest
3 голосов
/ 08 ноября 2010

Я следую учебному пособию по Django, в котором вам необходимо создать несколько миниатюр изображений, как только изображение будет сохранено в админке.Я также использую модуль временного файла Python для сохранения временного имени файла.

Однако я продолжаю сталкиваться со следующей ошибкой:

"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" alt="" src="/media/%s" /></a>""" % (
                                                        (self.image.name, self.thumbnail.name))
thumbnail.allow_tags = Trueenter code here

ADMIN

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 есть гораздо более эффективные способы использования миниатюр изображений, однако я бы хотелХотелось бы знать, почему я продолжаю получать эту ошибку Разрешения, когда пиктограммы используются таким образом.

Вся помощь очень ценится.Благодарю.

Ответы [ 2 ]

6 голосов
/ 08 ноября 2010

Я думаю, что это связано с поведением NamedTemporaryFile в Windows.Из документации :

Эта функция работает точно так же, как и TemporaryFile (), за исключением того, что файл гарантированно имеет видимое имя в файловой системе (в Unix, каталогезапись не связана).Это имя может быть получено из имени члена объекта файла. Возможность использования имени для открытия файла во второй раз, когда именованный временный файл все еще открыт, зависит от платформы (его можно использовать в Unix; в Windows NT или более поздней версии ).

(выделено мной)

в строке:

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

save предположительно пытается открыть файл, чтобы он мог записать в него.

Из документов PIL вы можете передать save объект файла вместо имени файла, поэтому замена вышеуказанного на

im.save(tf2, "JPEG")

может помочь.

3 голосов
/ 26 октября 2012

Сожалею, но ответ 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...