Django Categories v1.0b1 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 | from categories.models import CategoryBase
class SimpleCategory(CategoryBase):
"""
A simple of catgorizing example
"""
class Meta:
verbose_name_plural = 'simple categories'
|
For the Django admin, create a subclass of CategoryBaseAdminForm. Create an internal class called Meta and assign the attribute model to your model (see line 9 in the example).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | from django.contrib import admin
from categories.admin import CategoryBaseAdmin, CategoryBaseAdminForm
from .models import SimpleCategory
class SimpleCategoryAdminForm(CategoryBaseAdminForm):
class Meta:
model = SimpleCategory
class SimpleCategoryAdmin(CategoryBaseAdmin):
form = SimpleCategoryAdminForm
admin.site.register(SimpleCategory, SimpleCategoryAdmin)
|
Create a subclass of CategoryBaseAdmin and assign form attribute the class created above (see line 12 in the above example).
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 | class Category(CategoryBase):
thumbnail = models.FileField(
upload_to=THUMBNAIL_UPLOAD_PATH,
null=True, blank=True,
storage=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 | 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 | 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 | 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 | 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',),
}),
)
|