我在尝试删除上传的图片时遇到了问题。
错误如下:
SuspiciousOperation: Attempted access to '/media/artists/12-stones/154339.jpg' denied.
在阅读之后看起来错误是由于它正在寻找错误位置的图像(注意第一个斜杠,/ media /在文件系统上不存在)
我的MEDIA_ROOT和MEDIA_URL是:
MEDIA_ROOT = '/home/tsoporan/site/media/'
MEDIA_URL = "/media/
我的模型upload_to参数传递了这个函数:
def get_artist_path(instance, filename):
return os.path.join('artists', slugify(instance.name), filename)
我的问题是:
1)如何解决此问题以备将来上传?
2)是否可以在不重新上载的情况下修复当前图像的路径?
此致 泰特斯
答案 0 :(得分:58)
当我在upload_to定义中添加一个前导斜杠时出现此错误。
BAD
pic = models.ImageField(upload_to="/uploads/product_images/")
GOOD
pic = models.ImageField(upload_to="uploads/product_images/")
答案 1 :(得分:30)
嗯,代码中的一点点问题表明,可能会有更深层次的错误信息在整个过程中被同质化。
在django / core / files / storage.py第210行(这是1.1.1)中我们有:
def path(self, name):
try:
path = safe_join(self.location, name)
except ValueError:
raise SuspiciousOperation("Attempted access to '%s' denied." % name)
return smart_str(os.path.normpath(path))
所以错误必须来自safe_join()。
在django / utils / _os.py中,我们有以下内容。请注意它在第三行到最后一行引发的ValueError:
===========================
def safe_join(base, *paths):
"""
Joins one or more path components to the base path component intelligently.
Returns a normalized, absolute version of the final path.
The final path must be located inside of the base path component (otherwise
a ValueError is raised).
"""
# We need to use normcase to ensure we don't false-negative on case
# insensitive operating systems (like Windows).
base = force_unicode(base)
paths = [force_unicode(p) for p in paths]
final_path = normcase(abspathu(join(base, *paths)))
base_path = normcase(abspathu(base))
base_path_len = len(base_path)
# Ensure final_path starts with base_path and that the next character after
# the final path is os.sep (or nothing, in which case final_path must be
# equal to base_path).
if not final_path.startswith(base_path) \
or final_path[base_path_len:base_path_len+1] not in ('', sep):
raise ValueError('the joined path is located outside of the base path'
' component')
return final_path
==================
嗯,“连接路径位于基本路径组件之外”。现在有一些对abspathu()的调用(在此例程之上定义,对于NT而言与其他操作系统不同)。 abspathu()通过修改当前工作目录os.cwdu()将所有非绝对路径转换为绝对路径。
问题:您的媒体目录中是否有符号链接(符号链接)?换句话说,它不是项目目录的直接子项?我不知道这是否是一个有效的问题,它只是突然出现了。
问题:哪些 传递给safe_join()的self.location
和name
的值?
Wild-ass-guess:self.location
是空的吗?
另一个疯狂猜测:MEDIA_ROOT是否以某种方式变为/media/
?
如果您安装了自己的Django副本(这并不难),尝试在这些例程中添加一些print语句,然后将其作为开发服务器运行。打印输出将转到控制台。
更新:嗯。你说“2)self.location和name的值是:/ home / tsoporan / site / media和/media/albums/anthem-for-the-underdog/30103635.jpg”
以下路径是否有意义?
"/home/tsoporan/site/media/media/albums/anthem-for-the-underdog"
请注意... / media / media / ...在那里。
另外,这是什么操作系统? Django rev?
答案 2 :(得分:12)
作为对其他人的说明,如果您要查找的静态文件资源中有一个双“//”,则可能会导致此问题。
{{ STATIC_URL }}/style.css # Causes the issue it should be
{{ STATIC_URL }}style.css
答案 3 :(得分:2)
现在我有大约4000张错误路径的图片...有没有办法以某种方式修改所有这些图像的路径?还是需要重新加载?
谢谢大家,为我的错误道歉。
答案 4 :(得分:2)
你真的应该问一个新问题。请尝试以下方法:
编写一个独立的django脚本,如下所示:
from django.core.management import setup_environ
from mysite import settings
setup_environ(settings)
from django.db import transaction
from app.models import Album # or whatever your model name is
for a in Album.objects.all():
# Do something to cleanup the filename.
# NOTE! This will not move the files, just change the value in the field.
a.filename = re.sub(r'^/media', '', a.filename)
a.save()
transaction.commit_unless_managed() # flush all changes
答案 5 :(得分:1)
如果你想使用其他位置,例如/ data / images / myfile /,你应该在django settings.py文件中将MEDIA_ROOT设置为/ data / images。
答案 6 :(得分:0)
我发现,通过使用愚蠢的print
语句,某些媒体文件在其网址路径中以/media
为前缀。虽然默认存储选项会处理此问题,但如果您使用S3BotoStorage
中的django-storages
,则会出现问题。
所以我通过覆盖_normalize_name
来修复它(由@ peter-rowell的回答引导):
class MediaStorage(FixedUrlBotoStorage):
location = settings.MEDIAFILES_LOCATION
# Overriding function because some media files are stored with '/media' prefixed (which causes problems)
def _normalize_name(self, name):
if name.startswith('/media'):
name = name.lstrip('/media')
return super(MediaStorage, self)._normalize_name(name)
答案 7 :(得分:0)
如果您的临时文件不属于MEDIA_ROOT文件夹,请使用Inputs display none
<div class="container">
<div class="row">
<div class="line"></div>
<div class="square"></div>
<div class="line"></div>
</div>
<div class="row inputs none">
<input/>
<input/>
<input/>
<input/>
</div>
</div>
Inputs visible
<div class="container">
<div class="row">
<div class="line"></div>
<div class="square"></div>
<div class="line"></div>
</div>
<div class="row inputs">
<input/>
<input/>
<input/>
<input/>
</div>
</div>
Inputs reduced font-size
<div class="container">
<div class="row">
<div class="line"></div>
<div class="square"></div>
<div class="line"></div>
</div>
<div class="row inputs reduce-font-size">
<input/>
<input/>
<input/>
<input/>
</div>
</div>
。这不会引发SimpleUploadedFile
错误:
SuspiciousOperation
如果您的临时文件已经是MEDIA_ROOT的一部分,请使用upload_file = SimpleUploadedFile(name=basename(out_file), content=open(out_file, 'rb').read())
object = YourModel.objects.create(file=upload_file)
。如果要将现有的Django文件链接到对象,这很有用。
File
答案 8 :(得分:0)
我以一种非常简单的方式解决了这个问题,转到此文件夹中的 utils.py
djk\lib\site-packages\django\core\files\utils.py
(djk 是 virtualenv 的名字)
在文件中添加 line 7
和 line 8
python 注释,就是这样,工作完成了。
答案 9 :(得分:-1)
此错误已在django 1.2.5中修复。见http://docs.djangoproject.com/en/dev/releases/1.2.5/#filefield-no-longer-deletes-files
答案 10 :(得分:-1)
我也遇到了这个错误。通过调试我发现引发了以下异常。
SuspiciousOperation(u"Attempted access to '2015-03-19-08:29:51-2-f8945842891244629dfd0c0af4c72a9c.pdf' denied.",)
BTW,我使用django-storages(v1.1.8)将我的媒体文件存储到S3上(使用S3boto后端)。我正在使用django 1.7.6。
但是,如果我切换到存储文件名与冒号(:)它似乎工作。我还没弄明白,根本原因是什么。只是发布这个以防这对其他人有帮助。显然,django或django-storages不喜欢带冒号的文件名。