Pages

Thursday, March 24, 2011

Custom Template Loaders in Django

Django’s built-in template loaders (described in the “Inside Template Loading” section above) will usually cover all your template-loading needs, but it’s pretty easy to write your own if you need special loading logic. For example, you could load templates from a database, or directly from a Subversion repository using Subversion’s Python bindings, or (as shown shortly) from a ZIP archive.

A template loader—that is, each entry in the TEMPLATE_LOADERS setting —is expected to be a callable with this interface:

load_template_source(template_name, template_dirs=None)

The template_name argument is the name of the template to load (as passed to loader.get_template() orloader.select_template()), and template_dirs is an optional list of directories to search instead ofTEMPLATE_DIRS.

If a loader is able to successfully load a template, it should return a tuple:(template_source, template_path). Here, template_source is the template string that will be compiled by the template engine, and template_path is the path the template was loaded from. That path might be shown to the user for debugging purposes, so it should quickly identify where the template was loaded from.

If the loader is unable to load a template, it should raise django.template.TemplateDoesNotExist.
Each loader function should also have an is_usable function attribute. This is a Boolean that informs the template engine whether this loader is available in the current Python installation. For example, the eggs loader (which is capable of loading templates from Python eggs) sets is_usable to False if thepkg_resources module isn’t installed, because pkg_resources is necessary to read data from eggs.
An example should help clarify all of this. Here’s a template loader function that can load templates from a ZIP file. It uses a custom setting, TEMPLATE_ZIP_FILES, as a search path instead of TEMPLATE_DIRS, and it expects each item on that path to be a ZIP file containing templates:

import zipfile
from django.conf import settings
from django.template import TemplateDoesNotExist

def load_template_source(template_name, template_dirs=None):
"""Template loader that loads templates from a ZIP file."""

template_zipfiles = getattr(settings, "TEMPLATE_ZIP_FILES", [])

# Try each ZIP file in TEMPLATE_ZIP_FILES.
for fname in template_zipfiles:
try:
z = zipfile.ZipFile(fname)
source = z.read(template_name)
except (IOError, KeyError):
continue
z.close()
# We found a template, so return the source.
template_path = "%s:%s" % (fname, template_name)
return (source, template_path)

# If we reach here, the template couldn't be loaded
raise TemplateDoesNotExist(template_name)

# This loader is always usable (since zipfile is included with Python)
load_template_source.is_usable = True

The only step left if we want to use this loader is to add it to the TEMPLATE_LOADERS setting. If we put this code in a package called mysite.zip_loader, then we add mysite.zip_loader.load_template_source toTEMPLATE_LOADERS.

Tuesday, March 22, 2011

Hash Map class for stdext

Here’s a hash map derived class that works

typedef vector<char> Key;
typedef list<vector<char> > Element;
class my_hash_compare: public stdext::hash_compare<Key>{
public:
    bool operator( )( const Key& _Key1,const Key& _Key2 ) const
    {
        // add your own logic to compare _Key1 and _Key2
        return true; // return the result of compare
    }
};
//template<class T, class S>
class Mymap: public stdext::hash_map <Key, Element, my_hash_compare>
{
};

or
Code Block
typedef vector<char> Key;
typedef list<vector<char> > Element;
struct myLess: public less<Key>
{
    bool operator()(const Key& _Left, const Key& _Right) const
    {
        //your own logic to compare _Left and _Right
        return true; // return the result of compare
    }
};
//template<class T, class S>
class Mymap: public stdext::hash_map <Key, Element, hash_compare<Key,myLess> >
{
};

Thursday, March 17, 2011

Evaluating The DBQ Formulae

Our algorithm for evaluating DBQ formulae will not actually provide truth values directly for a formula, but will produce a set of substitutions reflecting possible values for variables appearing in the formula that yield true propositions. It is simplest to see this for formulae of the first type (involving simple predicates). Imagine that we have a database about car parts which includes information about which firms supply which parts. We will assume that a relation supplies is represented in the database by a long list of entries specifying exhaustively who supplies what, as follows:
Who            What

smith_corp     radiators

jones_inc      spark_plugs

morgan_bros    radiators

jones_inc      batteries

smith_corp     tyres

morgan_bros    pumps

Questions about this relation can be phrased in DBQ by using the predicate supplies. We will use the first (arg0) argument position associated with supplies to indicate the supplying firm and the second (arg1) position to indicate the type of part. Then, the following are possible DBQ formulae involving this relation:

(supplies _x radiators)

(supplies _x _y)
The result of evaluating the first of these formulae will be the set of possible values for _x which would result in the formula matching something in the database. So what we get is:
(((_x smith_corp))

((_x morgan_bros)))
The result of evaluating the second of the formulae will be the set of pairs of values for _x and _y that result in the formula matching something in the database.

Friday, March 11, 2011

Database Caching in Django

To use a database table as your cache back-end, create a cache table in your database and point Django’s cache system at that table.

First, create a cache table by running this command:

python manage.py createcachetable [cache_table_name]

where [cache_table_name] is the name of the database table to create. This name can be whatever you want, as long as it’s a valid table name that’s not already being used in your database. This command creates a single table in your database that is in the proper format Django’s database-cache system expects.

Once you’ve created that database table, set your CACHE_BACKEND setting to "db://tablename", wheretablename is the name of the database table. In this example, the cache table’s name is my_cache_table:

CACHE_BACKEND = 'db://my_cache_table'

The database caching back-end uses the same database as specified in your settings file. You can’t use a different database back-end for your cache table.