django-categories/categories/admin.py
2009-07-02 20:23:08 -04:00

99 lines
3.8 KiB
Python

from ellington.categories.models import Hierarchy, Category, Alias
from django.contrib import admin
from django import forms
from ellington.core.forms import RequiredModelForm
class CategoryAdminForm(RequiredModelForm):
required_if_other_not_given = {
'hierarchy': 'parent',
'parent': 'hierarchy',
}
class Meta:
model = Category
def clean_name(self):
if '/' in self.cleaned_data['name']:
raise forms.ValidationError, "A category name can't contain slashes."
return self.cleaned_data['name']
def clean(self):
super(CategoryAdminForm, self).clean()
if 'slug' in self.cleaned_data and 'parent' in self.cleaned_data and 'hierarchy' in self.cleaned_data:
if self.cleaned_data['parent'] is not None:
# inherit from parent
self.cleaned_data['hierarchy'] = self.cleaned_data['parent'].hierarchy
#Validate slug
kwargs = {}
if self.cleaned_data.get('hierarchy', False):
kwargs['hierarchy__pk'] = int(self.cleaned_data['hierarchy'].id)
kwargs['parent__isnull'] = True
else:
kwargs['parent__pk'] = int(self.cleaned_data['parent'].id)
this_level_slugs = [c.slug for c in Category.objects.filter(**kwargs) if c.id != self.cleaned_data.get("id", None)]
if self.cleaned_data['slug'] in this_level_slugs:
raise forms.ValidationError("A category slug must be unique among categories at its level.")
#Validate Category Parent
"Makes sure the category doesn't set itself or any of its children as its parent."
if not self.cleaned_data['parent']:
return self.cleaned_data
p_data = int(self.cleaned_data['parent'].pk)
h_data = self.cleaned_data.get('hierarchy', False)
if h_data:
h_data = int(h_data.pk)
if p_data and h_data:
p = Category.objects.get(pk=p_data)
if p.hierarchy_id != h_data:
raise forms.ValidationError("This parent is not within the selected hierarchy.")
# Check that the parent isn't a child of this category
# Requires that we look up "this" object; if it doesn't exist
# we can assume we're at the add stage and return
this_id = self.cleaned_data.get("id", None)
if not this_id:
return self.cleaned_data
try:
selected_parent = Category.objects.get(pk=p_data)
except Category.DoesNotExist:
return self.cleaned_data
if selected_parent.id == this_id:
raise forms.ValidationError("A category can't be its own parent.")
try:
this_category = Category.objects.get(pk=p_data)
except Category.DoesNotExist:
return self.cleaned_data
for c in this_category.get_all_children():
if c.id == this_id:
raise forms.ValidationError("A category can't set a child category to be its own parent.")
return self.cleaned_data
else:
raise forms.ValidationError("Cannot clean data")
class CategoryAdmin(admin.ModelAdmin):
form=CategoryAdminForm
fields = ('hierarchy', 'parent', 'name', 'slug')
list_display = ('__unicode__',)
list_filter = ('hierarchy',)
search_fields = ('name', 'path')
prepopulated_fields = {'slug': ('name',)}
class HierarchyAdmin(admin.ModelAdmin):
prepopulated_fields = {'slug': ('name',)}
class AliasAdmin(admin.ModelAdmin):
list_display = ['category', 'parent']
search_fields = ['category__name', 'parent__name']
admin.site.register(Category, CategoryAdmin)
admin.site.register(Hierarchy, HierarchyAdmin)
admin.site.register(Alias, AliasAdmin)