Customize the Django newform admin UI

djangopython

One of the exciting features Django 1.0 brings to the table is the integration of newform into the admin UI. Hat off to Brian, great work.

The essential workload in the Pattee’s admin UI is to input the meta information of the book, then link it to the eBook file. It is more convenient to take the advantage of Amazon Web Service, so the user scenario is:

  1. Search Amazon by keyword or ISBN
  2. Select the correct book
  3. Update the eBook file
  4. Save it to the database

Add a Book
Add a Book
Change a Book
Change a Book

It is straightforward to override the default template and implementation: redirect the admin URL to our own version of change_form.html template and add_view implementation, then save the object regardless the data integration; or we may reuse the infrastructure, and just implement our required function. Pattee takes the latter approach.

First, declare the BookAdmin and eBookAdmin in _admin.py, and hook eBook inline:

class eBookAdmin(admin.StackedInline):
    model = eBook
    extra = 1

class BookAdmin(admin.ModelAdmin):
    form = BookForm
    inlines = [eBookAdmin]
    change_form_template = 'book_change_form.html'

and don’t forget to register it to admin.site, which is required by Django 1.0.

admin.site.register(Book, BookAdmin)

Then in BookForm, we could override full_clean to provide the cleaned data. And in BookAdmin, the following tricks will guard against duplication of Book instances:

 def save_form(self, request, form, change):
     if form.is_valid():
         try :
             instance = self.model.objects.get(isbn = form.cleaned_data['isbn'])
         except ObjectDoesNotExist:
             return super(BookAdmin, self).save_form(request, form, change)
     return instance

That is all. You may consider to check out the source code for details:

svn checkout http://my-svn.assembla.com/svn/pattee/trunk pattee