Django Admin Integration
I love python and Django is probably the best Web application framework I have ever worked with, but it isn't without its issues. It has an absolutely great built-in, auto-generated admin interface for directly modifying database objects. It is incredibly convenient and takes care of most common Web application administration needs for the vast majority of applications. That being said, if it doesn't work for your application it can be painful to shim extended admin interfaces into it.
For example it doesn't really fit with Formunculous or File Manager than it is pretty much the exact opposite of convenient. I have wrestled with integrating other application's admin interfaces into the Django admin with out much success. The look and feel is easy thanks to template extensions, but just creating a simple link to your extended admin views is just not there, and there isn't really a recommended way to do it.
I have tried distributing template includes to include with the admin index template. This is painful because it requires the person installing your app to create a local copy of the admin template and then inject your template into it. I have also tried extending the admin base class to override the app_index views. This worked fine, but is way to heavy weight for most of these types of admin interfaces.
So, I have finally found a better way. With Formunculous 1.0, I simply was so mad at previous attempts of integrating with the Django admin application that I just gave up, and wrote it entirely without it. This wasn't the best of situations, and when it came to writing Formunculous 2.0 I decided I had to have a better way. I found it.
I read Django admin source code for a few hours, and finally realized that you can override the urls for an AdminModel. Eureka. I just need to create an empty AdminModel and replace the pre-canned URLs with the ones for my admin interface. I call the AdminModel the same as my app, and I'm done. The one trick that prevented this from working off the bat, was solved by the very unknown "lazy" utility in Django core (big thanks to Andr.in). So here is the code:
from django.contrib import admin
from django.conf.urls.defaults import *
from formunculous.models import Form
from django.utils.functional import lazy
from django.core.urlresolvers import reverse
reverse_lazy = lazy(reverse, unicode)
class FormAdmin(admin.ModelAdmin):
def get_urls(self):
urls = patterns('django.views.generic.simple',
url(r'^$', 'redirect_to',
{'url': reverse_lazy('builder-index')},
name="formunculous_applicationdefinition_changelist"),
url(r'^add/$', 'redirect_to',
{'url': reverse_lazy('builder-add-ad')},
name="formunculous_applicationdefinition_add"),
)
return urls
admin.site.register(Form, FormAdmin)
This is straight out of Formunculous. It creates an Admin model from a blank model in models.py and overrides the get_urls method of the class. It then changes the url for the add and change views of the class to lazily reversed urls by using the simple redirect view.
For clarity, here is the model I extended:
class Form(models.Model):
class Meta:
permissions = (
("can_delete_applications", "Can delete applications"),
)
The reason for the permissions there is specific to Formunculous, but a completely empty model should work as well. Something like:
class MyApplicationAdmin(models.Model):
pass
This will give a nice link in the admin interface to the administration views for your application without having to mess without overriding anything. An important thing to note is that this will only work with Django 1.1 and higher. The admin application in Django 1.0 didn't use the newer standards for URLs.

Comments
Post new comment