Django - 来自图像的 SuspiciousFileOperation 添加到本地开发环境
Django - SuspiciousFileOperation from image add on local development environment
过去几个月我一直在开发基于 Django 的个人照片网站,并使用 AWS 成功部署了它。到目前为止,我已经在 Windows 10 桌面上完成了所有开发工作。我最近买了一台新的 Windows 10 笔记本电脑,但在设置开发环境时遇到了困难。我将我的 Github 存储库克隆到我的笔记本电脑上,并成功地将网站 运行 本地化。但是,当我转到管理页面上传照片时,每次我都会收到 SuspiciousFileOperation 异常。加入的路径位于基本路径组件之外。当 运行ning collectstatic 时,我也遇到了这个错误。这些设置与我的桌面设置相同,除非我忽略了一个正盯着我看的问题。
我认为这可能与我设置 virtualenv 的方式或我的 MEDIA 变量的设置方式有关,尽管它们与我桌面上的工作方式相同。我已经通读了 Django 文档,但没有找到任何确定的内容。或者也许有人可以解释更多关于设置 virtualenv 的信息? Django/Python 是否需要我错过在笔记本电脑上设置的某些权限来移动文件?
下面是完整的错误和相关的代码片段。
堆栈跟踪:
Environment:
Request Method: POST
Request URL: http://127.0.0.1:8000/admin/PortfolioApp/image/add/
Django Version: 2.1.4
Python Version: 3.7.1
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'PortfolioApp.apps.PortfolioappConfig',
'storages']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Traceback:
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\core\handlers\exception.py" in inner
34. response = get_response(request)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\core\handlers\base.py" in _get_response
126. response = self.process_exception_by_middleware(e, request)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\core\handlers\base.py" in _get_response
124. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\contrib\admin\options.py" in wrapper
604. return self.admin_site.admin_view(view)(*args, **kwargs)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\utils\decorators.py" in _wrapped_view
142. response = view_func(request, *args, **kwargs)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\views\decorators\cache.py" in _wrapped_view_func
44. response = view_func(request, *args, **kwargs)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\contrib\admin\sites.py" in inner
223. return view(request, *args, **kwargs)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\contrib\admin\options.py" in add_view
1637. return self.changeform_view(request, None, form_url, extra_context)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\utils\decorators.py" in _wrapper
45. return bound_method(*args, **kwargs)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\utils\decorators.py" in _wrapped_view
142. response = view_func(request, *args, **kwargs)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\contrib\admin\options.py" in changeform_view
1525. return self._changeform_view(request, object_id, form_url, extra_context)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\contrib\admin\options.py" in _changeform_view
1564. self.save_model(request, new_object, form, not add)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\contrib\admin\options.py" in save_model
1091. obj.save()
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\db\models\base.py" in save
718. force_update=force_update, update_fields=update_fields)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\db\models\base.py" in save_base
748. updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\db\models\base.py" in _save_table
831. result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\db\models\base.py" in _do_insert
869. using=using, raw=raw)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\db\models\manager.py" in manager_method
82. return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\db\models\query.py" in _insert
1136. return query.get_compiler(using=using).execute_sql(return_id)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\db\models\sql\compiler.py" in execute_sql
1288. for sql, params in self.as_sql():
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\db\models\sql\compiler.py" in as_sql
1241. for obj in self.query.objs
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\db\models\sql\compiler.py" in <listcomp>
1241. for obj in self.query.objs
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\db\models\sql\compiler.py" in <listcomp>
1240. [self.prepare_value(field, self.pre_save_val(field, obj)) for field in fields]
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\db\models\sql\compiler.py" in pre_save_val
1192. return field.pre_save(obj, add=True)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\db\models\fields\files.py" in pre_save
288. file.save(file.name, file.file, save=False)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\db\models\fields\files.py" in save
87. self.name = self.storage.save(name, content, max_length=self.field.max_length)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\core\files\storage.py" in save
48. name = self.get_available_name(name, max_length=max_length)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\core\files\storage.py" in get_available_name
72. while self.exists(name) or (max_length and len(name) > max_length):
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\core\files\storage.py" in exists
308. return os.path.exists(self.path(name))
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\core\files\storage.py" in path
321. return safe_join(self.location, name)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\utils\_os.py" in safe_join
49. 'component ({})'.format(final_path, base_path))
Exception Type: SuspiciousFileOperation at /admin/PortfolioApp/image/add/
Exception Value: The joined path (C:\Users\Bryan\Documents\GitHub\Portfolio\media\pictures\VeselkaNYC-BJM.jpg) is located outside of the base path component (C:\Users\Bryan\Documents\GitHub\Portfolio\media\)
models.py
class Image(models.Model):
...
picture = models.ImageField(upload_to='pictures/', height_field='height', width_field='width', null=True)
...
settings.py
...
STATIC_URL = '/static/'
STATIC_ROOT = 'static/'
MEDIA_URL = '/media/'
MEDIA_ROOT = 'media/'
...
urls.py
...
if settings.DEBUG:
# Use static() to add url mapping to serve static files during development (only)
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
我已经包含了我认为相关的代码片段,但请询问您是否需要更多帮助我。非常感谢任何帮助。
编辑:
感谢 Giancarlo 的建议,重新定义了我的 STATIC_ROOT 和 MEDIA_ROOT 如下:
STATIC_ROOT = os.join.path(BASE_DIR, "static")
MEDIA_ROOT = os.join.path(BASE_DIR, "media")
我认为我桌面上的设置之所以有效,是因为 .pyc 缓存文件包含在开发过程中保存的正确设置。这是我能想到的最好的。
将您的 STATIC_ROOT 和 MEDIA_ROOT 更改为
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
MEDIA_ROOT = os.path.join(BASE_DIR, "media/")
因为 Windows 可能正在 C:\media
或 C:\static
搜索
编辑:我认为 BASE_DIR 是在 settings.py 中预定义的,但这里是如果它丢失了
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
并且可以肯定的是,在 upload_to
后面添加一个斜线
upload_to='pictures/'
过去几个月我一直在开发基于 Django 的个人照片网站,并使用 AWS 成功部署了它。到目前为止,我已经在 Windows 10 桌面上完成了所有开发工作。我最近买了一台新的 Windows 10 笔记本电脑,但在设置开发环境时遇到了困难。我将我的 Github 存储库克隆到我的笔记本电脑上,并成功地将网站 运行 本地化。但是,当我转到管理页面上传照片时,每次我都会收到 SuspiciousFileOperation 异常。加入的路径位于基本路径组件之外。当 运行ning collectstatic 时,我也遇到了这个错误。这些设置与我的桌面设置相同,除非我忽略了一个正盯着我看的问题。
我认为这可能与我设置 virtualenv 的方式或我的 MEDIA 变量的设置方式有关,尽管它们与我桌面上的工作方式相同。我已经通读了 Django 文档,但没有找到任何确定的内容。或者也许有人可以解释更多关于设置 virtualenv 的信息? Django/Python 是否需要我错过在笔记本电脑上设置的某些权限来移动文件?
下面是完整的错误和相关的代码片段。
堆栈跟踪:
Environment:
Request Method: POST
Request URL: http://127.0.0.1:8000/admin/PortfolioApp/image/add/
Django Version: 2.1.4
Python Version: 3.7.1
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'PortfolioApp.apps.PortfolioappConfig',
'storages']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Traceback:
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\core\handlers\exception.py" in inner
34. response = get_response(request)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\core\handlers\base.py" in _get_response
126. response = self.process_exception_by_middleware(e, request)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\core\handlers\base.py" in _get_response
124. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\contrib\admin\options.py" in wrapper
604. return self.admin_site.admin_view(view)(*args, **kwargs)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\utils\decorators.py" in _wrapped_view
142. response = view_func(request, *args, **kwargs)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\views\decorators\cache.py" in _wrapped_view_func
44. response = view_func(request, *args, **kwargs)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\contrib\admin\sites.py" in inner
223. return view(request, *args, **kwargs)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\contrib\admin\options.py" in add_view
1637. return self.changeform_view(request, None, form_url, extra_context)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\utils\decorators.py" in _wrapper
45. return bound_method(*args, **kwargs)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\utils\decorators.py" in _wrapped_view
142. response = view_func(request, *args, **kwargs)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\contrib\admin\options.py" in changeform_view
1525. return self._changeform_view(request, object_id, form_url, extra_context)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\contrib\admin\options.py" in _changeform_view
1564. self.save_model(request, new_object, form, not add)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\contrib\admin\options.py" in save_model
1091. obj.save()
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\db\models\base.py" in save
718. force_update=force_update, update_fields=update_fields)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\db\models\base.py" in save_base
748. updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\db\models\base.py" in _save_table
831. result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\db\models\base.py" in _do_insert
869. using=using, raw=raw)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\db\models\manager.py" in manager_method
82. return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\db\models\query.py" in _insert
1136. return query.get_compiler(using=using).execute_sql(return_id)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\db\models\sql\compiler.py" in execute_sql
1288. for sql, params in self.as_sql():
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\db\models\sql\compiler.py" in as_sql
1241. for obj in self.query.objs
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\db\models\sql\compiler.py" in <listcomp>
1241. for obj in self.query.objs
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\db\models\sql\compiler.py" in <listcomp>
1240. [self.prepare_value(field, self.pre_save_val(field, obj)) for field in fields]
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\db\models\sql\compiler.py" in pre_save_val
1192. return field.pre_save(obj, add=True)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\db\models\fields\files.py" in pre_save
288. file.save(file.name, file.file, save=False)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\db\models\fields\files.py" in save
87. self.name = self.storage.save(name, content, max_length=self.field.max_length)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\core\files\storage.py" in save
48. name = self.get_available_name(name, max_length=max_length)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\core\files\storage.py" in get_available_name
72. while self.exists(name) or (max_length and len(name) > max_length):
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\core\files\storage.py" in exists
308. return os.path.exists(self.path(name))
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\core\files\storage.py" in path
321. return safe_join(self.location, name)
File "C:\Users\Bryan\Envs\dj\lib\site-packages\django\utils\_os.py" in safe_join
49. 'component ({})'.format(final_path, base_path))
Exception Type: SuspiciousFileOperation at /admin/PortfolioApp/image/add/
Exception Value: The joined path (C:\Users\Bryan\Documents\GitHub\Portfolio\media\pictures\VeselkaNYC-BJM.jpg) is located outside of the base path component (C:\Users\Bryan\Documents\GitHub\Portfolio\media\)
models.py
class Image(models.Model):
...
picture = models.ImageField(upload_to='pictures/', height_field='height', width_field='width', null=True)
...
settings.py
...
STATIC_URL = '/static/'
STATIC_ROOT = 'static/'
MEDIA_URL = '/media/'
MEDIA_ROOT = 'media/'
...
urls.py
...
if settings.DEBUG:
# Use static() to add url mapping to serve static files during development (only)
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
我已经包含了我认为相关的代码片段,但请询问您是否需要更多帮助我。非常感谢任何帮助。
编辑: 感谢 Giancarlo 的建议,重新定义了我的 STATIC_ROOT 和 MEDIA_ROOT 如下:
STATIC_ROOT = os.join.path(BASE_DIR, "static")
MEDIA_ROOT = os.join.path(BASE_DIR, "media")
我认为我桌面上的设置之所以有效,是因为 .pyc 缓存文件包含在开发过程中保存的正确设置。这是我能想到的最好的。
将您的 STATIC_ROOT 和 MEDIA_ROOT 更改为
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
MEDIA_ROOT = os.path.join(BASE_DIR, "media/")
因为 Windows 可能正在 C:\media
或 C:\static
编辑:我认为 BASE_DIR 是在 settings.py 中预定义的,但这里是如果它丢失了
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
并且可以肯定的是,在 upload_to
后面添加一个斜线upload_to='pictures/'