我有以下情况。项目文件存储在〜/ 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
答案 0 :(得分:3)
这应该有效
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
答案 1 :(得分: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'
就足够了。
请注意,相对路径应存储在数据库中。