In the django project settings there is a key called MIDDLEWARE_CLASSES which is a tuple of strings implementing the middleware methods. Django base handler (TBD explain what this class does) reads this setting and initializes three of its own attributes: _request_middleware, _view_middleware and _response_middleware. It goes through the list of middleware classes instantiates each of them and adds the bound method process_request to the _request_middleware attribute, process_view method to view_middleware and process_reponse method to _response middleware.
If the middleware class method returns something (indicating that it has taken some action), the basehandler get_response method returns immediately. Otherwise it proceeds further.
There are 4 middleware classes built in:
- AdminUserRequired middleware class implements the process_view method and silently returns if the user in the request is logged in and is a valid admin user. Otherwise it returns login page with appropriate error message.
- CommonMiddleware implements process_view and process_response methods. process_view rejects forbidden user-agents and prepends URL with www and appends trailing slash if desired. process_response checks if there is a matching flat file present that can be sent for 404's and can also send email note to managers about broken links. process_response also manages ETags
- CacheMiddleware implements process_request to check pages (not containing any query string) against cache. process_response adds pages to cache as needed.
- XViewMiddleware (used internally for documentation) implements process_view and attaches 'X-View' header to internal HEAD requests.
Update: 10/14/2005. There are some updates to the middleware that ships with django and is now "officially" documented here.
Django framework has used some design patterns. There is a directory called decorator which currently has two decorators: (decorator is just a method which dynamically adds additional functionality to original method depending on the situation)
funcA = login_required(funcA)
This replaces the funcA with a function which checks if the user is logged in and calls original function if the user is indeed logged in and redirects the anonymous users to login page.
The original function is changed to look into the cached pages.
I was just about to abandon python and join the ruby camp to be able to use the wonderful rails framework for web application development. (They do have very good documentation and impressive video demo which you should check out!) But then came the announcement of Django. I really like the python language and feel that I can understand someone else's python code, (though ruby looks equally fascinating). I read through the tutorials and checked out the svn repository and worked with the tutorials. This framework looks easy to use and seemingly makes your application portable enough to use any of the underlying database backends (postgresql, mysql, sqlite) and webservers (apache, lighthttpd, twistedweb etc). The initial few days after the announcement, there were very hectic updates on the code and documentation front (with support for sqlite backend , standalone server and new tutorial and documentation about generic views and form fields coming in a matter of a couple of days). This has now gradually slowed down.
I decided to write a sample application (rebate tracking) and immediately hit some issues. I am trying to make the user registration and login/logout part work, but am not following how that is hooked into the framework. The users added with admin interface do not get recognized by the authentication code. Tried IRC help, but haven't been able to get anyone who can help. I am studying the code right now. I am going to look closely into the decorator and middleware code now. I will write about my progress here.