JavaWeb-based JavaThe Django Framework's Killer Feature for Java Developers

The Django Framework’s Killer Feature for Java Developers content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

Since Struts dominated the Java Web development landscape a decade ago, a competition began to replace it with something more productive. In addition to the Spring Framework and JavaServer Faces (JSF), an explosion of Java Web frameworks such as Wicket, Stripes, GWT, Play and Click has given Java developers a bewildering array of choices.

Outside of the Java world, the dynamic language ecosystem has produced its own Web frameworks such as Ruby on Rails and Django to name a couple. However, because of their “is not Java” or “does not run on the JVM” limitations, Java shops almost always ignore them.

Django, however, has such a specific feature set that is so symbiotic with the type of business applications many Java developers develop every day that it deserves special attention. Specifically, Django has a killer feature that makes it worthwhile for Java shops to leave the comforts of the Java language: its automatic admin interface.

What Is the Django Admin Interface?

Django is built around the idea of reusable modules (simply called “apps”) that can be assembled into a larger application. One of these apps is the Admin interface, basically an auto-generated UI for listing/searching/filtering database entities and creating the add/edit/delete screens for them.

Many frameworks claim to offer something along the same lines (e.g., Ruby on Rails), but none of them are truly production-ready out of the box. This is the big difference with Django Admin: you can deploy it as-is without any customizations and it would probably be more feature-rich, slick and polished than your hand-coded CRUD screens.

The productivity boost you get from this out-of-the-box usability is incredible. You stop thinking in terms of HTML forms or templates and start thinking instead at a much higher lever:

  • What database entities do I want to show?
  • What fields should be visible on the search screen?
  • Which of them can be used as filters?
  • What fields should be visible on the add/edit/delete screen?

As an example, when I initially started learning Django I developed a working CRUD portal for about 10 database entities in about 5 days — and that included brushing up on Python and doing a few Django tutorials. More importantly, I completed this project by writing a single line of HTML (no boring <form/>, <table/>, <tr/> tags, etc.). I later attempted to do the same thing in the latest version of JSF 2, but it was like being forced to crawl after I had already learned to run. I promptly went back to Django.

In this article, I’ll show you the Django automatic admin interface in action. We will build a simple invoicing application with four entities: Customer, Product, Invoice and Invoice Line. Invoice consists of a master-header relationship between an Invoice Header and Invoice Line.

Installing Python and Django

Start off by installing Python and Django, as per the instructions at those links.

On Ubuntu, it’s as simple as this:

sudo apt-get install python-setuptools
sudo easy_install Django

When you have done all of that, just do the following from the app folder:

./ syncdb
./ runserver

The first command auto-creates the database tables in the local SQLite3 database. The second one runs the app on port 8000.

Code Speaks for Itself

Here is how the model definition for the invoicing application would look like (usually in a file called

from django.db import models

class Product(models.Model):
    name = models.CharField("Name",max_length=30)
    price = models.DecimalField("Price", max_digits = 10, decimal_places = 2)
    def __unicode__(self):
        return "%s - $%s" % (,self.price)
class Customer(models.Model):
    first_name = models.CharField("First Name",max_length=50)
    last_name = models.CharField("Last Name",max_length=50)
    address = models.CharField("Address",max_length=50)
    city = models.CharField("City", max_length=50)
    state = models.CharField("State", max_length=2)
    postal_code = models.CharField("Postal Code", max_length=10)
    def __unicode__(self):
        return "%s %s" % (self.first_name,self.last_name)
class Invoice(models.Model):
    invoice_number = models.CharField("Invoice Number", max_length=30)
    customer = models.ForeignKey(Customer)
    invoice_date = models.DateField("Date")
    def __unicode__(self):
        return self.invoice_number
class InvoiceLine(models.Model):
    product = models.ForeignKey(Product)
    quantity = models.IntegerField("Quantity")
    invoice  = models.ForeignKey(Invoice)
    def __unicode__(self):
        return ("%s x %s = $%s") % (self.product,self.quantity,(self.product.price * self.quantity))

A bit less verbose than JPA, I think we would all agree.

Now let’s hook up the entities to the admin interface. Customer, Product and Invoice will all get their own CRUD screens, while Invoice Line will be hooked up automatically to its invoice via a master-header relationship.

In a file usually called we enter:

from models import Customer, Invoice, InvoiceLine, Product
from django.contrib import admin

class InvoiceLineAdmin(admin.TabularInline):
    model = InvoiceLine
    extra = 1

class InvoiceAdmin(admin.ModelAdmin):
    fields = ['invoice_number','invoice_date','customer',]
    inlines = [InvoiceLineAdmin],InvoiceAdmin)

That’s it! When this is up and running, the following screens are what we get:

Notice that in the invoice edit screen, the invoice lines are added automatically. The date field has a default for “Today”, as well as a built-in JavaScript date picker. The Customer and Product fields automatically show a drop-down list via the foreign key relationship. They also have the plus sign (+) next to them, which allows you to add a new customer or product via a popup screen without leaving the invoice edit screen. Also, every entity modification is automatically tracked via a built-in audit trail subsystem (see Figure 8).

Now think how much code and HTML you would have to create to provide the same functionality in any Java Web framework and ask yourself this simple question: isn’t Django worth my time?

And we haven’t touched on any of the advanced functionality available in the admin app: filtering, mass actions, in-line editing, customizing the edit/list screens, etc.

Python Tooling

When Java developers hear Python, they probably think of old school Unix editors like vi or emacs. Don’t fear; there is a great Python plugin for Eclipse called PyDev. This plugin allows you to stay within the comforts of a modern IDE, providing new project wizards, code completion and even refactoring.


I hope this short introduction to Django explained clearly how its admin interface elevates Web development above the low-level details of HTML/CSS/JavaScript, etc., and lets you focus instead on the business functionality. No other framework I’ve seen comes close to delivering this level of productivity.

In short, it’s worth learning a Python to take advantage of Django. In our development team, we have settled on Java as our language of choice for all of our performance-intensive server applications and Python Django for all of our Web development.

About the Author

  • Simple Invoicing Application
  • About the Author

    Jacek Furmankiewicz is a Senior Java EE, Python, Oracle and MySQL developer at Radialpoint. He has 16 years of IT experience in writing enterprise software for a wide variety of industries.

    Get the Free Newsletter!

    Subscribe to Developer Insider for top news, trends & analysis

    Latest Posts

    Related Stories