Ticket #6776: 6776_modeladmin_fix.1.diff

File 6776_modeladmin_fix.1.diff, 4.1 KB (added by Brian Rosner, 16 years ago)

initial cut for patching this. needs alot more work, but this is a proof of concept for the final patch.

  • new file django/contrib/admin/loading.py

    diff --git a/django/contrib/admin/loading.py b/django/contrib/admin/loading.py
    new file mode 100644
    index 0000000..2a23843
    - +  
     1
     2class ModelAdminCache(object):
     3   
     4    __shared_state = dict(
     5        modeladmin_store = {},
     6    )
     7   
     8    def __init__(self):
     9        self.__dict__ = self.__shared_state
     10       
     11    def get(self, key):
     12        return self.modeladmin_store[key]
     13   
     14    def register(self, *admin_classes):
     15        for admin_class in admin_classes:
     16            key = ".".join(admin_class.__module__.split(".")[-2:] + [admin_class.__name__])
     17            # print "ModelAdminCache registering %s (%s)" % (key, id(admin_class))
     18            if key in self.modeladmin_store:
     19                continue
     20            self.modeladmin_store[key] = admin_class
     21
     22admin_class_cache = ModelAdminCache()
  • django/contrib/admin/options.py

    diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
    index d0cca0a..d5358af 100644
    a b from django.newforms.formsets import all_valid  
    44from django.newforms.models import _modelform_factory, _inlineformset_factory
    55from django.contrib.contenttypes.models import ContentType
    66from django.contrib.admin import widgets
     7from django.contrib.admin.loading import admin_class_cache
    78from django.contrib.admin.util import get_deleted_objects
    89from django.core.exceptions import ImproperlyConfigured, PermissionDenied
    910from django.db import models, transaction
    class AdminField(object):  
    124125        attrs = classes and {'class': u' '.join(classes)} or {}
    125126        return self.field.label_tag(contents=contents, attrs=attrs)
    126127
     128class ModelAdminMetaclass(type):
     129    def __new__(cls, name, bases, attrs):
     130        new_class = forms.MediaDefiningClass.__new__(cls, name, bases, attrs)
     131        try:
     132            parents = [b for b in bases if issubclass(b, ModelAdmin)]
     133            if not parents:
     134                return new_class
     135        except NameError:
     136            return new_class
     137        # new_class = type.__new__(cls, name, bases, attrs)
     138        # put this in some sort of registry
     139        # print "ModelAdminMetaclass called (name=%s, module=%s, new_class=%s)" % (name, new_class.__module__, id(new_class))
     140        admin_class_cache.register(new_class)
     141        # due to the way imports happening only use the admin class that is
     142        # already registered.
     143        return admin_class_cache.get(".".join(new_class.__module__.split(".")[-2:] + [new_class.__name__]))
     144
    127145class BaseModelAdmin(object):
    128146    """Functionality common to both ModelAdmin and InlineAdmin."""
    129147    raw_id_fields = ()
    class BaseModelAdmin(object):  
    200218
    201219class ModelAdmin(BaseModelAdmin):
    202220    "Encapsulates all admin options and functionality for a given model."
    203     __metaclass__ = forms.MediaDefiningClass
     221    __metaclass__ = ModelAdminMetaclass
    204222
    205223    list_display = ('__str__',)
    206224    list_display_links = ()
  • django/contrib/admin/sites.py

    diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py
    index 6c6f47e..610f5e7 100644
    a b class AdminSite(object):  
    7676        if isinstance(model_or_iterable, ModelBase):
    7777            model_or_iterable = [model_or_iterable]
    7878        for model in model_or_iterable:
    79             if model in self._registry:
    80                 raise AlreadyRegistered('The model %s is already registered' % model.__name__)
     79            # print "registering %r (model=%s, admin_class=%s, in_registry=%s, self=%s)" % (model, id(model), id(admin_class), model in self._registry, id(self))
     80            if model in self._registry and self._registry[model].__class__ is not admin_class:
     81                # print "MAYDAY!! (%s is not %s)" % (id(self._registry[model].__class__), id(admin_class))
     82                raise AlreadyRegistered('The model %s is already registered to %s' % (model.__name__, self._registry[model].__class__.__name__))
    8183            self._registry[model] = admin_class(model, self)
    8284
    8385    def unregister(self, model_or_iterable):
Back to Top