Последние несколько месяцев я работаю над личным фото-сайтом, созданным на Django, и успешно развернул его с помощью AWS.До сих пор я сделал все свои разработки на моем рабочем столе Windows 10.Недавно я приобрел новый ноутбук с Windows 10 и застрял, настраивая на нем среду разработки.Я клонировал репозиторий Github на свой ноутбук и успешно заставил сайт работать локально.Однако, когда я захожу на страницу администратора, чтобы загрузить фотографию, и каждый раз я получаю исключение SuspiciousFileOperation.Присоединенный путь расположен вне компонента базового пути.Я также получил эту ошибку при запуске 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)
Я включил, как мне кажется, соответствующие фрагменты кода, но, пожалуйста, спросите, нужно ли вам больше, чтобы помочь мне.Любая помощь очень ценится.
РЕДАКТИРОВАТЬ: Благодаря предложениям Джанкарло, переопределил мои STATIC_ROOT и MEDIA_ROOT следующим образом:
STATIC_ROOT = os.join.path(BASE_DIR, "static")
MEDIA_ROOT = os.join.path(BASE_DIR, "media")
Я думаю, что настройки на моем рабочем столе работают из-за кэша .pycфайл, содержащий правильные настройки, которые были сохранены в процессе разработки.Это лучшее, что я могу придумать.