Django admin
Python meetup
Ines Jelovac
Zagreb, 14 June 2016
Django Web Framework
● High-level Python Web framework
● MVC
Django admin
● Automatic interface
● For site administrators
● Reads model metadata
● Customizing:
○ Layout
○ Filters
○ Actions
Model example
class Article(models.Model):
author = models.ForeignKey(settings.AUTH_USER_MODEL)
title = models.CharField(max_length=200)
lead_text = models.CharField(max_length=300)
content = models.TextField()
publish_date = models.DateTimeField()
image = models.ImageField()
section = models.ManyToManyField(Section)
def __str__(self):
return self.title
Model metadata
class Article(models.Model):
...
class Meta:
verbose_name = _('Article')
verbose_name_plural = _('Articles')
ordering = ('-publish_date',)
Default admin interface
app/admin.py
from django.contrib import admin
from articles.models import Article
admin.site.register(Article)
Default list interface
Customizing objects list: list_display
● List objects page
○ Default: str() of each object
● list_display option
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ['title', 'publish_date']
● list_display_links option
Customizing objects list: list_display
Customizing objects list: empty_value_display
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ['title', 'publish_date']
empty_value_display = '(unknown)'
Customizing objects list: empty_value_display
Customizing objects list: list_filter
● Model field
● Foreign key attribute lookup
● Custom querysets
● preserve_filters option
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ['title', 'publish_date']
empty_value_display = '(unknown)'
list_filter = ['section', PublishedListFilter]
Customizing objects list: list_filter
class PublishedListFilter(admin.SimpleListFilter):
title = 'published'
parameter_name = 'publish_date'
def lookups(self, request, model_admin):
return (
('published', 'published'),
('not_published', 'not published')
)
def queryset(self, request, queryset):
if self.value() == 'published':
return queryset.filter(publish_date__isnull=False)
if self.value() == 'not_published':
return queryset.filter(publish_date__isnull=True)
Customizing objects list: list_filter
Customizing objects list: date_hierarchy
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ['title', 'publish_date']
empty_value_display = '(unknown)'
list_filter = ['section', PublishedListFilter]
date_hierarchy = 'publish_date'
Customizing objects list: date_hierarchy
Customizing objects list: search_fields
● Model field
● Foreign key attribute lookup
● Operators
○ ^ to match starting at the beginning of the field
○ = for case-insensitive exact matching
○ @ operator to perform a full text match
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ['title', 'publish_date']
empty_value_display = '(unknown)'
list_filter = ['section', PublishedListFilter]
date_hierarchy = 'publish_date'
search_fields = ['title']
Customizing objects list: search_fields
Customizing objects list: list_editable
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ['title', 'lead_text','publish_date']
empty_value_display = '(unknown)'
list_filter = ['section', PublishedListFilter]
date_hierarchy = 'publish_date'
search_fields = ['title']
list_editable = ['lead_text']
Customizing objects list: list_editable
Default edit interface
Default edit interface
● Default buttons
○ Delete
○ Save and add another
○ Save and continue editing
○ Save
● save_as option: if set to True “Save as new” replaces “Save and add
another” button
Customizing edit interface: fields
● fields option
○ List of fields in model edit form
○ Change order
○ Group in same line
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
fields = [
'author',
('title', 'lead_text'),
'content',
('publish_date', 'image'),
'section'
]
Customizing edit interface
Customizing edit interface
● exclude option
○ List of fields not shown in edit form
● readonly_fields option
○ Field or method
● fieldsets option
○ Group fields
● form option
○ Replace default Form with custom
● view_on_site option
○ Boolean - calls get_absolute_url
○ Callable
Customizing edit interface: many to many
● filter_horizontal option
● filter_vertical option
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
…
filter_horizontal = ['section']
Customizing edit interface: filter_horizontal
Customizing edit interface: inlines
● TabularInline
● StackedInline
class GalleryInline(admin.TabularInline):
model = GalleyImage
extra = 2
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
...
filter_horizontal = ['section']
inlines = [GalleryInline]
Customizing edit interface: inlines
Customizing admin interface: actions
● Functions that get called with a list of objects selected on the change list page
● Simple logic: use function
● Complex logic: redirect the user to another view in function
def delete_publish_date(modeladmin, request, queryset):
queryset.update(publish_date=None)
delete_publish_date.short_description = "Delete published
date for selected articles"
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
…
actions = [delete_publish_date]
Customizing edit interface: actions
Customizing admin interface: actions
Optimization
● show_full_result_count option in list view
○ Eliminates expensive count
● list_select_related option in list view
○ Django will use select_related in query
● raw_id_fields option in edit view
There is more
● Overriding default templates
● Overriding methods
● History view
● Decorator @staff_member_required
ljudski_potencijali@styria.hr

