Django:collectstatic未收集静态文件
我找到一个GitHub项目,复制到本地后,运行collecstatic命令却没有把文件复制到staticfiles文件夹里。这是为什么呢?
如果我进行完整路径搜索:
python manage.py findstatic D:\web_proyects\imprenta_gallito\static\css\home.css
我收到一个错误:
django.core.exceptions.SuspiciousFileOperation: 这个路径 (D:\web_proyects\imprenta_gallito\static\css\home.css) 位于基本路径组件 (D:\virtual_envs\imprenta_gallito\Lib\site-packages\django\contrib\admin\static) 之外
settings.py:
import os
import os
import secrets
from pathlib import Path
import dj_database_url
from decouple import config
# SITE_ROOT = root()
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.environ.get(
"SECRET_KEY",
default=secrets.token_urlsafe(nbytes=64),
)
#DEBUG = config('DEBUG', default=False, cast=bool)
# The `DYNO` env var is set on Heroku CI, but it's not a real Heroku app, so we have to
# also explicitly exclude CI:
# https://devcenter.heroku.com/articles/heroku-ci#immutable-environment-variables
IS_HEROKU_APP = "DYNO" in os.environ and not "CI" in os.environ
# SECURITY WARNING: don't run with debug turned on in production!
if not IS_HEROKU_APP:
DEBUG = True
# On Heroku, it's safe to use a wildcard for `ALLOWED_HOSTS``, since the Heroku router performs
# validation of the Host header in the incoming HTTP request. On other platforms you may need
# to list the expected hostnames explicitly to prevent HTTP Host header attacks. See:
# https://docs.djangoproject.com/en/4.2/ref/settings/#std-setting-ALLOWED_HOSTS
if IS_HEROKU_APP:
ALLOWED_HOSTS = ["*"]
else:
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
# Use WhiteNoise's runserver implementation instead of the Django default, for dev-prod parity.
"whitenoise.runserver_nostatic",
# Uncomment this and the entry in `urls.py` if you wish to use the Django admin feature:
# https://docs.djangoproject.com/en/4.2/ref/contrib/admin/
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
'shop',
'search_app',
'cart',
'order',
'marketing',
'django.contrib.humanize',
'crispy_forms',
'crispy_bootstrap4'
]
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
# Django doesn't support serving static assets in a production-ready way, so we use the
# excellent WhiteNoise package to do so instead. The WhiteNoise middleware must be listed
# after Django's `SecurityMiddleware` so that security redirects are still performed.
# See: https://whitenoise.readthedocs.io
"whitenoise.middleware.WhiteNoiseMiddleware",
"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",
]
ROOT_URLCONF = 'imprenta_gallito.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates'),
os.path.join(BASE_DIR, 'shop', 'templates/'),
os.path.join(BASE_DIR, 'search_app', 'templates/'),
os.path.join(BASE_DIR, 'cart', 'templates/'),
os.path.join(BASE_DIR, 'order', 'templates/'), ]
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'shop.context_processor.menu_links',
'shop.context_processor.has_shop',
# 'cart.context_processor.current_time',
'cart.context_processor.cart_items_counter'
],
},
},
]
WSGI_APPLICATION = 'imprenta_gallito.wsgi.application'
# Database
# https://docs.djangoproject.com/en/2.1/ref/settings/#databases
# Database
# https://docs.djangoproject.com/en/4.2/ref/settings/#databases
if IS_HEROKU_APP:
# In production on Heroku the database configuration is derived from the `DATABASE_URL`
# environment variable by the dj-database-url package. `DATABASE_URL` will be set
# automatically by Heroku when a database addon is attached to your Heroku app. See:
# https://devcenter.heroku.com/articles/provisioning-heroku-postgres
# https://github.com/jazzband/dj-database-url
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': config('HEROKU_POSTGRESQL_NAME'),
'USER': config('HEROKU_POSTGRESQL_USER'),
'PASSWORD': config('HEROKU_POSTGRESQL_PASSWORD'),
'HOST': config('HEROKU_POSTGRESQL_HOST'),
'PORT': config('HEROKU_POSTGRESQL_PORT'),
}
}
else:
# When running locally in development or in CI, a sqlite database file will be used instead
# to simplify initial setup. Longer term it's recommended to use Postgres locally too.
SECURE_SSL_REDIRECT = False
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "db.sqlite3",
}
}
### HEROKU POSTGRESS ACCESS
# DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.postgresql',
# 'NAME': config('HEROKU_POSTGRESQL_NAME'),
# 'USER': config('HEROKU_POSTGRESQL_USER'),
# 'PASSWORD': config('HEROKU_POSTGRESQL_PASSWORD'),
# 'HOST': config('HEROKU_POSTGRESQL_HOST'),
# 'PORT': config('HEROKU_POSTGRESQL_PORT'),
# }
# }
####
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
LANGUAGE_CODE = 'es-PE'
TIME_ZONE = 'UTC'
USE_THOUSAND_SEPARATOR = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.1/howto/static-files/
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.2/howto/static-files/
STATIC_ROOT = BASE_DIR / "staticfiles"
STATIC_URL = "static/"
STORAGES = {
# Enable WhiteNoise's GZip and Brotli compression of static assets:
# https://whitenoise.readthedocs.io/en/latest/django.html#add-compression-and-caching-support
"default": {
"BACKEND": "django.core.files.storage.FileSystemStorage",
},
"staticfiles": {
"BACKEND": "whitenoise.storage.CompressedStaticFilesStorage",
},
}
# Don't store the original (un-hashed filename) version of static files, to reduce slug size:
# https://whitenoise.readthedocs.io/en/latest/django.html#WHITENOISE_KEEP_ONLY_HASHED_FILES
WHITENOISE_KEEP_ONLY_HASHED_FILES = True
# Default primary key field type
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
### Acaba Heroku Docs
# MEDIAFILES_LOCATION = 'media'
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'static', 'media')
CRISPY_TEMPLATE_PACK = 'bootstrap4'
### AMAZON ###
AWS_S3_OBJECT_PARAMETERS = {
'Expires': 'Thu, 31 Dec 2099 20:00:00 GMT',
'CacheControl': 'max-age=94608000',
}
# AWS_STORAGE_BUCKET_NAME = ''#os.environ['AWS_STORAGE_BUCKET_NAME']
# AWS_S3_REGION_NAME = 'os'#os.environ['AWS_S3_REGION_NAME']
# Tell django-storages the domain to use to refer to static files.
# AWS_S3_CUSTOM_DOMAIN = '%s.s3.amazonaws.com' % AWS_STORAGE_BUCKET_NAME
# AWS_ACCESS_KEY_ID = os.environ['AWS_ACCESS_KEY_ID']
# AWS_SECRET_ACCESS_KEY = os.environ['AWS_SECRET_ACCESS_KEY']
### MAILGUN - EMAIL MESSAGE SETTINGS ###
EMAIL_HOST = os.environ['EMAIL_HOST']
EMAIL_PORT = os.environ['EMAIL_PORT']
EMAIL_USE_TLS = config('EMAIL_USE_TLS', default=True, cast=bool)
EMAIL_HOST_USER = os.environ['EMAIL_HOST_USER']
EMAIL_HOST_PASSWORD = os.environ['EMAIL_HOST_PASSWORD']
### manage.py check --deploy
SECURE_BROWSER_XSS_FILTER = True
X_FRAME_OPTIONS = 'DENY'
### Promociones ###
PACKS3X2 = os.environ['PACKS3X2']
CRISPY_TEMPLATE_PACK = 'bootstrap4'
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'verbose': {
'format': ('%(asctime)s [%(process)d] [%(levelname)s] ' +
'pathname=%(pathname)s lineno=%(lineno)s ' +
'funcname=%(funcName)s %(message)s'),
'datefmt': '%Y-%m-%d %H:%M:%S'
},
'simple': {
'format': '%(levelname)s %(message)s'
}
},
'handlers': {
'null': {
'level': 'DEBUG',
'class': 'logging.NullHandler',
},
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'verbose'
}
},
'loggers': {
'testlogger': {
'handlers': ['console'],
'level': 'INFO',
}
}
}
DEBUG_PROPAGATE_EXCEPTIONS = True
COMPRESS_ENABLED = os.environ.get('COMPRESS_ENABLED', False)
2 个回答
0
你应该使用相对路径。
python manage.py findstatic 是一个调试工具;它会告诉你在某个路径下具体会收集到哪个静态文件。
可以试试下面的方式。
python manage.py findstatic static/css/home.css
#Or
python manage.py findstatic css/home.css
#Or
python manage.py findstatic imprenta_gallito/static/css/home.css
0
这个问题的解决方法是把:
STATIC_ROOT = BASE_DIR / "staticfiles"
改成:
STATIC_ROOT = os.path.join(BASE_DIR, "static")