Adjusted 14082 hack again... "fixed" the ModelFormMetaclass.__new__ method and wrote...
authorStephen Burrows <stephen.r.burrows@gmail.com>
Tue, 29 Mar 2011 17:07:13 +0000 (13:07 -0400)
committerStephen Burrows <stephen.r.burrows@gmail.com>
Tue, 29 Mar 2011 17:07:13 +0000 (13:07 -0400)
admin/base.py
forms/entities.py

index b616290..75fa336 100644 (file)
@@ -133,15 +133,6 @@ class EntityAdmin(admin.ModelAdmin):
                #       kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical))
                
                return db_field.formfield(**kwargs)
-       
-       def get_form(self, request, obj=None, **kwargs):
-               """
-               Ensures that the form's proxy fields are included in its base fields.
-               This will not be required after http://code.djangoproject.com/ticket/14082 has been resolved
-               """
-               form = super(EntityAdmin, self).get_form(request, obj, **kwargs)
-               form.base_fields.update(form.proxy_fields)
-               return form
 
 
 class TreeAdmin(MPTTModelAdmin):
index 43094b9..e781128 100644 (file)
@@ -42,6 +42,26 @@ def proxy_fields_for_entity_model(entity_model, fields=None, exclude=None, widge
        return field_dict
 
 
+# HACK until http://code.djangoproject.com/ticket/14082 is resolved.
+_old = ModelFormMetaclass.__new__
+def _new(cls, name, bases, attrs):
+       if cls == ModelFormMetaclass:
+               m = attrs.get('__metaclass__', None)
+               if m is None:
+                       parents = [b for b in bases if issubclass(b, ModelForm)]
+                       for c in parents:
+                               if c.__metaclass__ != ModelFormMetaclass:
+                                       m = c.__metaclass__
+                                       break
+       
+               if m is not None:
+                       return m(name, bases, attrs)
+       
+       return _old(cls, name, bases, attrs)
+ModelFormMetaclass.__new__ = staticmethod(_new)
+# END HACK
+
+
 class EntityFormMetaclass(ModelFormMetaclass):
        def __new__(cls, name, bases, attrs):
                try:
@@ -55,47 +75,20 @@ class EntityFormMetaclass(ModelFormMetaclass):
                        # Then there's no business trying to use proxy fields.
                        return sup.__new__(cls, name, bases, attrs)
                
-               # Preemptively make a meta so we can screen out any proxy fields.
-               # After http://code.djangoproject.com/ticket/14082 has been resolved,
-               # perhaps switch to setting proxy fields as "declared"?
-               _opts = ModelFormOptions(attrs.get('Meta', None))
-               
-               # Make another copy of opts to spoof the proxy fields not being there.
+               # Fake a declaration of all proxy fields so they'll be handled correctly.
                opts = ModelFormOptions(attrs.get('Meta', None))
+               
                if opts.model:
                        formfield_callback = attrs.get('formfield_callback', None)
                        proxy_fields = proxy_fields_for_entity_model(opts.model, opts.fields, opts.exclude, opts.widgets, formfield_callback)
                else:
                        proxy_fields = {}
                
-               # Screen out all proxy fields from the meta
-               opts.fields = list(opts.fields or [])
-               opts.exclude = list(opts.exclude or [])
-               
-               for field in proxy_fields.keys():
-                       try:
-                               opts.fields.remove(field)
-                       except ValueError:
-                               pass
-                       try:
-                               opts.exclude.remove(field)
-                       except ValueError:
-                               pass
-               opts.fields = opts.fields or None
-               opts.exclude = opts.exclude or None
-               
-               # Put in the new Meta.
-               attrs['Meta'] = opts
-               
-               new_class = sup.__new__(cls, name, bases, attrs)
-               
-               intersections = set(new_class.declared_fields.keys()) & set(proxy_fields.keys())
-               for key in intersections:
-                       proxy_fields.pop(key)
+               new_attrs = proxy_fields.copy()
+               new_attrs.update(attrs)
                
+               new_class = sup.__new__(cls, name, bases, new_attrs)
                new_class.proxy_fields = proxy_fields
-               new_class._meta = _opts
-               new_class.base_fields.update(proxy_fields)
                return new_class