Django Admin (Python meeutp)

  • 1.
    Django admin Python meetup InesJelovac Zagreb, 14 June 2016
  • 2.
    Django Web Framework ●High-level Python Web framework ● MVC Django admin ● Automatic interface ● For site administrators ● Reads model metadata ● Customizing: ○ Layout ○ Filters ○ Actions
  • 3.
    Model example class Article(models.Model): author= models.ForeignKey(settings.AUTH_USER_MODEL) title = models.CharField(max_length=200) lead_text = models.CharField(max_length=300) content = models.TextField() publish_date = models.DateTimeField() image = models.ImageField() section = models.ManyToManyField(Section) def __str__(self): return self.title
  • 4.
    Model metadata class Article(models.Model): ... classMeta: verbose_name = _('Article') verbose_name_plural = _('Articles') ordering = ('-publish_date',)
  • 5.
    Default admin interface app/admin.py fromdjango.contrib import admin from articles.models import Article admin.site.register(Article)
  • 6.
  • 7.
    Customizing objects list:list_display ● List objects page ○ Default: str() of each object ● list_display option @admin.register(Article) class ArticleAdmin(admin.ModelAdmin): list_display = ['title', 'publish_date'] ● list_display_links option
  • 8.
  • 9.
    Customizing objects list:empty_value_display @admin.register(Article) class ArticleAdmin(admin.ModelAdmin): list_display = ['title', 'publish_date'] empty_value_display = '(unknown)'
  • 10.
    Customizing objects list:empty_value_display
  • 11.
    Customizing objects list:list_filter ● Model field ● Foreign key attribute lookup ● Custom querysets ● preserve_filters option @admin.register(Article) class ArticleAdmin(admin.ModelAdmin): list_display = ['title', 'publish_date'] empty_value_display = '(unknown)' list_filter = ['section', PublishedListFilter]
  • 12.
    Customizing objects list:list_filter class PublishedListFilter(admin.SimpleListFilter): title = 'published' parameter_name = 'publish_date' def lookups(self, request, model_admin): return ( ('published', 'published'), ('not_published', 'not published') ) def queryset(self, request, queryset): if self.value() == 'published': return queryset.filter(publish_date__isnull=False) if self.value() == 'not_published': return queryset.filter(publish_date__isnull=True)
  • 13.
  • 14.
    Customizing objects list:date_hierarchy @admin.register(Article) class ArticleAdmin(admin.ModelAdmin): list_display = ['title', 'publish_date'] empty_value_display = '(unknown)' list_filter = ['section', PublishedListFilter] date_hierarchy = 'publish_date'
  • 15.
  • 16.
    Customizing objects list:search_fields ● Model field ● Foreign key attribute lookup ● Operators ○ ^ to match starting at the beginning of the field ○ = for case-insensitive exact matching ○ @ operator to perform a full text match @admin.register(Article) class ArticleAdmin(admin.ModelAdmin): list_display = ['title', 'publish_date'] empty_value_display = '(unknown)' list_filter = ['section', PublishedListFilter] date_hierarchy = 'publish_date' search_fields = ['title']
  • 17.
  • 18.
    Customizing objects list:list_editable @admin.register(Article) class ArticleAdmin(admin.ModelAdmin): list_display = ['title', 'lead_text','publish_date'] empty_value_display = '(unknown)' list_filter = ['section', PublishedListFilter] date_hierarchy = 'publish_date' search_fields = ['title'] list_editable = ['lead_text']
  • 19.
  • 20.
  • 21.
    Default edit interface ●Default buttons ○ Delete ○ Save and add another ○ Save and continue editing ○ Save ● save_as option: if set to True “Save as new” replaces “Save and add another” button
  • 22.
    Customizing edit interface:fields ● fields option ○ List of fields in model edit form ○ Change order ○ Group in same line @admin.register(Article) class ArticleAdmin(admin.ModelAdmin): fields = [ 'author', ('title', 'lead_text'), 'content', ('publish_date', 'image'), 'section' ]
  • 23.
  • 24.
    Customizing edit interface ●exclude option ○ List of fields not shown in edit form ● readonly_fields option ○ Field or method ● fieldsets option ○ Group fields ● form option ○ Replace default Form with custom ● view_on_site option ○ Boolean - calls get_absolute_url ○ Callable
  • 25.
    Customizing edit interface:many to many ● filter_horizontal option ● filter_vertical option @admin.register(Article) class ArticleAdmin(admin.ModelAdmin): … filter_horizontal = ['section']
  • 26.
    Customizing edit interface:filter_horizontal
  • 27.
    Customizing edit interface:inlines ● TabularInline ● StackedInline class GalleryInline(admin.TabularInline): model = GalleyImage extra = 2 @admin.register(Article) class ArticleAdmin(admin.ModelAdmin): ... filter_horizontal = ['section'] inlines = [GalleryInline]
  • 28.
  • 29.
    Customizing admin interface:actions ● Functions that get called with a list of objects selected on the change list page ● Simple logic: use function ● Complex logic: redirect the user to another view in function def delete_publish_date(modeladmin, request, queryset): queryset.update(publish_date=None) delete_publish_date.short_description = "Delete published date for selected articles" @admin.register(Article) class ArticleAdmin(admin.ModelAdmin): … actions = [delete_publish_date]
  • 30.
    Customizing edit interface:actions Customizing admin interface: actions
  • 31.
    Optimization ● show_full_result_count optionin list view ○ Eliminates expensive count ● list_select_related option in list view ○ Django will use select_related in query ● raw_id_fields option in edit view
  • 32.
    There is more ●Overriding default templates ● Overriding methods ● History view ● Decorator @staff_member_required
  • 33.