The inbuilt admin interface is one of the most powerful & popular features of Django. Once we create the models, we need to register them with the admin interface, so that it can read metadata and populate interface for it.
If the Django project has too many models or if it has a legacy database, then adding all those models to admin becomes a tedious task. To automate this process, we can programmatically fetch all the models in the project and register them with the admin interface.
Open admin.py file and add this code to it.
from django.apps import apps
models = apps.get_models()
for model in models:
admin.site.register(model)
This will fetch all the models in all apps and registers them with the admin interface.
This works well if we are automatically registering all the models. However, if we separately register some models with customizations and try to register all models in our apps again, there will be conflicts as Django doesn't allow registering the same model twice.
So, we need to make sure this piece of code runs at the end of admin.py file and it should ignore models which are already registered. We can add this code at the end of the admin.py file.
from django.apps import apps
from book.models import Book
class BookAdmin(admin.ModelAdmin):
list_display = ('name', 'author')
# model registered with custom admin
admin.site.register(Book, BookAdmin)
# all other models
models = apps.get_models()
for model in models:
try:
admin.site.register(model)
except admin.sites.AlreadyRegistered:
pass
Now manually registered models will get registered first followed by automatic registration of remaining models.
class Book(models.Model):
name = models.CharField(max_length=100)
author = models.ForeignKey(Author, null=True)
borrowed = models.CharField(max_length=100, default='')
def __str__(self):
return self.name
If we go to a model page in admin, automatically registered models will just show 1 column like this.
This interface is not informative for the users who want to see the data. To improve that, we can create a ListAdminMixin, which will populate list_display with all the fields in the model.
We can create a new admin class which will subclass ListAdminMixin & ModelAdmin. We can use this admin class when we are registering the model so that all the fields in the model will show up in the admin.
from django.apps import apps
from django.contrib import admin
class ListAdminMixin(object):
def __init__(self, model, admin_site):
self.list_display = [field.name for field in model._meta.fields]
super(ListAdminMixin, self).__init__(model, admin_site)
models = apps.get_models()
for model in models:
admin_class = type('AdminClass', (ListAdminMixin, admin.ModelAdmin), {})
try:
admin.site.register(model, admin_class)
except admin.sites.AlreadyRegistered:
pass
Now, whenever we create a new model or add a new field to an existing model, it will get reflected in the admin automatically.
With this, we can avoid registering models with admin whenever models get added to our apps.
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — -
Originally published at https://avilpage.com on November 24, 2017.
More Django Tips & Tricks at https://avilpage.com/tags/django.html