I try to make the Pyramid Single File Tasks Tutorial runs under mod_wsgi, and figure that two changes are needed to make it runs both standalone (http://localhost:6543) and under mod_wsgi (http://localhost/task).
I would like to share these two changes:
[tasks.py]
FROM:
if __name__ == '__main__':
# configuration settings
settings = {}
settings['reload_all'] = True
settings['debug_all'] = True
settings['mako.directories'] = os.path.join(here, 'templates')
settings['db'] = os.path.join(here, 'tasks.db')
# session factory
session_factory = UnencryptedCookieSessionFactoryConfig('itsaseekreet')
# configuration setup
config = Configurator(settings=settings, session_factory=session_factory)
# routes setup
config.add_route('list', '/')
config.add_route('new', '/new')
config.add_route('close', '/close/{id}')
# static view setup
config.add_static_view('static', os.path.join(here, 'static'))
# scan for @view_config and @subscriber decorators
config.scan()
# serve app
app = config.make_wsgi_app()
server = make_server('0.0.0.0', 8080, app)
server.serve_forever()
TO:
def get_app():
# configuration settings
settings = {}
settings['reload_all'] = True
settings['debug_all'] = True
settings['mako.directories'] = os.path.join(here, 'templates')
settings['db'] = os.path.join(here, 'tasks.db')
# session factory
session_factory = UnencryptedCookieSessionFactoryConfig('itsaseekreet')
# configuration setup
config = Configurator(settings=settings, session_factory=session_factory)
# routes setup
config.add_route('list', '/')
config.add_route('new', '/new')
config.add_route('close', '/close/{id}')
# static view setup
config.add_static_view('static', os.path.join(here, 'static'))
# scan for @view_config and @subscriber decorators
config.scan()
# serve app
app = config.make_wsgi_app()
return app
application = get_app()
if __name__ == '__main__':
server = make_server('0.0.0.0', 8080, application)
server.serve_forever()
[templates/layout.mako]
FROM:
<link rel="shortcut icon" href="/static/favicon.ico">
<link rel="stylesheet" href="/static/style.css">
TO:
<link rel="shortcut icon" href="${request.application_url}/static/favicon.ico">
<link rel="stylesheet" href="${request.application_url}/static/style.css">
I am using Debian 6, and the following is the relevant section in /etc/apache2/mods-enabled/wsgi.conf, where task.wsgi is a symbolic link to task.py in the same directory.
WSGIApplicationGroup %{GLOBAL}
WSGIPassAuthorization On
WSGIDaemonProcess pyramid user=david group=david threads=4 \
python-path=/home/david/tasks/env/lib/python2.6/site-packages
WSGIScriptAlias /task /home/david/tasks/env/task/task.wsgi
<Directory /home/david/tasks/env>
WSGIProcessGroup pyramid
Order allow,deny
Allow from all
</Directory>
[end]
2014-08-25
Django logging setting, part 2
This is a follow up to the Django logging setting post in 2013.
This time, it makes use of the hierarchical nature of the logging system, removing the need to define a separate section for each app in the settings file. Notice the dot after the <project_name> in U_LOGGER_ROOT.
=== settings.py === U_LOGFILE_NAME = r'/path/to/log.txt' U_LOGFILE_SIZE = 1 * 1024 * 1024 U_LOGFILE_COUNT = 2 U_LOGGER_ROOT = '<project_name>.' LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'standard': { 'format' : "[%(asctime)s] %(levelname)s [%(name)s:%(lineno)s] %(message)s", }, }, 'filters': { 'require_debug_false': { '()': 'django.utils.log.RequireDebugFalse' } }, 'handlers': { 'logfile': { 'level':'DEBUG', 'class':'logging.handlers.RotatingFileHandler', 'filename': U_LOGFILE_NAME, 'maxBytes': U_LOGFILE_SIZE, 'backupCount': U_LOGFILE_COUNT, 'formatter': 'standard', }, }, 'loggers': { U_LOGGER_ROOT.rstrip('.'): { 'handlers': ['logfile'], 'level': 'DEBUG', 'propagate': True, }, } } === in any app module === import logging fromimport settings logger = logging.getLogger(settings.U_LOGGER_ROOT + __name__) logger.info('some useful information')
2014-08-19
Showing the description of a choice in a Django template
Sometimes you would like to show the description of a choice instead of its code in a Django template. One way to achieve that is to define a property in the model and referencing it in a template as below:
{{ object.status_desc }}
=== models.py === from django.db.models import IntegerField, CharField, Model class Invoice(Model): STATUS_TYPE = ( ('A', 'Active'), ('I', 'Inactive'), ) invoice_no = IntegerField() status = CharField(max_length=1, choices=STATUS_TYPE, default='A') @property def status_desc(self): return dict(self.STATUS_TYPE)[self.status]
EDITED 2015-07-13 Turn out there is a django function for this purpose: Model.get_FOO_display()
2014-08-16
Django File Upload
The following is a minimalistic but complete example of handling file upload in Django 1.6.
=== forms.py === from django import forms class UploadFileForm(forms.Form): file = forms.FileField() === views.py === import os.path from django.http import HttpResponse from django.shortcuts import render from .forms import UploadFileForm def home(request): if request.method == 'POST': form = UploadFileForm(request.POST, request.FILES) if form.is_valid(): handle_uploaded_file(request.FILES['file']) return HttpResponse("Upload Successful.") else: form = UploadFileForm() return render(request, 'home.html', {'form': form}) def handle_uploaded_file(f): with open(os.path.join('/path/to/', f.name), 'wb+') as destination: for chunk in f.chunks(): destination.write(chunk) === home.html ===<html> <body> <form action="" method="post" {% if form.is_multipart %}enctype="multipart/form-data"{% endif %}> {{ form.as_p }} {% csrf_token %} <input type="submit" value="Submit" /> </form> </body> </html>
Subscribe to:
Posts (Atom)