© Julian Moritz, 16.05.2009, JulianMoritz.de: Anleitung für eine settings.py bei AditSystems, mit Anpassungen © 2011
Ich konnte in den letzten Wochen bei dem bisher einzigen deutschen Hoster für Django einige Erfahrungen sammeln, was das Erstellen von Django-Applikationen angeht. Da es anfangs immer wieder zu ärgerlichen Fehlern gekommen ist und das Debuggen durch eine fehlende Konsole nicht gerade erleichtert wird, habe ich diese Anleitung verfasst.
In einer brauchbaren settings.py-Datei sollte natürlich die Prinzipien von Django befolgt werden. Dazu benutze ich nirgends absolute hardkodierte Pfade. Außerdem will man vielleicht mitloggen können, was so passiert, damit man Fehler einfacher analyisieren kann als nur in der error-Logdatei.
Für unser Beispiel nehmen wir die Domain beispiel.de. Die Domain wurde also im Confixx angelegt und es existiert das Verzeichnis /html/beispielde (ich gehe einfach mal von meiner eigenen Namenskonvention aus). In diesem Verzeichnis liegen nun drei Dateien:
RewriteEngine On RewriteBase / RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ /app.wsgi/$1 [QSA,L]
#!/usr/bin/python import sys, os djangopath = '/var/www/USERNAME/files/beispielde' if djangopath not in sys.path: sys.path.insert(0, djangopath) os.environ['DJANGO_SETTINGS_MODULE'] = 'settings' from django.core.handlers.wsgi import WSGIHandler application = WSGIHandler()
wobei USERNAME natürlich mit dem passenden Benutzernamen zu ersetzen ist und die Datei app.wsgi ausführbar gemacht werden muss (chmod 0755).
<h1>Reload app.wsgi</h1> filemtime app.wsgi: <?php echo date("d.m.Y H:i:s", filemtime("app.wsgi"))."<br />\n"; echo "touching <em>app.wsgi</em>..."; touch ("src/app.wsgi"); clearstatcache(); echo "done<br />\n"; echo "neue filemtime: ".date("d.m.Y H:i:s", filemtime("app.wsgi"))."<br />\n"; ?>
Die beiden ersten Dateien sind für das Laufen der Django-Applikation wichtig, die letztere, um zu verhindern, das bei einem Upload von neuen Dateien alte Daten verwendet werden.
Und dann muss in dem Verzeichnis noch ein weiteres Verzeichnis static angelegt werden. Dort werden nun die Inhalte aus dem Verzeichnis hochgeladen, auf das MEDIA_ROOT in der settings.py verweist.
Nun wird im Verzeichnis /files/ das verzeichnis beispielde angelegt und dorthin gewechselt. Dorthin wird nun die komplette Django-Applikation hochgeladen (natürlich außer dem Verzeichnis aus MEDIA_ROOT). Darauf nur noch die URL http://www.beispiel.de/reloadpython.php aufrufen und hoffen, das alles funktioniert.
Und damit alles halbwegs reibungslos funktioniert, hier meine
# Django settings for djangoproject project. import os import logging from logging import config #absolute path to this project PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__)) LOGGING_CONFIG_FILE = os.path.join(PROJECT_ROOT, "logging.cfg") try: config.fileConfig(LOGGING_CONFIG_FILE) except: #rewrite logging config file LOGGING_FILE = open(LOGGING_CONFIG_FILE, "w") LOGGING_TARGET = os.path.join(PROJECT_ROOT, "django.log") LOGGING_CONFIG = """[loggers] keys=root [handlers] keys=hand01,hand02 [formatters] keys=form01 [logger_root] level=DEBUG handlers=hand02 [handler_hand01] class=StreamHandler level=DEBUG formatter=form01 args=(sys.stdout,) [handler_hand02] class=FileHandler level=DEBUG formatter=form01 args=("%(logging_target)s", "a") [formatter_form01] format= %%(levelname)s %%(pathname)s %%(lineno)d %%(asctime)s %%(message)s datefmt= class=logging.Formatter """ % {"logging_target": LOGGING_TARGET} LOGGING_FILE.write(LOGGING_CONFIG) LOGGING_FILE.close() config.fileConfig(LOGGING_CONFIG_FILE) logging.debug("start logging") DEBUG = False TEMPLATE_DEBUG = DEBUG ADMINS = ( # ('Your Name', 'your_email@domain.com'), ) MANAGERS = ADMINS DATABASE_ENGINE = '' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. DATABASE_NAME = '' # Or path to database file if using sqlite3. DATABASE_USER = '' # Not used with sqlite3. DATABASE_PASSWORD = '' # Not used with sqlite3. DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3. DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3. # Local time zone for this installation. Choices can be found here: # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name # although not all choices may be available on all operating systems. # If running in a Windows environment this must be set to the same as your # system time zone. TIME_ZONE = 'Europe/Berlin' # Language code for this installation. All choices can be found here: # http://www.i18nguy.com/unicode/language-identifiers.html LANGUAGE_CODE = 'de' SITE_ID = 1 # If you set this to False, Django will make some optimizations so as not # to load the internationalization machinery. USE_I18N = True # Absolute path to the directory that holds media. # Example: "/home/media/media.lawrence.com/" MEDIA_ROOT = '' # URL that handles the media served from MEDIA_ROOT. Make sure to use a # trailing slash if there is a path component (optional in other cases). # Examples: "http://media.lawrence.com", "http://example.com/media/" MEDIA_URL = '' # URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a # trailing slash. # Examples: "http://foo.com/media/", "/media/". ADMIN_MEDIA_PREFIX = '/media/' # Make this unique, and don't share it with anybody. try: SECRET_KEY except NameError: SECRET_FILE = os.path.abspath(os.path.join(PROJECT_ROOT, "../secret_%s.txt" % os.path.basename(PROJECT_ROOT))) try: SECRET_KEY = open(SECRET_FILE).read().strip() except IOError: try: from random import choice SECRET_KEY = ''.join([choice('abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)') for i in range(50)]) secret = file(SECRET_FILE, 'w') secret.write(SECRET_KEY) secret.close() except IOError: Exception("Please create a file named '%s' with random characters to generate your secret key!" % SECRET_FILE) # List of callables that know how to import templates from various sources. TEMPLATE_LOADERS = ( 'django.template.loaders.filesystem.load_template_source', 'django.template.loaders.app_directories.load_template_source', # 'django.template.loaders.eggs.load_template_source', ) TEMPLATE_CONTEXT_PROCESSORS = ( 'django.core.context_processors.auth', 'django.core.context_processors.debug', 'django.core.context_processors.i18n', 'django.core.context_processors.media', 'django.core.context_processors.request', ) MIDDLEWARE_CLASSES = ( 'django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.middleware.doc.XViewMiddleware', ) ROOT_URLCONF = 'urls' TEMPLATE_DIRS = ( # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". # Always use forward slashes, even on Windows. # Don't forget to use absolute paths, not relative paths. os.path.join(PROJECT_ROOT, "templates"), PROJECT_ROOT, ) INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.admin', 'django.contrib.admindocs', ) #setting for 404 errors SEND_BROKEN_LINK_EMAILS = True #settings for sending emails: EMAIL_HOST = 'mail.beispiel.de' EMAIL_PORT = 25 EMAIL_HOST_USER = 'mars12345' try: EMAIL_FILE = os.path.join(PROJECT_ROOT, "../email_%s.txt" % os.path.basename(PROJECT_ROOT)) EMAIL_HOST_PASSWORD = open(EMAIL_FILE).read().strip() except IOError: logging.error("Please create a file named '%s' with your email host password!" % EMAIL_FILE) raise Exception("Please create a file named '%s' with your email host password!" % EMAIL_FILE) EMAIL_SENDER = 'admin@beispiel.de' # in local_settings.py I put all the local data try: from local_settings import * logging.info("local_settings imported") except ImportError, msg: logging.error("local_settings could not be imported, reason follows") logging.error(str(msg))
Bei mir sieht das wie folgt aus:
from django.conf import settings import os import logging DATABASE_ENGINE = 'sqlite3' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. DATABASE_NAME = os.path.join(settings.PROJECT_ROOT, 'database.sqlite') # Or path to database file if using sqlite3. DATABASE_USER = '' # Not used with sqlite3. DATABASE_PASSWORD = '' # Not used with sqlite3. DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3. DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3. # url to static_content dir with trailing slash! MEDIA_URL = "/static/" #settings for server ADMIN_MEDIA_PREFIX = MEDIA_URL + 'admin_media/' #setting MEDIA_ROOT BASE_NAME = os.path.basename(settings.PROJECT_ROOT) MEDIA_ROOT = os.path.abspath(os.path.join(settings.PROJECT_ROOT, "../../html/", BASE_NAME, MEDIA_URL[1:])) ADMINS = ( ("Max Mustermann", "admin@beispiel.de", ), )