在 Django 生产中找不到静态文件
Static file not found in Django production
我正在尝试使用 Ubuntu 和 apache 网络服务器部署我的 Django 项目。当我将我的项目转移到 Ubuntu 网络服务器并在开发中对其进行测试时,一切正常。然而,当更改为生产时,我遇到了找不到文件的问题,我怀疑这个问题与我的 setings.py 有关,但我无法进一步解决它。我在访问我的网站时在生产中看到的错误是:
Environment:
Request Method: GET
Request URL: http://139.162.163.35/
Django Version: 3.1.3
Python Version: 3.8.5
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles']
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 (most recent call last):
File "/home/jianwu/HD_website/website/env/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/home/jianwu/HD_website/website/env/lib/python3.8/site-packages/django/core/handlers/base.py", line 179, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/jianwu/HD_website/website/env/lib/python3.8/site-packages/django/views/generic/base.py", line 63, in view
self = cls(**initkwargs)
File "/home/jianwu/HD_website/website/index/views.py", line 57, in __init__
self.ContextObject.importTextFile('static/mainAboutUs.txt')
File "/home/jianwu/HD_website/website/index/views.py", line 50, in importTextFile
with open(filePath,'r') as fid:
Exception Type: FileNotFoundError at /
Exception Value: [Errno 2] No such file or directory: 'static/mainAboutUs.txt'
在我的 Meta 中我有
CONTEXT_DOCUMENT_ROOT
'/var/www/html'
CONTEXT_PREFIX
''
CSRF_COOKIE
'jF3vdEgpyhbKxavRw3pEWzRdIjc4lvw0MsV4lpBLdYXPqcGcIVyH02kEuBeGSXlh'
DOCUMENT_ROOT
'/var/www/html'
GATEWAY_INTERFACE
'CGI/1.1'
HTTP_ACCEPT
'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9'
HTTP_ACCEPT_ENCODING
'gzip, deflate'
HTTP_ACCEPT_LANGUAGE
'da-DK,da;q=0.9,en-US;q=0.8,en;q=0.7,bg;q=0.6,zh-CN;q=0.5,zh;q=0.4'
HTTP_CONNECTION
'keep-alive'
HTTP_COOKIE
'csrftoken=jF3vdEgpyhbKxavRw3pEWzRdIjc4lvw0MsV4lpBLdYXPqcGcIVyH02kEuBeGSXlh'
HTTP_HOST
'139.162.163.35'
HTTP_PURPOSE
'prefetch'
HTTP_UPGRADE_INSECURE_REQUESTS
'1'
HTTP_USER_AGENT
('Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_2) AppleWebKit/537.36 (KHTML, '
'like Gecko) Chrome/88.0.4324.192 Safari/537.36')
PATH_INFO
'/'
PATH_TRANSLATED
'/home/jianwu/HD_website/website/website/wsgi.py/'
QUERY_STRING
''
REMOTE_ADDR
'94.147.65.45'
REMOTE_PORT
'58717'
REQUEST_METHOD
'GET'
REQUEST_SCHEME
'http'
REQUEST_URI
'/'
SCRIPT_FILENAME
'/home/jianwu/HD_website/website/website/wsgi.py'
SCRIPT_NAME
''
SERVER_ADDR
'139.162.163.35'
SERVER_ADMIN
'webmaster@localhost'
SERVER_NAME
'139.162.163.35'
SERVER_PORT
'80'
SERVER_PROTOCOL
'HTTP/1.1'
SERVER_SIGNATURE
'********************'
SERVER_SOFTWARE
'Apache/2.4.41 (Ubuntu)'
apache.version
(2, 4, 41)
mod_wsgi.application_group
'139.162.163.35|'
mod_wsgi.callable_object
'application'
mod_wsgi.daemon_connects
'1'
mod_wsgi.daemon_restarts
'0'
mod_wsgi.daemon_start
'1615618126945298'
mod_wsgi.enable_sendfile
'0'
mod_wsgi.handler_script
''
mod_wsgi.ignore_activity
'0'
mod_wsgi.listener_host
''
mod_wsgi.listener_port
'80'
mod_wsgi.path_info
'/'
mod_wsgi.process_group
'django_app'
mod_wsgi.queue_start
'1615618126945099'
mod_wsgi.request_handler
'wsgi-script'
mod_wsgi.request_id
'Z5qMaD13cW8'
mod_wsgi.request_start
'1615618126944871'
mod_wsgi.script_name
''
mod_wsgi.script_reloading
'1'
mod_wsgi.script_start
'1615618126945462'
mod_wsgi.thread_id
2
mod_wsgi.thread_requests
13
mod_wsgi.total_requests
27
mod_wsgi.version
(4, 6, 8)
wsgi.errors
<_io.TextIOWrapper name='<wsgi.errors>' encoding='utf-8'>
wsgi.file_wrapper
<class 'mod_wsgi.FileWrapper'>
wsgi.input
<mod_wsgi.Input object at 0x7f38645595e0>
wsgi.input_terminated
True
wsgi.multiprocess
False
wsgi.multithread
True
wsgi.run_once
False
wsgi.url_scheme
'http'
wsgi.version
(1, 0)
在我的网络浏览器的设置中
ABSOLUTE_URL_OVERRIDES
{}
ADMINS
[]
ALLOWED_HOSTS
['139.162.163.35']
APPEND_SLASH
True
AUTHENTICATION_BACKENDS
['django.contrib.auth.backends.ModelBackend']
AUTH_PASSWORD_VALIDATORS
'********************'
AUTH_USER_MODEL
'auth.User'
BASE_DIR
PosixPath('/home/jianwu/HD_website/website')
CACHES
{'default': {'BACKEND': 'django.core.cache.backends.locmem.LocMemCache'}}
CACHE_MIDDLEWARE_ALIAS
'default'
CACHE_MIDDLEWARE_KEY_PREFIX
'********************'
CACHE_MIDDLEWARE_SECONDS
600
CSRF_COOKIE_AGE
31449600
CSRF_COOKIE_DOMAIN
None
CSRF_COOKIE_HTTPONLY
False
CSRF_COOKIE_NAME
'csrftoken'
CSRF_COOKIE_PATH
'/'
CSRF_COOKIE_SAMESITE
'Lax'
CSRF_COOKIE_SECURE
False
CSRF_FAILURE_VIEW
'django.views.csrf.csrf_failure'
CSRF_HEADER_NAME
'HTTP_X_CSRFTOKEN'
CSRF_TRUSTED_ORIGINS
[]
CSRF_USE_SESSIONS
False
DATABASES
{'default': {'ATOMIC_REQUESTS': False,
'AUTOCOMMIT': True,
'CONN_MAX_AGE': 0,
'ENGINE': 'django.db.backends.sqlite3',
'HOST': '',
'NAME': PosixPath('/home/jianwu/HD_website/website/db.sqlite3'),
'OPTIONS': {},
'PASSWORD': '********************',
'PORT': '',
'TEST': {'CHARSET': None,
'COLLATION': None,
'MIGRATE': True,
'MIRROR': None,
'NAME': None},
'TIME_ZONE': None,
'USER': ''}}
DATABASE_ROUTERS
[]
DATA_UPLOAD_MAX_MEMORY_SIZE
2621440
DATA_UPLOAD_MAX_NUMBER_FIELDS
1000
DATETIME_FORMAT
'N j, Y, P'
DATETIME_INPUT_FORMATS
['%Y-%m-%d %H:%M:%S',
'%Y-%m-%d %H:%M:%S.%f',
'%Y-%m-%d %H:%M',
'%m/%d/%Y %H:%M:%S',
'%m/%d/%Y %H:%M:%S.%f',
'%m/%d/%Y %H:%M',
'%m/%d/%y %H:%M:%S',
'%m/%d/%y %H:%M:%S.%f',
'%m/%d/%y %H:%M']
DATE_FORMAT
'N j, Y'
DATE_INPUT_FORMATS
['%Y-%m-%d',
'%m/%d/%Y',
'%m/%d/%y',
'%b %d %Y',
'%b %d, %Y',
'%d %b %Y',
'%d %b, %Y',
'%B %d %Y',
'%B %d, %Y',
'%d %B %Y',
'%d %B, %Y']
DEBUG
True
DEBUG_PROPAGATE_EXCEPTIONS
False
DECIMAL_SEPARATOR
'.'
DEFAULT_CHARSET
'utf-8'
DEFAULT_EXCEPTION_REPORTER
'django.views.debug.ExceptionReporter'
DEFAULT_EXCEPTION_REPORTER_FILTER
'django.views.debug.SafeExceptionReporterFilter'
DEFAULT_FILE_STORAGE
'django.core.files.storage.FileSystemStorage'
DEFAULT_FROM_EMAIL
'webmaster@localhost'
DEFAULT_HASHING_ALGORITHM
'sha256'
DEFAULT_INDEX_TABLESPACE
''
DEFAULT_TABLESPACE
''
DISALLOWED_USER_AGENTS
[]
EMAIL_BACKEND
'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST
'localhost'
EMAIL_HOST_PASSWORD
'********************'
EMAIL_HOST_USER
''
EMAIL_PORT
25
EMAIL_SSL_CERTFILE
None
EMAIL_SSL_KEYFILE
'********************'
EMAIL_SUBJECT_PREFIX
'[Django] '
EMAIL_TIMEOUT
None
EMAIL_USE_LOCALTIME
False
EMAIL_USE_SSL
False
EMAIL_USE_TLS
False
FILE_UPLOAD_DIRECTORY_PERMISSIONS
None
FILE_UPLOAD_HANDLERS
['django.core.files.uploadhandler.MemoryFileUploadHandler',
'django.core.files.uploadhandler.TemporaryFileUploadHandler']
FILE_UPLOAD_MAX_MEMORY_SIZE
2621440
FILE_UPLOAD_PERMISSIONS
420
FILE_UPLOAD_TEMP_DIR
None
FIRST_DAY_OF_WEEK
0
FIXTURE_DIRS
[]
FORCE_SCRIPT_NAME
None
FORMAT_MODULE_PATH
None
FORM_RENDERER
'django.forms.renderers.DjangoTemplates'
IGNORABLE_404_URLS
[]
INSTALLED_APPS
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles']
INTERNAL_IPS
[]
LANGUAGES
[('af', 'Afrikaans'),
('ar', 'Arabic'),
('ar-dz', 'Algerian Arabic'),
('ast', 'Asturian'),
('az', 'Azerbaijani'),
('bg', 'Bulgarian'),
('be', 'Belarusian'),
('bn', 'Bengali'),
('br', 'Breton'),
('bs', 'Bosnian'),
('ca', 'Catalan'),
('cs', 'Czech'),
('cy', 'Welsh'),
('da', 'Danish'),
('de', 'German'),
('dsb', 'Lower Sorbian'),
('el', 'Greek'),
('en', 'English'),
('en-au', 'Australian English'),
('en-gb', 'British English'),
('eo', 'Esperanto'),
('es', 'Spanish'),
('es-ar', 'Argentinian Spanish'),
('es-co', 'Colombian Spanish'),
('es-mx', 'Mexican Spanish'),
('es-ni', 'Nicaraguan Spanish'),
('es-ve', 'Venezuelan Spanish'),
('et', 'Estonian'),
('eu', 'Basque'),
('fa', 'Persian'),
('fi', 'Finnish'),
('fr', 'French'),
('fy', 'Frisian'),
('ga', 'Irish'),
('gd', 'Scottish Gaelic'),
('gl', 'Galician'),
('he', 'Hebrew'),
('hi', 'Hindi'),
('hr', 'Croatian'),
('hsb', 'Upper Sorbian'),
('hu', 'Hungarian'),
('hy', 'Armenian'),
('ia', 'Interlingua'),
('id', 'Indonesian'),
('ig', 'Igbo'),
('io', 'Ido'),
('is', 'Icelandic'),
('it', 'Italian'),
('ja', 'Japanese'),
('ka', 'Georgian'),
('kab', 'Kabyle'),
('kk', 'Kazakh'),
('km', 'Khmer'),
('kn', 'Kannada'),
('ko', 'Korean'),
('ky', 'Kyrgyz'),
('lb', 'Luxembourgish'),
('lt', 'Lithuanian'),
('lv', 'Latvian'),
('mk', 'Macedonian'),
('ml', 'Malayalam'),
('mn', 'Mongolian'),
('mr', 'Marathi'),
('my', 'Burmese'),
('nb', 'Norwegian Bokmål'),
('ne', 'Nepali'),
('nl', 'Dutch'),
('nn', 'Norwegian Nynorsk'),
('os', 'Ossetic'),
('pa', 'Punjabi'),
('pl', 'Polish'),
('pt', 'Portuguese'),
('pt-br', 'Brazilian Portuguese'),
('ro', 'Romanian'),
('ru', 'Russian'),
('sk', 'Slovak'),
('sl', 'Slovenian'),
('sq', 'Albanian'),
('sr', 'Serbian'),
('sr-latn', 'Serbian Latin'),
('sv', 'Swedish'),
('sw', 'Swahili'),
('ta', 'Tamil'),
('te', 'Telugu'),
('tg', 'Tajik'),
('th', 'Thai'),
('tk', 'Turkmen'),
('tr', 'Turkish'),
('tt', 'Tatar'),
('udm', 'Udmurt'),
('uk', 'Ukrainian'),
('ur', 'Urdu'),
('uz', 'Uzbek'),
('vi', 'Vietnamese'),
('zh-hans', 'Simplified Chinese'),
('zh-hant', 'Traditional Chinese')]
LANGUAGES_BIDI
['he', 'ar', 'ar-dz', 'fa', 'ur']
LANGUAGE_CODE
'en-us'
LANGUAGE_COOKIE_AGE
None
LANGUAGE_COOKIE_DOMAIN
None
LANGUAGE_COOKIE_HTTPONLY
False
LANGUAGE_COOKIE_NAME
'django_language'
LANGUAGE_COOKIE_PATH
'/'
LANGUAGE_COOKIE_SAMESITE
None
LANGUAGE_COOKIE_SECURE
False
LOCALE_PATHS
[]
LOGGING
{}
LOGGING_CONFIG
'logging.config.dictConfig'
LOGIN_REDIRECT_URL
'/accounts/profile/'
LOGIN_URL
'/accounts/login/'
LOGOUT_REDIRECT_URL
None
MANAGERS
[]
MEDIA_ROOT
''
MEDIA_URL
'/'
MESSAGE_STORAGE
'django.contrib.messages.storage.fallback.FallbackStorage'
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']
MIGRATION_MODULES
{}
MONTH_DAY_FORMAT
'F j'
NUMBER_GROUPING
0
PASSWORD_HASHERS
'********************'
PASSWORD_RESET_TIMEOUT
'********************'
PASSWORD_RESET_TIMEOUT_DAYS
'********************'
PREPEND_WWW
False
ROOT_URLCONF
'website.urls'
SECRET_KEY
'********************'
SECURE_BROWSER_XSS_FILTER
False
SECURE_CONTENT_TYPE_NOSNIFF
True
SECURE_HSTS_INCLUDE_SUBDOMAINS
False
SECURE_HSTS_PRELOAD
False
SECURE_HSTS_SECONDS
0
SECURE_PROXY_SSL_HEADER
None
SECURE_REDIRECT_EXEMPT
[]
SECURE_REFERRER_POLICY
'same-origin'
SECURE_SSL_HOST
None
SECURE_SSL_REDIRECT
False
SERVER_EMAIL
'root@localhost'
SESSION_CACHE_ALIAS
'default'
SESSION_COOKIE_AGE
1209600
SESSION_COOKIE_DOMAIN
None
SESSION_COOKIE_HTTPONLY
True
SESSION_COOKIE_NAME
'sessionid'
SESSION_COOKIE_PATH
'/'
SESSION_COOKIE_SAMESITE
'Lax'
SESSION_COOKIE_SECURE
False
SESSION_ENGINE
'django.contrib.sessions.backends.db'
SESSION_EXPIRE_AT_BROWSER_CLOSE
False
SESSION_FILE_PATH
None
SESSION_SAVE_EVERY_REQUEST
False
SESSION_SERIALIZER
'django.contrib.sessions.serializers.JSONSerializer'
SETTINGS_MODULE
'website.settings'
SHORT_DATETIME_FORMAT
'm/d/Y P'
SHORT_DATE_FORMAT
'm/d/Y'
SIGNING_BACKEND
'django.core.signing.TimestampSigner'
SILENCED_SYSTEM_CHECKS
[]
STATICFILES_DIRS
('/home/jianwu/HD_website/website/static',)
STATICFILES_FINDERS
['django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder']
STATICFILES_STORAGE
'django.contrib.staticfiles.storage.StaticFilesStorage'
STATIC_ROOT
'/home/jianwu/HD_website/website/productionStatic'
STATIC_URL
'/static/'
TEMPLATES
[{'APP_DIRS': True,
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': ['templates'],
'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']}}]
TEST_NON_SERIALIZED_APPS
[]
TEST_RUNNER
'django.test.runner.DiscoverRunner'
THOUSAND_SEPARATOR
','
TIME_FORMAT
'P'
TIME_INPUT_FORMATS
['%H:%M:%S', '%H:%M:%S.%f', '%H:%M']
TIME_ZONE
'UTC'
USE_I18N
True
USE_L10N
True
USE_THOUSAND_SEPARATOR
False
USE_TZ
True
USE_X_FORWARDED_HOST
False
USE_X_FORWARDED_PORT
False
WSGI_APPLICATION
'website.wsgi.application'
X_FRAME_OPTIONS
'DENY'
YEAR_MONTH_FORMAT
'F Y'
我的 settings.py 如下,我已将我的 STATIC_ROOT
指向 productionStatic
文件夹。这是 collectstatic 将静态文件从我的 static
文件夹传输到 productionStatic
的文件夹。我不确定为什么这是必要的,因为我只能从 Django 的文档中了解到应该在生产中复制文件。
"""
Django settings for website project.
Generated by 'django-admin startproject' using Django 3.1.3.
For more information on this file, see
https://docs.djangoproject.com/en/3.1/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.1/ref/settings/
"""
from pathlib import Path
import os
import json
#with open('/etc/config.json') as fileId:
# config = json.load(fileId)
# 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/3.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'xxxxxxxxxxxxxxxxxxx'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ['139.162.163.35']
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
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',
]
ROOT_URLCONF = 'website.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': ['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',
],
},
},
]
WSGI_APPLICATION = 'website.wsgi.application'
# Database
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
# Password validation
# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators
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',
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.1/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.1/howto/static-files/
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'productionStatic')
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'),)
在我的 views.py 中,我导入相关 txt 文件的片段在 static/aboutUsNytorv.txt 中。我试图将其更改为 productionStatic/aboutUsNytorv.txt,但它一直说找不到文件。
from django.shortcuts import redirect, render
from django.contrib import messages
from django.views import View
from .forms import contactForm
from .forms import newsLetterForm
from website.Modules.emailMessage import sendEmail
from website.Modules.registerEmailSubscription import registerEmail
from website.Modules.recaptchaValidate import Validate
# Create your views here.
class ContextBuilder:
def __init__(self):
self.context = {'imagePath' : None,
'navbarLogoPath' : None,
'links' : None,
'menuImgPath' : None,
'aboutUsImagePath' : None,
'aboutUsText' : None,
'dayRange1' : None,
'timeRange1' : None,
'form' : None,
'emailSignUpForm' : None,
'shopTitle' : None,
'addressStreet' : None,
'addressPhone' : None,
'addressEmail' : 'kontakt@dimsum.dk',
'addressCVR' : 'CVR: 38908901',
'instagramLink' : None,
'youtubeLink' : None,
'facebookLink' : None}
def Set_headerCoverImageLinks(self, linksList):
'''
Accepts a list of tuples containing ('Link_title', 'url')
'''
self.links = list()
for linkTuple in linksList:
self.links.append(linkTuple)
def Set_context(self, **kwargs):
'''
The kwargs points to the dictionary keys in context, and the values are inserted
'''
for key in kwargs.keys():
self.context[key] = kwargs[key]
def importTextFile(self, filePath):
with open(filePath,'r') as fid:
self.textString = fid.read()
class indexPage(View):
def __init__(self, *args, **kwargs):
self.ContextObject = ContextBuilder()
self.ContextObject.importTextFile('static/mainAboutUs.txt')
self.ContextObject.Set_headerCoverImageLinks(linksList = [
('LOCATIONS', '#anchor_locations'),
('ABOUT US', '#anchor-aboutUs'),
('CONTACT', '#anchor-mainContact')
]
)
self.emailSignupForm = newsLetterForm()
self.ContextObject.Set_context(
links = self.ContextObject.links,
imagePath = 'static/media/cover.jpg',
aboutUsImagePath = 'static/media/aboutus2900.jpg',
aboutUsText = self.ContextObject.textString,
coverTitle1 = 'We are dimsum!',
coverTitle2 = 'at',
coverTitle3 = 'HIDDEN DIMSUM',
emailSignUpForm = self.emailSignupForm,
shopTitle = 'Hidden Dimsum',
addressStreet = 'Nytorv 19',
addressPostcodeCity = '1450 København K',
addressPhone = '+45-33 12 88 28')
self.context = self.ContextObject.context
def get(self, request, *args, **kwargs):
return render(request, template_name='index.html', context = self.context)
在我的 apache2 设置中,我有以下代码,其中我已将静态别名指向 productionStatic 中的文件夹。我错过了什么?
<VirtualHost *:80>
# The ServerName directive sets the request scheme, hostname and port that
# the server uses to identify itself. This is used when creating
# redirection URLs. In the context of virtual hosts, the ServerName
# specifies what hostname must appear in the request's Host: header to
# match this virtual host. For the default virtual host (this file) this
# value is not decisive as it is used as a last resort host regardless.
# However, you must set it for any further virtual host explicitly.
#ServerName www.example.com
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual host. For example the
# following line enables the CGI configuration for this host only
# after it has been globally disabled with "a2disconf".
#Include conf-available/serve-cgi-bin.conf
Alias /static /home/jianwu/HD_website/website/productionStatic
<Directory /home/jianwu/HD_website/website/productionStatic>
Require all granted
</Directory>
Alias /media /home/jianwu/HD_website/website/media
<Directory /home/jianwu/HD_website/website/media>
Require all granted
</Directory>
<Directory /home/jianwu/HD_website/website/website>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
WSGIScriptAlias / /home/jianwu/HD_website/website/website/wsgi.py
WSGIDaemonProcess django_app python-path=/home/jianwu/HD_website/website python-home=/home/jianwu/HD_website/website/env
WSGIProcessGroup django_app
</VirtualHost>
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
正如 Ivan Starostin 所评论的那样,应该提供生产环境中文件的绝对路径。在这种情况下,也可以按照评论中的建议使用反向 url。
我正在尝试使用 Ubuntu 和 apache 网络服务器部署我的 Django 项目。当我将我的项目转移到 Ubuntu 网络服务器并在开发中对其进行测试时,一切正常。然而,当更改为生产时,我遇到了找不到文件的问题,我怀疑这个问题与我的 setings.py 有关,但我无法进一步解决它。我在访问我的网站时在生产中看到的错误是:
Environment:
Request Method: GET
Request URL: http://139.162.163.35/
Django Version: 3.1.3
Python Version: 3.8.5
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles']
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 (most recent call last):
File "/home/jianwu/HD_website/website/env/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/home/jianwu/HD_website/website/env/lib/python3.8/site-packages/django/core/handlers/base.py", line 179, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/jianwu/HD_website/website/env/lib/python3.8/site-packages/django/views/generic/base.py", line 63, in view
self = cls(**initkwargs)
File "/home/jianwu/HD_website/website/index/views.py", line 57, in __init__
self.ContextObject.importTextFile('static/mainAboutUs.txt')
File "/home/jianwu/HD_website/website/index/views.py", line 50, in importTextFile
with open(filePath,'r') as fid:
Exception Type: FileNotFoundError at /
Exception Value: [Errno 2] No such file or directory: 'static/mainAboutUs.txt'
在我的 Meta 中我有
CONTEXT_DOCUMENT_ROOT
'/var/www/html'
CONTEXT_PREFIX
''
CSRF_COOKIE
'jF3vdEgpyhbKxavRw3pEWzRdIjc4lvw0MsV4lpBLdYXPqcGcIVyH02kEuBeGSXlh'
DOCUMENT_ROOT
'/var/www/html'
GATEWAY_INTERFACE
'CGI/1.1'
HTTP_ACCEPT
'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9'
HTTP_ACCEPT_ENCODING
'gzip, deflate'
HTTP_ACCEPT_LANGUAGE
'da-DK,da;q=0.9,en-US;q=0.8,en;q=0.7,bg;q=0.6,zh-CN;q=0.5,zh;q=0.4'
HTTP_CONNECTION
'keep-alive'
HTTP_COOKIE
'csrftoken=jF3vdEgpyhbKxavRw3pEWzRdIjc4lvw0MsV4lpBLdYXPqcGcIVyH02kEuBeGSXlh'
HTTP_HOST
'139.162.163.35'
HTTP_PURPOSE
'prefetch'
HTTP_UPGRADE_INSECURE_REQUESTS
'1'
HTTP_USER_AGENT
('Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_2) AppleWebKit/537.36 (KHTML, '
'like Gecko) Chrome/88.0.4324.192 Safari/537.36')
PATH_INFO
'/'
PATH_TRANSLATED
'/home/jianwu/HD_website/website/website/wsgi.py/'
QUERY_STRING
''
REMOTE_ADDR
'94.147.65.45'
REMOTE_PORT
'58717'
REQUEST_METHOD
'GET'
REQUEST_SCHEME
'http'
REQUEST_URI
'/'
SCRIPT_FILENAME
'/home/jianwu/HD_website/website/website/wsgi.py'
SCRIPT_NAME
''
SERVER_ADDR
'139.162.163.35'
SERVER_ADMIN
'webmaster@localhost'
SERVER_NAME
'139.162.163.35'
SERVER_PORT
'80'
SERVER_PROTOCOL
'HTTP/1.1'
SERVER_SIGNATURE
'********************'
SERVER_SOFTWARE
'Apache/2.4.41 (Ubuntu)'
apache.version
(2, 4, 41)
mod_wsgi.application_group
'139.162.163.35|'
mod_wsgi.callable_object
'application'
mod_wsgi.daemon_connects
'1'
mod_wsgi.daemon_restarts
'0'
mod_wsgi.daemon_start
'1615618126945298'
mod_wsgi.enable_sendfile
'0'
mod_wsgi.handler_script
''
mod_wsgi.ignore_activity
'0'
mod_wsgi.listener_host
''
mod_wsgi.listener_port
'80'
mod_wsgi.path_info
'/'
mod_wsgi.process_group
'django_app'
mod_wsgi.queue_start
'1615618126945099'
mod_wsgi.request_handler
'wsgi-script'
mod_wsgi.request_id
'Z5qMaD13cW8'
mod_wsgi.request_start
'1615618126944871'
mod_wsgi.script_name
''
mod_wsgi.script_reloading
'1'
mod_wsgi.script_start
'1615618126945462'
mod_wsgi.thread_id
2
mod_wsgi.thread_requests
13
mod_wsgi.total_requests
27
mod_wsgi.version
(4, 6, 8)
wsgi.errors
<_io.TextIOWrapper name='<wsgi.errors>' encoding='utf-8'>
wsgi.file_wrapper
<class 'mod_wsgi.FileWrapper'>
wsgi.input
<mod_wsgi.Input object at 0x7f38645595e0>
wsgi.input_terminated
True
wsgi.multiprocess
False
wsgi.multithread
True
wsgi.run_once
False
wsgi.url_scheme
'http'
wsgi.version
(1, 0)
在我的网络浏览器的设置中
ABSOLUTE_URL_OVERRIDES
{}
ADMINS
[]
ALLOWED_HOSTS
['139.162.163.35']
APPEND_SLASH
True
AUTHENTICATION_BACKENDS
['django.contrib.auth.backends.ModelBackend']
AUTH_PASSWORD_VALIDATORS
'********************'
AUTH_USER_MODEL
'auth.User'
BASE_DIR
PosixPath('/home/jianwu/HD_website/website')
CACHES
{'default': {'BACKEND': 'django.core.cache.backends.locmem.LocMemCache'}}
CACHE_MIDDLEWARE_ALIAS
'default'
CACHE_MIDDLEWARE_KEY_PREFIX
'********************'
CACHE_MIDDLEWARE_SECONDS
600
CSRF_COOKIE_AGE
31449600
CSRF_COOKIE_DOMAIN
None
CSRF_COOKIE_HTTPONLY
False
CSRF_COOKIE_NAME
'csrftoken'
CSRF_COOKIE_PATH
'/'
CSRF_COOKIE_SAMESITE
'Lax'
CSRF_COOKIE_SECURE
False
CSRF_FAILURE_VIEW
'django.views.csrf.csrf_failure'
CSRF_HEADER_NAME
'HTTP_X_CSRFTOKEN'
CSRF_TRUSTED_ORIGINS
[]
CSRF_USE_SESSIONS
False
DATABASES
{'default': {'ATOMIC_REQUESTS': False,
'AUTOCOMMIT': True,
'CONN_MAX_AGE': 0,
'ENGINE': 'django.db.backends.sqlite3',
'HOST': '',
'NAME': PosixPath('/home/jianwu/HD_website/website/db.sqlite3'),
'OPTIONS': {},
'PASSWORD': '********************',
'PORT': '',
'TEST': {'CHARSET': None,
'COLLATION': None,
'MIGRATE': True,
'MIRROR': None,
'NAME': None},
'TIME_ZONE': None,
'USER': ''}}
DATABASE_ROUTERS
[]
DATA_UPLOAD_MAX_MEMORY_SIZE
2621440
DATA_UPLOAD_MAX_NUMBER_FIELDS
1000
DATETIME_FORMAT
'N j, Y, P'
DATETIME_INPUT_FORMATS
['%Y-%m-%d %H:%M:%S',
'%Y-%m-%d %H:%M:%S.%f',
'%Y-%m-%d %H:%M',
'%m/%d/%Y %H:%M:%S',
'%m/%d/%Y %H:%M:%S.%f',
'%m/%d/%Y %H:%M',
'%m/%d/%y %H:%M:%S',
'%m/%d/%y %H:%M:%S.%f',
'%m/%d/%y %H:%M']
DATE_FORMAT
'N j, Y'
DATE_INPUT_FORMATS
['%Y-%m-%d',
'%m/%d/%Y',
'%m/%d/%y',
'%b %d %Y',
'%b %d, %Y',
'%d %b %Y',
'%d %b, %Y',
'%B %d %Y',
'%B %d, %Y',
'%d %B %Y',
'%d %B, %Y']
DEBUG
True
DEBUG_PROPAGATE_EXCEPTIONS
False
DECIMAL_SEPARATOR
'.'
DEFAULT_CHARSET
'utf-8'
DEFAULT_EXCEPTION_REPORTER
'django.views.debug.ExceptionReporter'
DEFAULT_EXCEPTION_REPORTER_FILTER
'django.views.debug.SafeExceptionReporterFilter'
DEFAULT_FILE_STORAGE
'django.core.files.storage.FileSystemStorage'
DEFAULT_FROM_EMAIL
'webmaster@localhost'
DEFAULT_HASHING_ALGORITHM
'sha256'
DEFAULT_INDEX_TABLESPACE
''
DEFAULT_TABLESPACE
''
DISALLOWED_USER_AGENTS
[]
EMAIL_BACKEND
'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST
'localhost'
EMAIL_HOST_PASSWORD
'********************'
EMAIL_HOST_USER
''
EMAIL_PORT
25
EMAIL_SSL_CERTFILE
None
EMAIL_SSL_KEYFILE
'********************'
EMAIL_SUBJECT_PREFIX
'[Django] '
EMAIL_TIMEOUT
None
EMAIL_USE_LOCALTIME
False
EMAIL_USE_SSL
False
EMAIL_USE_TLS
False
FILE_UPLOAD_DIRECTORY_PERMISSIONS
None
FILE_UPLOAD_HANDLERS
['django.core.files.uploadhandler.MemoryFileUploadHandler',
'django.core.files.uploadhandler.TemporaryFileUploadHandler']
FILE_UPLOAD_MAX_MEMORY_SIZE
2621440
FILE_UPLOAD_PERMISSIONS
420
FILE_UPLOAD_TEMP_DIR
None
FIRST_DAY_OF_WEEK
0
FIXTURE_DIRS
[]
FORCE_SCRIPT_NAME
None
FORMAT_MODULE_PATH
None
FORM_RENDERER
'django.forms.renderers.DjangoTemplates'
IGNORABLE_404_URLS
[]
INSTALLED_APPS
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles']
INTERNAL_IPS
[]
LANGUAGES
[('af', 'Afrikaans'),
('ar', 'Arabic'),
('ar-dz', 'Algerian Arabic'),
('ast', 'Asturian'),
('az', 'Azerbaijani'),
('bg', 'Bulgarian'),
('be', 'Belarusian'),
('bn', 'Bengali'),
('br', 'Breton'),
('bs', 'Bosnian'),
('ca', 'Catalan'),
('cs', 'Czech'),
('cy', 'Welsh'),
('da', 'Danish'),
('de', 'German'),
('dsb', 'Lower Sorbian'),
('el', 'Greek'),
('en', 'English'),
('en-au', 'Australian English'),
('en-gb', 'British English'),
('eo', 'Esperanto'),
('es', 'Spanish'),
('es-ar', 'Argentinian Spanish'),
('es-co', 'Colombian Spanish'),
('es-mx', 'Mexican Spanish'),
('es-ni', 'Nicaraguan Spanish'),
('es-ve', 'Venezuelan Spanish'),
('et', 'Estonian'),
('eu', 'Basque'),
('fa', 'Persian'),
('fi', 'Finnish'),
('fr', 'French'),
('fy', 'Frisian'),
('ga', 'Irish'),
('gd', 'Scottish Gaelic'),
('gl', 'Galician'),
('he', 'Hebrew'),
('hi', 'Hindi'),
('hr', 'Croatian'),
('hsb', 'Upper Sorbian'),
('hu', 'Hungarian'),
('hy', 'Armenian'),
('ia', 'Interlingua'),
('id', 'Indonesian'),
('ig', 'Igbo'),
('io', 'Ido'),
('is', 'Icelandic'),
('it', 'Italian'),
('ja', 'Japanese'),
('ka', 'Georgian'),
('kab', 'Kabyle'),
('kk', 'Kazakh'),
('km', 'Khmer'),
('kn', 'Kannada'),
('ko', 'Korean'),
('ky', 'Kyrgyz'),
('lb', 'Luxembourgish'),
('lt', 'Lithuanian'),
('lv', 'Latvian'),
('mk', 'Macedonian'),
('ml', 'Malayalam'),
('mn', 'Mongolian'),
('mr', 'Marathi'),
('my', 'Burmese'),
('nb', 'Norwegian Bokmål'),
('ne', 'Nepali'),
('nl', 'Dutch'),
('nn', 'Norwegian Nynorsk'),
('os', 'Ossetic'),
('pa', 'Punjabi'),
('pl', 'Polish'),
('pt', 'Portuguese'),
('pt-br', 'Brazilian Portuguese'),
('ro', 'Romanian'),
('ru', 'Russian'),
('sk', 'Slovak'),
('sl', 'Slovenian'),
('sq', 'Albanian'),
('sr', 'Serbian'),
('sr-latn', 'Serbian Latin'),
('sv', 'Swedish'),
('sw', 'Swahili'),
('ta', 'Tamil'),
('te', 'Telugu'),
('tg', 'Tajik'),
('th', 'Thai'),
('tk', 'Turkmen'),
('tr', 'Turkish'),
('tt', 'Tatar'),
('udm', 'Udmurt'),
('uk', 'Ukrainian'),
('ur', 'Urdu'),
('uz', 'Uzbek'),
('vi', 'Vietnamese'),
('zh-hans', 'Simplified Chinese'),
('zh-hant', 'Traditional Chinese')]
LANGUAGES_BIDI
['he', 'ar', 'ar-dz', 'fa', 'ur']
LANGUAGE_CODE
'en-us'
LANGUAGE_COOKIE_AGE
None
LANGUAGE_COOKIE_DOMAIN
None
LANGUAGE_COOKIE_HTTPONLY
False
LANGUAGE_COOKIE_NAME
'django_language'
LANGUAGE_COOKIE_PATH
'/'
LANGUAGE_COOKIE_SAMESITE
None
LANGUAGE_COOKIE_SECURE
False
LOCALE_PATHS
[]
LOGGING
{}
LOGGING_CONFIG
'logging.config.dictConfig'
LOGIN_REDIRECT_URL
'/accounts/profile/'
LOGIN_URL
'/accounts/login/'
LOGOUT_REDIRECT_URL
None
MANAGERS
[]
MEDIA_ROOT
''
MEDIA_URL
'/'
MESSAGE_STORAGE
'django.contrib.messages.storage.fallback.FallbackStorage'
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']
MIGRATION_MODULES
{}
MONTH_DAY_FORMAT
'F j'
NUMBER_GROUPING
0
PASSWORD_HASHERS
'********************'
PASSWORD_RESET_TIMEOUT
'********************'
PASSWORD_RESET_TIMEOUT_DAYS
'********************'
PREPEND_WWW
False
ROOT_URLCONF
'website.urls'
SECRET_KEY
'********************'
SECURE_BROWSER_XSS_FILTER
False
SECURE_CONTENT_TYPE_NOSNIFF
True
SECURE_HSTS_INCLUDE_SUBDOMAINS
False
SECURE_HSTS_PRELOAD
False
SECURE_HSTS_SECONDS
0
SECURE_PROXY_SSL_HEADER
None
SECURE_REDIRECT_EXEMPT
[]
SECURE_REFERRER_POLICY
'same-origin'
SECURE_SSL_HOST
None
SECURE_SSL_REDIRECT
False
SERVER_EMAIL
'root@localhost'
SESSION_CACHE_ALIAS
'default'
SESSION_COOKIE_AGE
1209600
SESSION_COOKIE_DOMAIN
None
SESSION_COOKIE_HTTPONLY
True
SESSION_COOKIE_NAME
'sessionid'
SESSION_COOKIE_PATH
'/'
SESSION_COOKIE_SAMESITE
'Lax'
SESSION_COOKIE_SECURE
False
SESSION_ENGINE
'django.contrib.sessions.backends.db'
SESSION_EXPIRE_AT_BROWSER_CLOSE
False
SESSION_FILE_PATH
None
SESSION_SAVE_EVERY_REQUEST
False
SESSION_SERIALIZER
'django.contrib.sessions.serializers.JSONSerializer'
SETTINGS_MODULE
'website.settings'
SHORT_DATETIME_FORMAT
'm/d/Y P'
SHORT_DATE_FORMAT
'm/d/Y'
SIGNING_BACKEND
'django.core.signing.TimestampSigner'
SILENCED_SYSTEM_CHECKS
[]
STATICFILES_DIRS
('/home/jianwu/HD_website/website/static',)
STATICFILES_FINDERS
['django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder']
STATICFILES_STORAGE
'django.contrib.staticfiles.storage.StaticFilesStorage'
STATIC_ROOT
'/home/jianwu/HD_website/website/productionStatic'
STATIC_URL
'/static/'
TEMPLATES
[{'APP_DIRS': True,
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': ['templates'],
'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']}}]
TEST_NON_SERIALIZED_APPS
[]
TEST_RUNNER
'django.test.runner.DiscoverRunner'
THOUSAND_SEPARATOR
','
TIME_FORMAT
'P'
TIME_INPUT_FORMATS
['%H:%M:%S', '%H:%M:%S.%f', '%H:%M']
TIME_ZONE
'UTC'
USE_I18N
True
USE_L10N
True
USE_THOUSAND_SEPARATOR
False
USE_TZ
True
USE_X_FORWARDED_HOST
False
USE_X_FORWARDED_PORT
False
WSGI_APPLICATION
'website.wsgi.application'
X_FRAME_OPTIONS
'DENY'
YEAR_MONTH_FORMAT
'F Y'
我的 settings.py 如下,我已将我的 STATIC_ROOT
指向 productionStatic
文件夹。这是 collectstatic 将静态文件从我的 static
文件夹传输到 productionStatic
的文件夹。我不确定为什么这是必要的,因为我只能从 Django 的文档中了解到应该在生产中复制文件。
"""
Django settings for website project.
Generated by 'django-admin startproject' using Django 3.1.3.
For more information on this file, see
https://docs.djangoproject.com/en/3.1/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.1/ref/settings/
"""
from pathlib import Path
import os
import json
#with open('/etc/config.json') as fileId:
# config = json.load(fileId)
# 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/3.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'xxxxxxxxxxxxxxxxxxx'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ['139.162.163.35']
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
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',
]
ROOT_URLCONF = 'website.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': ['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',
],
},
},
]
WSGI_APPLICATION = 'website.wsgi.application'
# Database
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
# Password validation
# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators
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',
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.1/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.1/howto/static-files/
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'productionStatic')
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'),)
在我的 views.py 中,我导入相关 txt 文件的片段在 static/aboutUsNytorv.txt 中。我试图将其更改为 productionStatic/aboutUsNytorv.txt,但它一直说找不到文件。
from django.shortcuts import redirect, render
from django.contrib import messages
from django.views import View
from .forms import contactForm
from .forms import newsLetterForm
from website.Modules.emailMessage import sendEmail
from website.Modules.registerEmailSubscription import registerEmail
from website.Modules.recaptchaValidate import Validate
# Create your views here.
class ContextBuilder:
def __init__(self):
self.context = {'imagePath' : None,
'navbarLogoPath' : None,
'links' : None,
'menuImgPath' : None,
'aboutUsImagePath' : None,
'aboutUsText' : None,
'dayRange1' : None,
'timeRange1' : None,
'form' : None,
'emailSignUpForm' : None,
'shopTitle' : None,
'addressStreet' : None,
'addressPhone' : None,
'addressEmail' : 'kontakt@dimsum.dk',
'addressCVR' : 'CVR: 38908901',
'instagramLink' : None,
'youtubeLink' : None,
'facebookLink' : None}
def Set_headerCoverImageLinks(self, linksList):
'''
Accepts a list of tuples containing ('Link_title', 'url')
'''
self.links = list()
for linkTuple in linksList:
self.links.append(linkTuple)
def Set_context(self, **kwargs):
'''
The kwargs points to the dictionary keys in context, and the values are inserted
'''
for key in kwargs.keys():
self.context[key] = kwargs[key]
def importTextFile(self, filePath):
with open(filePath,'r') as fid:
self.textString = fid.read()
class indexPage(View):
def __init__(self, *args, **kwargs):
self.ContextObject = ContextBuilder()
self.ContextObject.importTextFile('static/mainAboutUs.txt')
self.ContextObject.Set_headerCoverImageLinks(linksList = [
('LOCATIONS', '#anchor_locations'),
('ABOUT US', '#anchor-aboutUs'),
('CONTACT', '#anchor-mainContact')
]
)
self.emailSignupForm = newsLetterForm()
self.ContextObject.Set_context(
links = self.ContextObject.links,
imagePath = 'static/media/cover.jpg',
aboutUsImagePath = 'static/media/aboutus2900.jpg',
aboutUsText = self.ContextObject.textString,
coverTitle1 = 'We are dimsum!',
coverTitle2 = 'at',
coverTitle3 = 'HIDDEN DIMSUM',
emailSignUpForm = self.emailSignupForm,
shopTitle = 'Hidden Dimsum',
addressStreet = 'Nytorv 19',
addressPostcodeCity = '1450 København K',
addressPhone = '+45-33 12 88 28')
self.context = self.ContextObject.context
def get(self, request, *args, **kwargs):
return render(request, template_name='index.html', context = self.context)
在我的 apache2 设置中,我有以下代码,其中我已将静态别名指向 productionStatic 中的文件夹。我错过了什么?
<VirtualHost *:80>
# The ServerName directive sets the request scheme, hostname and port that
# the server uses to identify itself. This is used when creating
# redirection URLs. In the context of virtual hosts, the ServerName
# specifies what hostname must appear in the request's Host: header to
# match this virtual host. For the default virtual host (this file) this
# value is not decisive as it is used as a last resort host regardless.
# However, you must set it for any further virtual host explicitly.
#ServerName www.example.com
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual host. For example the
# following line enables the CGI configuration for this host only
# after it has been globally disabled with "a2disconf".
#Include conf-available/serve-cgi-bin.conf
Alias /static /home/jianwu/HD_website/website/productionStatic
<Directory /home/jianwu/HD_website/website/productionStatic>
Require all granted
</Directory>
Alias /media /home/jianwu/HD_website/website/media
<Directory /home/jianwu/HD_website/website/media>
Require all granted
</Directory>
<Directory /home/jianwu/HD_website/website/website>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
WSGIScriptAlias / /home/jianwu/HD_website/website/website/wsgi.py
WSGIDaemonProcess django_app python-path=/home/jianwu/HD_website/website python-home=/home/jianwu/HD_website/website/env
WSGIProcessGroup django_app
</VirtualHost>
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
正如 Ivan Starostin 所评论的那样,应该提供生产环境中文件的绝对路径。在这种情况下,也可以按照评论中的建议使用反向 url。