X-Git-Url: http://git.ithinksw.org/philo.git/blobdiff_plain/3a134160f8e7e663c5807cd44296f5f3a88b8a36..3c26965045e8881acd4d5de8c195e4aa61b95ed1:/forms/entities.py diff --git a/forms/entities.py b/forms/entities.py index 43094b9..e781128 100644 --- a/forms/entities.py +++ b/forms/entities.py @@ -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