【问题标题】:Django - SuspiciousFileOperation from image add on local development environmentDjango - 来自图像的 SuspiciousFileOperation 添加到本地开发环境
【发布时间】:2018-12-19 17:55:46
【问题描述】:

过去几个月我一直在开发一个基于 Django 的个人照片网站,并成功地将其部署到 AWS。到目前为止,我已经在我的 Windows 10 桌面上完成了所有的开发。我最近买了一台新的 Windows 10 笔记本电脑,并且在上面设置开发环境时遇到了困难。我将我的 Github 存储库克隆到我的笔记本电脑上,并成功地让该站点在本地运行。但是,当我去管理页面上传照片时,每次我得到一个 SuspiciousFileOperation 异常。连接路径位于基本路径组件之外。运行 collectstatic 时我也遇到了这个错误。这些设置与我的桌面设置相同,除非我忽略了一个正盯着我的问题。

我认为这可能与我设置 virtualenv 的方式或我的 MEDIA 变量的设置方式有关,尽管它们与我桌面上的工作方式相同。我已经阅读了 Django 文档,但没有找到任何确定的东西。或者也许有人可以解释一下关于设置 virtualenv 的更多信息? Django/Python 是否需要我错过在笔记本电脑上设置的某些权限才能移动文件?

下面是完整的错误和相关代码sn-ps。

堆栈跟踪:

    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)

我已经包含了我认为相关的代码 sn-ps 但请询问您是否需要更多来帮助我。非常感谢任何帮助。

编辑: 感谢 Giancarlo 的建议,重新定义了我的 STATIC_ROOT 和 MEDIA_ROOT 如下:

    STATIC_ROOT = os.join.path(BASE_DIR, "static")
    MEDIA_ROOT = os.join.path(BASE_DIR, "media")

我认为我桌面上的设置可以正常工作,因为 .pyc 缓存文件包含在开发过程中保存的正确设置。这是我能想到的最好的。

【问题讨论】:

标签: python django django-settings


【解决方案1】:

将您的 STATIC_ROOT 和 MEDIA_ROOT 更改为

STATIC_ROOT = os.path.join(BASE_DIR, "static/")
MEDIA_ROOT = os.path.join(BASE_DIR, "media/")

因为可能 Windows 正在搜索 C:\mediaC:\static

编辑:我认为 BASE_DIR 是在 settings.py 中预定义的,但如果它丢失了,这里是

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

并且可以肯定的是,在 upload_to 中添加一个斜杠

upload_to='pictures/'

【讨论】:

  • 我尝试按照您的建议重新定义 STATIC_ROOT 和 MEDIA_ROOT 但没有运气。 BASE_DIR 如您所述定义。当我上传问题时,我注意到我错过了斜杠,但修复它并没有帮助。仍然得到异常。回溯看起来图像正在尝试上传到正确的文件夹。但是将静态或媒体路径与基本路径连接的方式有问题。
  • 我现在可以正常工作了。我的桌面设置上必须有一个具有正确路径的缓存文件才能使其正常工作。我使用了您对 STATIC_ROOT 和 MEDIA_ROOT 的定义,但没有尾部斜杠。将您的答案标记为正确,因为它使我走上了正确的道路。谢谢!
猜你喜欢
  • 1970-01-01
  • 2018-09-11
  • 1970-01-01
  • 2017-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多