Changes between Initial Version and Version 1 of CookBookCategoryDataModel


Ignore:
Timestamp:
Aug 5, 2005, 5:21:14 AM (19 years ago)
Author:
oubiwann
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • CookBookCategoryDataModel

    v1 v1  
     1= CookBook - Data Modela =
     2
     3== Description ==
     4I 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 display as 'Development :: Python'. Using that example, other data models/content types that utilize this code will have drop-downs in the admin interface with entires of 'Development' and 'Development :: Python'
     5
     6== Code ==
     7{{{
     8class Category(meta.Model):
     9    verbose_name_plural = 'Categories'
     10    module_name = verbose_name_plural.lower()
     11    fields = (
     12        meta.CharField('category_name', maxlength=50),
     13        meta.CharField('category_parents', maxlength=250, editable=False),
     14        meta.ForeignKey('self', blank=True, null=True,
     15            rel_name='parent', related_name='child'),
     16    )
     17    unique_together = (("category_name", "category_parents"),)
     18
     19    def _recurse_for_parents(self, cat_obj):
     20        p_list = []
     21        if cat_obj.parent_id:
     22            p = cat_obj.get_parent()
     23            p_list.append(p.category_name)
     24            more = self._recurse_for_parents(p)
     25            p_list.extend(more)
     26        if p_list:
     27            p_list.reverse()
     28        return p_list
     29
     30    def get_separator(self):
     31        return ' :: '
     32
     33    def _parents_repr(self):
     34        p_list = self._recurse_for_parents(self)
     35        return self.get_separator().join(p_list)
     36
     37    def __repr__(self):
     38        if self.category_parents:
     39            l = [self.category_parents, self.category_name]
     40            return self.get_separator().join(l)
     41        return self.category_name
     42
     43    def _pre_save(self):
     44        self.category_parents = self._parents_repr()
     45
     46    admin = meta.Admin(
     47        list_display = ('category_name', 'category_parents'),
     48        search_fields = ['category_name', 'category_parents'],
     49    )
     50    ordering = ('category_parents', 'category_name')
     51}}}
     52
     53== API Usage ==
     54Let's fill in some root-level categories:
     55{{{
     56>>> from yourpkg.apps.yourapp.models import yourapp
     57>>> base_cats = [
     58...   {'category_name': 'Development'},
     59...   {'category_name': 'Systems'},
     60...   {'category_name': 'Management'},
     61...   {'category_name': 'Community'},
     62... ]
     63>>> for cat in base_cats:
     64...   new_cat = yourapp.Category(**cat)
     65...   new_cat.save()
     66>>>
     67}}}
     68
     69Now, let's create some sub categories, examining the dict as we go:
     70{{{
     71>>> cat = {'parent_id': 1, 'category_name': 'Python'}
     72>>> new_cat = yourapp.Category(**cat)
     73>>> new_cat.__dict__
     74{'parent_id': 1, 'id': '', 'category_parents': '', 'category_name': 'Python'}
     75>>> new_cat._pre_save()
     76>>> new_cat.__dict__
     77{'_parent_cache': Development, 'parent_id': 1, 'id': '', 'category_parents': 'Development', 'category_name': 'Python'}
     78>>> new_cat.save()
     79>>> new_cat.__dict__
     80{'_parent_cache': Development, 'parent_id': 1, 'id': 5, 'category_parents': 'Development', 'category_name': 'Python'}
     81>>> new_cat
     82Development :: Python
     83}}}
     84
     85
     86Now, let's add a few more and print all the categories:
     87{{{
     88>>> cat = {'parent_id': 2, 'category_name': 'Administration'}
     89>>> yourapp.Category(**cat).save()
     90>>> cat = {'parent_id': 7, 'category_name': 'UNIX'}
     91>>> yourapp.Category(**cat).save()
     92>>> for cat in yourapp.categories.get_list():
     93...   print cat
     94...
     95Community
     96Development
     97Management
     98Systems
     99Development :: Python
     100Systems :: Administration
     101Systems :: Administration :: UNIX
     102}}}
     103== Usage in Other Data Models ==
     104{{{
     105class Document(meta.Model):
     106    fields = (
     107        meta.CharField('title', maxlength=200),
     108        meta.ForeignKey(Category, name='subject', blank=True, null=True),
     109        ...
     110}}}
Back to Top