Django Alphabet Filter Released with International Character Support <a href=_http_/www.flickr.com/photos/moirabot/219779055/__Moira/index.html Clunie</a>
Photo by Moira Clunie

Django Alphabet Filter Released With International Character Support

by Corey Oordt •  Published 28 Jul 2010

My previous post about the alphabet filter explained the first take at creating the alphabet filter. There were several issues, especially with international character sets, so we have revised the code to fix the issues and made it installable via PyPI.

The Default Alphabet

The default alphabet is the list of characters displayed in the admin even if there is no data for that character. As there is data, the letters of the alphabet are enabled. Any characters not in the default alphabet, but that exist in the data, are added dynamically.

There is no easy way to determine what the default alphabet should be based on the language or locale. We hit several barriers while automating the default alphabet:

  1. The default character encoding (on a Mac and in English, at least) is ISO-8859-1, but Django tries to interpret it as UTF-8.

  2. The default character set includes too many characters.

  3. Some languages (I’m looking at you, Spanish) treat certain two-letter combinations as letters (e.g. ch and ll).

Due to these issues, the default alphabet is now a setting named DEFAULT_ALPHABET . The default setting is the ASCII alphabet and digits. You can set the DEFAULT_ALPHABET to a string or list or tuple.

If you only what the ASCII characters, no digits:

DEFAULT_ALPHABET = u'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

For the German alphabet:

DEFAULT_ALPHABET = u'0123456789A\xc4BCDEFGHIJKLMNO\xd6PQRS\xdfTU\xdcVWXYZ'

For the Icelandic alphabet:

DEFAULT_ALPHABET = u'0123456789A\xc1BD\xd0E\xc9FGHI\xcdJKLMNO\xd3PRSTU\xdaVXY\xdd\xde\xd6'

The ordering of the alphabet will not stay the same as entered, it is sorted through Python’s list sort method.

Using Alphabet Filter on a Model

You need to do two things to make it work on a model

  1. Add an alphabet_filter setting in the ModelAdmin.
  2. Create a custom template.

The first step is easy: in the model’s admin.py set alphabet_filter to the name of a character field. For example:

class TagAdmin(admin.ModelAdmin):
    alphabet_filter = 'name'

You also have to create a template for the model (or application) that will override the admin’s change_list.html template.

Within your project’s template directory, you need to create an admin directory, and a directory with the name of the application, and optionally the name of the model. For example, if you were adding the filter on the Tag model of an application named cooltags, the directory structure would look like::

MyProject
    templates
        admin
            cooltags
                tag

Create a document named change_list.html and put it in either the application (templates/admin/cooltags) directory, to have it work for every model within that application or put it in the model directory (templates/admin/cooltags/tag) to have it work only for that model.

The change_list.html document should only contain one line:

{% extends "alphafilter/change_list.html" %}

You cannot place this template in the admin directory, as it leads to an infinite loop of inheritance. The alphafilter’s change_list.html template extends Django’s change_list.html template. Django always looks for overridden templates first, so it would find your template, which extends alphafilter/change_list.html, which extends admin/change_list.html and it finds your template again.

There are no side effects of using this ModelAdmin setting without the special template, or using the special admin template without the setting in the ModelAdmin. Either way, you just won’t see the alphabet filter.

blog comments powered by Disqus