Commits

Matthew Schinckel  committed fd0bc4e

Added patching functions for ModelAdmin classes.
Updated version number.

  • Participants
  • Parent commits 093a502
  • Tags 0.1.1

Comments (0)

Files changed (3)

         'FULLY_DYNAMIC_FORMSETS': True,
     }
 
-## Modules/patches/settings
+## settings
 
 ### RETURN_TO_FILTERED_CHANGELIST
 
 ### FULLY_DYNAMIC_FORMSETS
 
 Sets the `extra` value on `InlineModelAdmin` to 0, so you just use the addition button
-instead of having any empty formsets.
+instead of having any empty formsets.
+
+## Patching functions
+
+### patch_model_admin(model, patch_function)
+
+Patch an installed ``ModelAdmin``. This includes unregistering, patching and then re-registering. You may pass in a model, or a string of the form `"app_label.ModelName"`, and a function that will take and patch a ``ModelAdmin`` class.
+
+If you create a new class based on the passed in class, then you may return it: that will then be used within the re-registration. If you simply patch the existing class, you can return nothing, and the patched original class will be used.
+
+    from admin_additions.patchers import patch_model_admin
+    
+    def patcher_function(model_admin):
+        # Do stuff here.
+        model_admin.form = MyClassyForm
+        return model_admin # optional: you may patch in-place
+    
+    patch_model_admin(MyModel, patcher_function)
+
+### add_inlines(model, *inlines)
+
+A simple/common case of patching a ``ModelAdmin``: adding a new inline:
+
+    from django.contrib import admin
+    from admin_additions.patchers import add_inlines
+    
+    from models import Foo
+    
+    class FooInline(admin.StackedInline):
+        model = Foo
+    
+    add_inlines('bar.Bar', FooInline)
+    
+You may pass multiple inlines.
+
+You may also pass in any combination of models or admin inlines: if a model is received, it will create a `StackedInline` for that model.

File admin_additions/__init__.py

-__version__ = "0.1"
+__version__ = "0.1.1"

File admin_additions/patchers.py

+from django.db.models import get_model
+from django.contrib import admin
+
+def patch_model_admin(model, patch_function):
+    """
+    Patch an installed ModelAdmin.
+    
+    patch_function must take one argument, the ModelAdmin, and
+    may mutate the object in place, or return a new ModelAdmin.
+    """
+    if isinstance(model, basestring):
+        model = get_model(*model.split('.'))
+    ModelAdmin = type(admin.site._registry.get(model))
+    ModelAdmin = patch_function(ModelAdmin) or ModelAdmin
+    admin.site.unregister(model)
+    admin.site.register(model, ModelAdmin)
+
+def add_inlines(model, *inlines):
+    """
+    Add an arbitrary number of inlines to the admin for
+    the provided model.
+    """
+    inlines = list(inlines)
+    for i, inline in enumerate(inlines):
+        if not issubclass(inline, admin.options.InlineModelAdmin):
+            inlines[i] = type("%sInline" % inline.__name__, (admin.StackedInline,), {"model": inline})
+    def inner(admin):
+        admin.inlines = tuple(admin.inlines) + tuple(inlines)
+    
+    patch_model_admin(model, inner)