The admin app is clever enough to figure out a lot of things from your model automatically. However, sometimes the inferred information can be improved. This usually involves adding an attribute or a method to the model itself (rather than at the ModelAdmin
class).
Let's first take a look at an example that enhances the model for better presentation, including the admin interface:
# models.py class SuperHero(models.Model): name = models.CharField(max_length=100) added_on = models.DateTimeField(auto_now_add=True) def __str__(self): return "{0} - {1:%Y-%m-%d %H:%M:%S}".format(self.name, self.added_on) def get_absolute_url(self): return reverse('superhero.views.details', args=[self.id]) class Meta: ordering = ["-added_on"] verbose_name = "superhero" verbose_name_plural = "superheroes"
Let's take a look at how admin uses all these non-field attributes:
__str__()
: Without this, the list of superhero entries would look extremely boring. Every entry would be plainly shown as <SuperHero: SuperHero object>
. Try to include the object's unique information in its str
representation (or unicode
representation, in the case of Python 2.x code), such as its name or version. Anything that helps the admin to recognize the object unambiguously would help.get_absolute_url()
: This attribute is handy if you like to switch between the admin view and the object's detail view on your website. If this method is defined, then a button labelled "View on site" will appear in the top right-hand side of the object's edit page in its admin page.ordering
: Without this meta option, your entries can appear in any order as returned from the database. As you can imagine, this is no fun for the admins if you have a large number of objects. Fresh entries are usually preferred to be seen first, so sorting by date in the reverse chronological order is common.verbose_name
: If you omit this attribute, your model's name would be converted from CamelCase into camel case. In this case, "super hero" would look awkward, so it is better to be explicit about how you would like the user-readable name to appear in the admin interface.verbose_name_plural
: Again, omitting this option can leave you with funny results. Since Django simply prepends an 's' to the word, the plural of a superhero would be shown as "superheros" (on the admin front page, no less). So, it is better to define it correctly here.It is recommended that you define the previous Meta
attributes and methods, not just for the admin interface, but also for better representation in the shell, log files, and so on.
Of course, a further improved representation within the admin is possible by creating a ModelAdmin
class as follows:
# admin.py class SuperHeroAdmin(admin.ModelAdmin): list_display = ('name', 'added_on') search_fields = ["name"] ordering = ["name"] admin.site.register(models.SuperHero, SuperHeroAdmin)
Let's take a look at these options more closely:
list_display
: This option shows the model instances in a tabular form. Instead of using the model's __str__
representation, it shows each field mentioned as a separate sortable column. This is ideal if you like to see more than one attribute of your model.search_fields
: This option shows a search box above the list. Any search term entered would be searched against the mentioned fields. Hence, only text fields such as CharField
or TextField
can be mentioned here.ordering
: This option takes precedence over your model's default ordering. It is useful if you prefer a different ordering in your admin screen.The preceding screenshot shows the following insets:
str
or Meta
attributesmeta
attributesModelAdmin
Here, we have only mentioned a subset of commonly used admin options. Certain kinds of sites use the admin interface heavily. In such cases, it is highly recommended that you go through and understand the admin part of the Django documentation.
Since admin interfaces are so easy to create, people tend to misuse them. Some give early users admin access by merely turning on their 'staff' flag. Soon such users begin making feature requests, mistaking the admin interface to be the actual application interface.
Unfortunately, this is not what the admin interface is for. As the flag suggests, it is an internal tool for the staff to enter content. It is production-ready but not really intended for the end users of your website.
It is best to use admin for simple data entry. For example, in a project I had reviewed, every teacher was made an admin for a Django application managing university courses. This was a poor decision since the admin interface confused the teachers.
The workflow for scheduling a class involves checking the schedules of other teachers and students. Using the admin interface gives them a direct view of the database. There is very little control over how the data gets modified by the admin.
So, keep the set of people with admin access as small as possible. Make changes via admin sparingly, unless it is simple data entry such as adding an article's content.
Ensure that all your admins understand the data inconsistencies that can arise from making changes through the admin. If possible, record manually or use apps, such as django-audit-loglog
that can keep a log of admin changes made for future reference.
In the case of the university example, we created a separate interface for teachers, such as a course builder. These tools will be visible and accessible only if the user has a teacher profile.
Essentially, rectifying most misuses of the admin interface involves creating more powerful tools for certain sets of users. However, don't take the easy (and wrong) path of granting them admin access.