【问题标题】:Set new `path` value for ImageField为 ImageField 设置新的 `path` 值
【发布时间】:2012-08-21 21:25:54
【问题描述】:

我有以下情况。项目文件存储在 ~/django-apps/app-old/app.由于某些原因,我将文件移动到 ~/django-apps/app 。应用程序有一些图像,使用 ImageField 存储。在数据库中图像的路径如下:

~/django-apps/app-old/app/media/images/blabla.jpeg

所以,我需要在数据库中修复这条路径,使其看起来像这样:

~django-apps/app/media/images/blabla.jpeg

我尝试为此编写管理命令:

from django.core.management.base import BaseCommand, CommandError
from books.models import Book
import string

class Command(BaseCommand):
    help = ''

    def handle(self, *args, **options):
        books = Book.objects.all()
        total = len(books)
        curr = 1

        for book in books:
            print "%d/%d" % (curr, total)
            if book.cover_url != "":
                book.cover_url.path = string.replace(book.cover_url.path, "app-old/", "")
                book.save()
            curr+=1

通过使用此命令,我收到以下错误:

Traceback (most recent call last):
  File "manage.py", line 11, in <module>
    execute_manager(settings)
  File "/usr/local/lib/python2.6/dist-packages/django/core/management/__init__.py", line 438, in execute_manager
    utility.execute()
  File "/usr/local/lib/python2.6/dist-packages/django/core/management/__init__.py", line 379, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python2.6/dist-packages/django/core/management/base.py", line 191, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/usr/local/lib/python2.6/dist-packages/django/core/management/base.py", line 220, in execute
    output = self.handle(*args, **options)
  File "/var/www/dizpers/data/django-apps/app/books/management/commands/fix-covers-path.py", line 23, in handle
    book.cover_url.path = string.replace(book.cover_url.path, "bparser-old/", "")
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/fields/files.py", line 65, in _get_path
    return self.storage.path(self.name)
  File "/usr/local/lib/python2.6/dist-packages/django/core/files/storage.py", line 234, in path
    raise SuspiciousOperation("Attempted access to '%s' denied." % name)
django.core.exceptions.SuspiciousOperation: Attempted access to '/var/www/dizpers/data/django-apps/app-old/app/media/covers/a3d9545d3a17bb68a91749019c95357d.jpeg' denied.

为什么我会收到此错误消息?如何修复图像的路径?

UPD1

我的模型包含这样的 ImageField:

cover_url = models.ImageField(upload_to=os.path.join(MEDIA_ROOT, "covers"), null=True, default=None)

UPD2

Path property is readonly

【问题讨论】:

    标签: python django django-1.3


    【解决方案1】:

    您收到此消息是因为默认文件系统存储出于安全原因阻止使用绝对路径。

    如果你真的想使用绝对路径

    django-documents 出于安全原因强制使用绝对路径,方法如下:

    from django.core.files.storage import FileSystemStorage
    
    
    fs = FileSystemStorage(location=UPLOAD_TO)
    
    
    class Document(models.Model):
        file = models.FileField(storage=fs, upload_to=UPLOAD_TO)
    

    其中 UPLOAD_TO 可以是绝对路径。

    -- 回复问题更新--

    如果您不需要这样的安全性

    那么你应该阅读documentation on FileField:

    FileField.upload_to 将附加到您的 MEDIA_ROOT 设置以确定 url 属性的值的本地文件系统路径。

    在你的情况下,upload_to='covers' 就足够了。

    请注意,相对路径应存储在数据库中。

    【讨论】:

    • 我添加了问题更新 - 我的 ImageField 的描述。我在那里使用绝对路径?我不应该这样做吗?
    • 是不是ImageField没关系,因为ImageField继承自FileField :) 试试看就知道了;)
    • 那么,我需要修改我的模型吗?是的,你说得对,ImageField 从 FileField 中消失。我在这个字段中谈论绝对路径而不是相对路径 - 也许我应该在 ImageField 中使用相对路径,也许它会解决问题?
    • 我有一个关于您更新答案的问题。当简单地修改模型以使用相对路径(第二种方式“如果你不需要这种安全性”)时,我会面临什么样的安全问题?
    • 如果 MEDIA_ROOT 是公开的,则上传到 MEDIA_ROOT 的文件是公开的。这适用于头像等,但不适用于机密文件。
    【解决方案2】:

    这应该可以工作

    for book in books:
            print "%d/%d" % (curr, total)
            if book.cover_url != "":
                new_path = string.replace(book.cover_url.path, "app-old/", "")
                book.cover_url = new_path
                book.save()
            curr+=1
    

    【讨论】:

    • 我的问题中的错误。 SuspiciousOperation: Attempted access to '/var/www/dizpers/data/django-apps/app-old/app/media/covers/a3d9545d3a17bb68a91749019c95357d.jpeg' denied.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-23
    • 2012-03-13
    • 1970-01-01
    • 1970-01-01
    • 2012-07-12
    • 2015-11-03
    相关资源
    最近更新 更多