From: Joseph Spiros Date: Thu, 17 Jun 2010 09:34:22 +0000 (-0400) Subject: Merge branch 'master' into penfield X-Git-Tag: philo-0.9~67^2~11 X-Git-Url: http://git.ithinksw.org/philo.git/commitdiff_plain/6d2c7644b56ed2ecc5e274819322e077e0975fa9?hp=77910c8b4d5e1661e53f2a0500fa23654b677c4a Merge branch 'master' into penfield --- diff --git a/admin.py b/admin.py index 178a904..64893d5 100644 --- a/admin.py +++ b/admin.py @@ -8,6 +8,11 @@ from django.utils.safestring import mark_safe from django.utils.html import escape from django.utils.text import truncate_words from philo.models import * +from django.core.exceptions import ValidationError, ObjectDoesNotExist +from validators import TreeParentValidator, TreePositionValidator + + +COLLAPSE_CLASSES = ('collapse', 'collapse-closed', 'closed',) class AttributeInline(generic.GenericTabularInline): @@ -37,12 +42,14 @@ class CollectionMemberInline(admin.TabularInline): fk_name = 'collection' model = CollectionMember extra = 1 - classes = ('collapse-closed',) + classes = COLLAPSE_CLASSES allow_add = True + fields = ('member_content_type', 'member_object_id', 'index',) class CollectionAdmin(admin.ModelAdmin): inlines = [CollectionMemberInline] + list_display = ('name', 'description', 'get_count') class NodeAdmin(EntityAdmin): @@ -76,16 +83,77 @@ class ModelLookupWidget(forms.TextInput): return mark_safe(output) +class TreeForm(forms.ModelForm): + def __init__(self, *args, **kwargs): + super(TreeForm, self).__init__(*args, **kwargs) + instance = self.instance + instance_class = self.get_instance_class() + + if instance_class is not None: + try: + self.fields['parent'].queryset = instance_class.objects.exclude(id=instance.id) + except ObjectDoesNotExist: + pass + + self.fields['parent'].validators = [TreeParentValidator(*self.get_validator_args())] + + def get_instance_class(self): + return self.instance.__class__ + + def get_validator_args(self): + return [self.instance] + + def clean(self): + cleaned_data = self.cleaned_data + + try: + parent = cleaned_data['parent'] + slug = cleaned_data['slug'] + obj_class = self.get_instance_class() + tpv = TreePositionValidator(parent, slug, obj_class) + tpv(self.instance) + except KeyError: + pass + + return cleaned_data + + +class NodeForm(TreeForm): + def get_instance_class(self): + return Node + + def get_validator_args(self): + return [self.instance, 'instance'] + + +class PageAdminForm(NodeForm): + class Meta: + model = Page + + +class RedirectAdminForm(NodeForm): + class Meta: + model = Redirect + + +class FileAdminForm(NodeForm): + class Meta: + model = File + + class RedirectAdmin(NodeAdmin): fieldsets = ( (None, { 'fields': ('slug', 'target', 'status_code') }), ('URL/Tree/Hierarchy', { - 'classes': ('collapse', 'collapse-closed'), + 'classes': COLLAPSE_CLASSES, 'fields': ('parent',) }), ) + list_display=('slug', 'target', 'path', 'status_code',) + list_filter=('status_code',) + form = RedirectAdminForm class FileAdmin(NodeAdmin): @@ -95,10 +163,12 @@ class FileAdmin(NodeAdmin): 'fields': ('file', 'slug', 'mimetype') }), ('URL/Tree/Hierarchy', { - 'classes': ('collapse', 'collapse-closed'), + 'classes': COLLAPSE_CLASSES, 'fields': ('parent',) }), ) + form=FileAdminForm + list_display=('slug', 'mimetype', 'path', 'file',) class PageAdmin(NodeAdmin): @@ -109,13 +179,14 @@ class PageAdmin(NodeAdmin): 'fields': ('title', 'slug', 'template') }), ('URL/Tree/Hierarchy', { - 'classes': ('collapse', 'collapse-closed'), + 'classes': COLLAPSE_CLASSES, 'fields': ('parent',) }), ) list_display = ('title', 'path', 'template') list_filter = ('template',) search_fields = ['title', 'slug', 'contentlets__content'] + form = PageAdminForm def get_fieldsets(self, request, obj=None, **kwargs): fieldsets = list(self.fieldsets) @@ -191,19 +262,21 @@ class TemplateAdmin(admin.ModelAdmin): 'fields': ('parent', 'name', 'slug') }), ('Documentation', { - 'classes': ('collapse', 'collapse-closed'), + 'classes': COLLAPSE_CLASSES, 'fields': ('documentation',) }), (None, { 'fields': ('code',) }), ('Advanced', { - 'classes': ('collapse','collapse-closed'), + 'classes': COLLAPSE_CLASSES, 'fields': ('mimetype',) }), ) save_on_top = True save_as = True + list_display = ('__unicode__', 'slug', 'get_path',) + form = TreeForm admin.site.register(Collection, CollectionAdmin) diff --git a/models.py b/models.py index ecd1c1f..39f166c 100644 --- a/models.py +++ b/models.py @@ -101,6 +101,13 @@ class Entity(models.Model): class Collection(models.Model): name = models.CharField(max_length=255) description = models.TextField(blank=True, null=True) + + @fattr(short_description='Members') + def get_count(self): + return self.members.count() + + def __unicode__(self): + return self.name class CollectionMemberManager(models.Manager): @@ -117,6 +124,9 @@ class CollectionMember(models.Model): member_content_type = models.ForeignKey(ContentType, verbose_name='Member type') member_object_id = models.PositiveIntegerField(verbose_name='Member ID') member = generic.GenericForeignKey('member_content_type', 'member_object_id') + + def __unicode__(self): + return u'%s - %s' % (self.collection, self.member) class TreeManager(models.Manager): @@ -235,6 +245,9 @@ class Node(InheritableTreeEntity): def render_to_response(self, request, path=None, subpath=None): return HttpResponseServerError() + + class Meta: + unique_together = (('parent', 'slug'),) class MultiNode(Node): @@ -278,6 +291,9 @@ class File(Node): response = HttpResponse(wrapper, content_type=self.mimetype) response['Content-Length'] = self.file.size return response + + def __unicode__(self): + return self.file class Template(TreeModel): @@ -353,9 +369,7 @@ class Template(TreeModel): class Page(Node): """ - Represents an HTML page. The page will have a number of related Contentlets - depending on the template selected - but these will appear only after the - page has been saved with that template. + Represents a page - something which is rendered according to a template. The page will have a number of related Contentlets depending on the template selected - but these will appear only after the page has been saved with that template. """ template = models.ForeignKey(Template, related_name='pages') title = models.CharField(max_length=255) @@ -376,6 +390,9 @@ class Contentlet(models.Model): name = models.CharField(max_length=255) content = models.TextField() dynamic = models.BooleanField(default=False) + + def __unicode__(self): + return self.name class ContentReference(models.Model): @@ -384,6 +401,9 @@ class ContentReference(models.Model): content_type = models.ForeignKey(ContentType, verbose_name='Content type') content_id = models.PositiveIntegerField(verbose_name='Content ID') content = generic.GenericForeignKey('content_type', 'content_id') + + def __unicode__(self): + return self.name register_templatetags('philo.templatetags.containers') diff --git a/templates/admin/philo/edit_inline/tabular_collapse.html b/templates/admin/philo/edit_inline/tabular_collapse.html index c457297..6aecaf5 100644 --- a/templates/admin/philo/edit_inline/tabular_collapse.html +++ b/templates/admin/philo/edit_inline/tabular_collapse.html @@ -2,7 +2,7 @@