django: Migrating to Admin-newforms made easy
I have been a great admirer of simplicity of django. So I was rather disappointed when I saw the newforms-admin. Using newforms-admin requires more code, more named classes and more work
. This is a simple comparison of how to use admin functionality before and after the changes.
Before
#file models.py from django.db import models class MyModel(models.Model): #field definitions class Admin: #admin options
Now
#file models.py from django.db import models class MyModel(models.Model): #field definitions #file admin.py from django.contrib import admin from myapp.models import * class MyModelAdmin(admin.ModelAdmin): #admin options admin.site.register(MyModel, MyModelAdmin)
Migrating all of my django projects (having a large number of models) was a huge ask. So I started thinking, is there an easy way to migrate all of my django projects to newform-admin? As I started the migration manually, I identified the steps involved,
- for every model in models.py create an admin.ModelAdmin base class
- define admin options
- register the Model and ModelAdmin base classes
Looking at my code, I realized that 1,2 were almost already complete. The model classes already have an inner Admin class with all the options. The only thing required was to call admin.site.register properly. The logic is something like,
for every model in models.py if model_class has Admin admin_class = create subclass of admin.ModelAdmin at run-time having all admin options admin.site.register(mode_class, admin_class)
But how to create a named subclass at run-time with unknown attributes?
This is where the type function comes into play. The common use of type is to check the datatype of an object. But if you look closely, you ll find that type can also be used as,
type(name, base, dict) =>creates a class named name =>with base classes base =>and having attributes dict
After messing around with the code for about an hour, I came up with this.
from django.contrib import admin from django.db import models from django.contrib import admin from django.db import models for app in models.get_apps(): for m in models.get_models(app): if hasattr(m, 'Admin'): try: admin.site.register(m, type('Admin' + m.__name__, (admin.ModelAdmin,), dict( [(a,getattr(m.Admin,a)) for a in dir(m.Admin)] ))) except: pass
The snippet iterates over all models of every installed app, checks if the model has an inner class Admin. If found, it creates an admin.ModelAdmin base class using the options from the inner class and names it by appending ‘Admin’ to model name. A try, except block is added to handle if there are any models already registered.
And thats it. I placed this code in admin.py of only one of my apps and I did not have to make any change in any of my apps (other than removing the unsupported options). This made my migration to newforms-admin a painless procedure. Until you feel like migrating manually, use this code to make life a little easier
Related posts:


