Django Categories 1.6 documentation
Django Categories isn’t just for using a single category model. It allows you to create your own custom category-like models with as little or much customization as you need.
For many cases, you want a simple user-managed lookup table. You can do this with just a little bit of code. The resulting model will include name, slug and active fields and a hierarchical admin.
Create a model that subclasses CategoryBase
1 2 3 4 5 6 7 8 9 10 | from categories.models import CategoryBase
class SimpleCategory(CategoryBase):
"""
A simple of catgorizing example
"""
class Meta:
verbose_name_plural = 'simple categories'
|
Create a subclass of CategoryBaseAdmin.
1 2 3 4 5 6 7 8 9 10 11 12 | from django.contrib import admin
from categories.admin import CategoryBaseAdmin
from .models import SimpleCategory
class SimpleCategoryAdmin(CategoryBaseAdmin):
pass
admin.site.register(SimpleCategory, SimpleCategoryAdmin)
|
Register your model and custom model admin class.
Sometimes you need more functionality, such as extra metadata and custom functions. The Category
model in this package does this.
Create a model that subclasses CategoryBase
as above.
Add new fields to the model. The Category
model adds these extra fields.
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 33 | from categories import models, settings
from categories.base import CategoryBase
class Category(CategoryBase):
thumbnail = models.FileField(
upload_to=settings.THUMBNAIL_UPLOAD_PATH,
null=True, blank=True,
storage=settings.THUMBNAIL_STORAGE,)
thumbnail_width = models.IntegerField(blank=True, null=True)
thumbnail_height = models.IntegerField(blank=True, null=True)
order = models.IntegerField(default=0)
alternate_title = models.CharField(
blank=True,
default="",
max_length=100,
help_text="An alternative title to use on pages with this category.")
alternate_url = models.CharField(
blank=True,
max_length=200,
help_text="An alternative URL to use instead of the one derived from "
"the category hierarchy.")
description = models.TextField(blank=True, null=True)
meta_keywords = models.CharField(
blank=True,
default="",
max_length=255,
help_text="Comma-separated keywords for search engines.")
meta_extra = models.TextField(
blank=True,
default="",
help_text="(Advanced) Any additional HTML to be placed verbatim "
"in the <head>")
|
Add new methods to the model. For example, the Category
model adds several new methods, including overriding the save()
method.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | from categories.models import Category
def save(self, *args, **kwargs):
if self.thumbnail:
from django.core.files.images import get_image_dimensions
import django
if django.VERSION[1] < 2:
width, height = get_image_dimensions(self.thumbnail.file)
else:
width, height = get_image_dimensions(self.thumbnail.file, close=True)
else:
width, height = None, None
self.thumbnail_width = width
self.thumbnail_height = height
super(Category, self).save(*args, **kwargs)
|
Alter Meta
or MPTTMeta
class. Either of these inner classes can be overridden, however your Meta
class should inherit CategoryBase.Meta
. Options for Meta
are in the Django-MPTT docs.
1 2 3 4 5 6 7 8 9 | from categories.base import CategoryBase
class Meta(CategoryBase.Meta):
verbose_name_plural = 'categories'
class MPTTMeta:
order_insertion_by = ('order', 'name')
|
For the admin, you must create a form that subclasses CategoryBaseAdminForm
and at least sets the Meta.model
attribute. You can also alter the form fields and cleaning methods, as Category
does.
1 2 3 4 5 6 7 8 9 10 11 12 13 | from categories.base import CategoryBaseAdminForm
from categories.models import Category
class CategoryAdminForm(CategoryBaseAdminForm):
class Meta:
model = Category
def clean_alternate_title(self):
if self.instance is None or not self.cleaned_data['alternate_title']:
return self.cleaned_data['name']
else:
return self.cleaned_data['alternate_title']
|
Next you must subclass CategoryBaseAdmin
and assign the form
attribute the form class created above. You can alter any other attributes as necessary.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | from categories.admin import CategoryAdminForm
from categories.base import CategoryBaseAdmin
class CategoryAdmin(CategoryBaseAdmin):
form = CategoryAdminForm
list_display = ('name', 'alternate_title', 'active')
fieldsets = (
(None, {
'fields': ('parent', 'name', 'thumbnail', 'active')
}),
('Meta Data', {
'fields': ('alternate_title', 'alternate_url', 'description',
'meta_keywords', 'meta_extra'),
'classes': ('collapse',),
}),
('Advanced', {
'fields': ('order', 'slug'),
'classes': ('collapse',),
}),
)
|