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:
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.
The default character set includes too many characters.
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
- Add an
alphabet_filter
setting in theModelAdmin
. - 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