def dynamic_inline_factory(inline_cls): "Make sure the inline has a dynamic form" form_cls = getattr(inline_cls, 'form', None) if form_cls is ModelForm: form_cls = DynamicModelForm elif issubclass(form_cls, DynamicModelForm): return inline_cls else: form_cls = dynamic_model_form_factory(form_cls) class cls(inline_cls): form = form_cls def get_formset(self, request, obj=None, **kwargs): formset = super(cls, self).get_formset(request, obj=None, **kwargs) if not isinstance(formset.form(), DynamicModelForm): raise Exception('DynamicAdmin inlines\'s formset\'s form must be an instance of DynamicModelForm') return formset cls.__name__ = "Dynamic%s" % inline_cls.__name__ return cls
def __new__(cls, name, bases, attrs): # If there's already a form defined we make sure to subclass it if 'form' in attrs: attrs['form'] = dynamic_model_form_factory(attrs['form']) else: attrs['form'] = DynamicModelForm # Make sure the specified add|change_form_template # extends "admin/dynamic_choices/change_form.html" for t, default in {'add_form_template': None, 'change_form_template': change_form_template}.iteritems(): if t in attrs: if not template_extends(attrs[t], change_form_template): raise Exception("Make sure specified %s.%s='%s' template extends '%s' " "in order to enabled DynamicAdmin" % (name, t, attrs[t], change_form_template)) else: attrs[t] = default # If there's some inlines defined we make sure that their form is dynamic # see dynamic_inline_factory if 'inlines' in attrs: attrs['inlines'] = [dynamic_inline_factory(inline_cls) for inline_cls in attrs['inlines']] return super(meta_cls, cls).__new__(cls, name, bases, attrs)