Version 2 (modified by ttate@…, 9 years ago) (diff)


CookBook - Data Model

A "category" Data Model


I like to have parent/child categories for my documents and weblog entries. I also am a fan of simplicity. This recipe lets you create new categories, and children of categories while providing an intuitively obvious presentation to the user. A parent category of 'Development' with a child category of 'Python' will be displayed as 'Development :: Python'. Using that example, other data models/content types that utilize this code will have drop-downs in the admin interface with entries of 'Development' and 'Development :: Python'


class Category(models.Model):
        name = models.CharField(core=True, maxlength=200)
        slug = models.SlugField(prepopulate_from=('name',))
        parent = models.ForeignKey('self', blank=True, null=True, related_name='child')
        description = models.TextField(blank=True,help_text="Optional")
        class Admin:
                list_display = ('name', '_parents_repr')
        def __str__(self):
                p_list = self._recurse_for_parents(self)
                return self.get_separator().join(p_list)
        def get_absolute_url(self):
                if self.parent_id:
                        return "/tag/%s/%s/" % (self.parent.slug, self.slug)
                        return "/tag/%s/" % (self.slug)
        def _recurse_for_parents(self, cat_obj):
                p_list = []
                if cat_obj.parent_id:
                        p = cat_obj.parent
                        more = self._recurse_for_parents(p)
                if cat_obj == self and p_list:
                return p_list
        def get_separator(self):
                return ' :: '
        def _parents_repr(self):
                p_list = self._recurse_for_parents(self)
                return self.get_separator().join(p_list)
        _parents_repr.short_description = "Tag parents"
        def save(self):
                p_list = self._recurse_for_parents(self)
                if in p_list:
                        raise validators.ValidationError("You must not save a category in itself!")
                super(Category, self).save()

See Also

Attachments (1)

Download all attachments as: .zip

Back to Top