from django.contrib.admin import AdminSite, ModelAdmin, site, TabularInline from django.db import models from .schema import get_schemas, schemas_update_subscribe from models import (Schema, View, ViewMember, Attribute, Principal, Predicate, Relation, AttributeValue, PrincipalUser) class DirectoryAdmin(AdminSite): def __init__(self, *args, **kwargs): super(DirectoryAdmin, self).__init__(*args, **kwargs) self.directory_proxy_models = [] self.regenerate_proxy_models() schemas_update_subscribe(id(self), self.regenerate_proxy_models) def make_accessor(self, attribute): def accessor(self, principal): values = principal.attributes.filter(attribute=attribute) if attribute.multivalued: return ', '.join(values.values_list('text_value', flat=True)) else: if values: return values[0].text_value else: return '' accessor.__name__ = str(attribute.name) accessor.short_description = unicode(attribute) return accessor def make_proxy(self, schema, name, model): class Meta: proxy = True verbose_name = unicode(schema) return type(name, (model,), dict(Meta=Meta, __module__=__name__)) def make_model_admin(self, model_admin_name, schema): model_admin = None def queryset(self, request): qs = super(model_admin, self).queryset(request) qs = qs.filter(schema=schema) qs.prefetch_related('attributes', 'child_relations', 'parent_relations') return qs model_admin = type(model_admin_name, (ModelAdmin,), dict(queryset=queryset)) return model_admin def regenerate_proxy_models(self): print 'regenerating proxy models' for proxy_model, proxy_model_admin in self.directory_proxy_models: self.unregister(proxy_model) self.directory_proxy_models = [] for schema in get_schemas(): prefix = str(schema.name.capitalize()) name = '%sPrincipalProxy' % prefix model_admin_name = '%sPrincipalModelAdmin' % prefix proxy = self.make_proxy(schema, name, Principal) model_admin = self.make_model_admin(model_admin_name, schema) list_display = [] if schema.views.all()[:1]: view = schema.views.all()[0] qs = view.viewmember_set.order_by('order')[:5] print qs for i, viewmember in enumerate(qs): attribute = viewmember.attribute name = str(attribute.name) print 'setattre', model_admin, name setattr(model_admin, name, self.make_accessor(attribute)) list_display.append(name) print 'setting list display', list_display, 'for', proxy self.register(proxy, model_admin, list_display=list_display) self.directory_proxy_models.append((proxy, model_admin)) site = DirectoryAdmin() class AttributeValueInlineAdmin(TabularInline): model = AttributeValue class PrincipalModelAdmin(ModelAdmin): inlines = [ AttributeValueInlineAdmin ] class ViewMemberInlineAdmin(TabularInline): model = ViewMember class ViewModelAdmin(ModelAdmin): inlines = [ ViewMemberInlineAdmin] for model in (Schema, Attribute, Predicate, Relation, AttributeValue, PrincipalUser): site.register(model) site.register(Principal, PrincipalModelAdmin) site.register(View, ViewModelAdmin)