- May 7, 2011
- middleware django redirect
- 2 (after 4 ratings)
Simple piece of middleware that redirects all requests to settings.FIRSTRUN_APP_PATH, until a lockfile is created.
Tested on 1.3 only, but I do not believe it requires any special functionality beyond that provided in 1.1
This is useful if you need to force a user to run an installer, or do some configuration before your project can function fully.
At first glance, such a thing would generate a lot of hits on the disk. However, once the lockfile has been created, the middleware unloads itself, so when a project is in a production environment, the lockfile is only checked once per process invocation (with passenger or mod_wsgi, that's not very often at all).
Once your user has completed your FirstRun app, simply create the lockfile and the project will function as normal.
For it to function, the following settings must be configured:
- settings.PROJECT_PATH - absolute path to project on disk (e.g. /var/www/project/)
- settings.FIRSTRUN_LOCKFILE - relative path of the lockfile (e.g. /.lockfile)
- settings.FIRSTRUN_APP_ROOT - relative URL of the App you want to FirstRun (eg./firstrun/)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
from django.conf import settings from django.core.files.storage import FileSystemStorage from django.shortcuts import redirect import django.core.exceptions import logging import re import os # Check for the existance of a lockfile. If the lockfile doesn't exist, deny access to everywhere except settings.FIRSTRUN_APP_ROOT # If the lockfile exists, throw django.core.exceptions.MiddlewareNotUsed() so that this class is unloaded class FirstRunMiddleware: def __init__(self): if not self.is_first_run(): logging.debug('FirstRunMiddleware: FirstRun not required, unloading for process lifetime.') raise django.core.exceptions.MiddlewareNotUsed() self.p = re.compile(''.join(['^', settings.FIRSTRUN_APP_ROOT])) def process_request(self, request): if self.p.match(request.path) == None: if self.is_first_run(): logging.debug(''.join(['FirstRunMiddleware: Denying access to ', request.path, ' FirstRun needed.'])); return redirect(settings.FIRSTRUN_APP_ROOT) else: # Will only be executed between the time firstrun has been completed, until the process is regenerated (typically on the scale of mins). logging.debug('FirstRunMiddleware: FirstRun completed, resuming normal flow.') def is_first_run(self): return not os.path.exists(''.join([settings.PROJECT_PATH, settings.FIRSTRUN_LOCKFILE]))