Administration All Versions
Improvements requested:
-
Other: I think these examples should be moved to new topics within http://stackoverflow.com/documentation/django-admin but I don't know how to do this. – Antoine Pinsard Jul 31 at 11:36add a comment
This draft deletes the entire topic.
Examples
-
Let's say you have a simple
myblog
app with the following model:class Article(models.Model): title = models.CharField(max_length=70) slug = models.SlugField(max_length=70, unique=True) author = models.ForeignKey(settings.AUTH_USER_MODEL, models.PROTECT) date_published = models.DateTimeField(default=timezone.now) is_draft = models.BooleanField(default=True) content = models.TextField()
Django Admin's "change list" is the page that lists all objects of a given model.
from django.contrib import admin from myblog.models import Article @admin.register(Article) class ArticleAdmin(admin.ModelAdmin): pass
By default, it will use the
__str__()
method (or__unicode__()
if you on python2) of your model to display the object "name". This means that if you didn't override it, you will see a list of articles, all named "Article object". To change this behavior, you can set the__str__()
method:class Article(models.Model): def __str__(self): return self.title
Now, all your articles should have a different name, and more explicit than "Article object".
However you may want to display other data in this list. For this, use
list_display
:@admin.register(Article) class ArticleAdmin(admin.ModelAdmin): list_display = ['__str__', 'author', 'date_published', 'is_draft']
list_display
is not limited to the model fields and properties. it can also be a method of yourModelAdmin
:from django.forms.utils import flatatt from django.urls import reverse from django.utils.html import format_html @admin.register(Article) class ArticleAdmin(admin.ModelAdmin): list_display = ['title', 'author_link', 'date_published', 'is_draft'] def author_link(self, obj): author = obj.author opts = author._meta route = '{}_{}_change'.format(opts.app_label, opts.model_name) author_edit_url = reverse(route, args=[author.pk]) return format_html( '<a{}>{}</a>', flatatt({'href': author_edit_url}), author.first_name) # Set the column name in the change list author_link.short_description = "Author" # Set the field to use when ordering using this column author_link.admin_order_field = 'author__firstname'
-
By default, Django renders
ForeignKey
fields as a<select>
input. This can cause pages to be load really slowly if you have thousands or tens of thousand entries in the referenced table. And even if you have only hundreds of entries, it is quite uncomfortable to look for a particular entry among all.A very handy external module for this is django-autocomplete-light (DAL). This enables to use autocomplete fields instead of
<select>
fields.views.py
from dal import autocomplete class CityAutocomp(autocomplete.Select2QuerySetView): def get_queryset(self): qs = City.objects.all() if self.q: qs = qs.filter(name__istartswith=self.q) return qs
urls.py
urlpatterns = [ url(r'^city-autocomp/$', CityAutocomp.as_view(), name='city-autocomp'), ]
forms.py
from dal import autocomplete class PlaceForm(forms.ModelForm): city = forms.ModelChoiceField( queryset=City.objects.all(), widget=autocomplete.ModelSelect2(url='city-autocomp') ) class Meta: model = Place fields = ['__all__']
admin.py
@admin.register(Place) class PlaceAdmin(admin.ModelAdmin): form = PlaceForm
-
-
Suppose you have a simple
Customer
model:class Customer(models.Model): first_name = models.CharField(max_length=255) last_name = models.CharField(max_length=255) is_premium = models.BooleanField(default=False)
You register it in the Django admin and add search field by
first_name
andlast_name
:@admin.register(Customer) class CustomerAdmin(admin.ModelAdmin): list_display = ['first_name', 'last_name', 'is_premium'] search_fields = ['first_name', 'last_name']
After you do this, the search fields appear in the admin list page with the default placeholder: "keyword". But what if you want to change that placeholder to "Search by name"?
You can do this by passing custom Javascript file into admin
Media
:@admin.register(Customer) class CustomerAdmin(admin.ModelAdmin): list_display = ['first_name', 'last_name', 'is_premium'] search_fields = ['first_name', 'last_name'] class Media: #this path may be any you want, #just put it in your static folder js = ('js/admin/placeholder.js', )
You can use browser debug toolbar to find what id or class Django set to this searchbar and then write your js code:
$(function () { $('#searchbar').attr('placeholder', 'Search by name') })
Also
Media
class allows you to add css files with dictionary object:class Media: css = { 'all': ('css/admin/styles.css',) }
For example we need to display each element of
first_name
column in specific color.
By default Django create table column for every item inlist_display
, all<td>
tags will have css class likefield-'list_display_name'
, in our case it willfield_first_name
.field_first_name { background-color: #e6f2ff; }
If you want to customize other behavior by adding JS or some css styles, you can always check id`s and classes of elements in the browser debug tool.
Topic Outline
Sign up or log in
Save edit as a guest
Join Stack Overflow
Using Google
Using Facebook
Using Email and Password
We recognize you from another Stack Exchange Network site!
Join and Save Draft