Slide 1

Slide 1 text

PUSHING THE PONY’S BOUNDRIES

Slide 2

Slide 2 text

BFF Ola + Admin ==

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

6 years of building admin interfaces

Slide 5

Slide 5 text

Ola Sitarska

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

DjangoCon Europe 2013 Django Girls Django Core Team DSF Board

Slide 8

Slide 8 text

DjangoCon Europe 2013 Django Girls Django Core Team DSF Board

Slide 9

Slide 9 text

DjangoCon Europe 2013 Django Girls Django Core Team DSF Board

Slide 10

Slide 10 text

DjangoCon Europe 2013 Django Girls Django Core Team DSF Board

Slide 11

Slide 11 text

ADMIN

Slide 12

Slide 12 text

Insides of the admin Magic tricks Future of the admin

Slide 13

Slide 13 text

before after

Slide 14

Slide 14 text

HOW ADMIN WORKS

Slide 15

Slide 15 text

AdminSite ModelAdmin ChangeList

Slide 16

Slide 16 text

AdminSite ModelAdmin ChangeList

Slide 17

Slide 17 text

AdminSite ModelAdmin ChangeList

Slide 18

Slide 18 text

AdminSite encapsulates an instance of the Django admin application, ready to be hooked in to your URLconf.

Slide 19

Slide 19 text

site = AdminSite() AdminSite: URLs

Slide 20

Slide 20 text

url(r'^admin/', include(admin.site.urls)), AdminSite: URLs

Slide 21

Slide 21 text

super_awesome_site = AdminSite() 
 url(r’^super-awesome-admin/', 
 include(super_awesome_site.urls)), AdminSite: URLs

Slide 22

Slide 22 text

class AdminSite(object): … @property def urls(self): return self.get_urls(), ‘admin’, self.name AdminSite: URLs

Slide 23

Slide 23 text

class AdminSite(object): … @property def get_urls(self): # Admin-site-wide urls urlpatterns = [ url(r'^$', wrap(self.index), name='index'), url(r'^login/$', self.login, name='login'), url(r'^logout/$', wrap(self.logout), 
 name='logout'), … AdminSite: URLs

Slide 24

Slide 24 text

# Add in each model's views, and create a list of 
 # valid URLS for the app_index for model, model_admin in self._registry.items(): urlpatterns += [ url(r'^%s/%s/' % (model._meta.app_label, 
 model._meta.model_name), 
 include(model_admin.urls) ), ] AdminSite: URLs

Slide 25

Slide 25 text

AdminSite: model registry from django.contrib import admin admin.site.register(Author, AuthorAdmin)

Slide 26

Slide 26 text

AdminSite: model registry from django.contrib import admin admin.site.register(Author, AuthorAdmin) @admin.register(Author) class AuthorAdmin(admin.ModelAdmin):

Slide 27

Slide 27 text

AdminSite: model registry from django.contrib import admin admin.site.register(Author, AuthorAdmin) @admin.register(Author) class AuthorAdmin(admin.ModelAdmin): admin.site.register(Author)

Slide 28

Slide 28 text

AdminSite: model registry from django.contrib import admin admin.site.register(Author, AuthorAdmin) @admin.register(Author) class AuthorAdmin(admin.ModelAdmin): admin.site.register(Author) register(Author, list_display=(‘name’, ‘age’))

Slide 29

Slide 29 text

AdminSite: basic config class AdminSite(object): # Text to put at the end of each page's . site_title = ugettext_lazy('Django site admin') # Text to put in each page's

. site_header = ugettext_lazy('Django administration') # Text to put at the top of the admin index page. index_title = ugettext_lazy('Site administration')

Slide 30

Slide 30 text

ModelAdmin encapsulates all admin options and functionality for any given model.

Slide 31

Slide 31 text

ModelAdmin actions actions_on_top actions_on_bottom actions_selection_counter date_hierarchy exclude fields fieldsets filter_horizontal form formfield_overrides inlines list_display list_display_links list_editable list_filter list_max_show_all list_per_page list_select_related ordering paginator prepopulated_fields preserve_filters radio_fields raw_id_fields readonly_fields save_as save_on_top search_fields show_full_result_count view_on_site

Slide 32

Slide 32 text

ModelAdmin actions actions_on_top actions_on_bottom actions_selection_counter date_hierarchy exclude fields fieldsets filter_horizontal form formfield_overrides inlines list_display list_display_links list_editable list_filter list_max_show_all list_per_page list_select_related ordering paginator prepopulated_fields preserve_filters radio_fields raw_id_fields readonly_fields save_as save_on_top search_fields show_full_result_count view_on_site

Slide 33

Slide 33 text

No content

Slide 34

Slide 34 text

ModelAdmin actions actions_on_top actions_on_bottom actions_selection_counter date_hierarchy exclude fields fieldsets filter_horizontal form formfield_overrides inlines list_display list_display_links list_editable list_filter list_max_show_all list_per_page list_select_related ordering paginator prepopulated_fields preserve_filters radio_fields raw_id_fields readonly_fields save_as save_on_top search_fields show_full_result_count view_on_site

Slide 35

Slide 35 text

No content

Slide 36

Slide 36 text

ModelAdmin actions actions_on_top actions_on_bottom actions_selection_counter date_hierarchy exclude fields fieldsets filter_horizontal form formfield_overrides inlines list_display list_display_links list_editable list_filter list_max_show_all list_per_page list_select_related ordering paginator prepopulated_fields preserve_filters radio_fields raw_id_fields readonly_fields save_as save_on_top search_fields show_full_result_count view_on_site

Slide 37

Slide 37 text

No content

Slide 38

Slide 38 text

ModelAdmin actions actions_on_top actions_on_bottom actions_selection_counter date_hierarchy exclude fields fieldsets filter_horizontal form formfield_overrides inlines list_display list_display_links list_editable list_filter list_max_show_all list_per_page list_select_related ordering paginator prepopulated_fields preserve_filters radio_fields raw_id_fields readonly_fields save_as save_on_top search_fields show_full_result_count view_on_site

Slide 39

Slide 39 text

No content

Slide 40

Slide 40 text

ModelAdmin actions actions_on_top actions_on_bottom actions_selection_counter date_hierarchy exclude fields fieldsets filter_horizontal form formfield_overrides inlines list_display list_display_links list_editable list_filter list_max_show_all list_per_page list_select_related ordering paginator prepopulated_fields preserve_filters radio_fields raw_id_fields readonly_fields save_as save_on_top search_fields show_full_result_count view_on_site

Slide 41

Slide 41 text

ModelAdmin actions actions_on_top actions_on_bottom actions_selection_counter date_hierarchy exclude fields fieldsets filter_horizontal form formfield_overrides inlines list_display list_display_links list_editable list_filter list_max_show_all list_per_page list_select_related ordering paginator prepopulated_fields preserve_filters radio_fields raw_id_fields readonly_fields save_as save_on_top search_fields show_full_result_count view_on_site

Slide 42

Slide 42 text

No content

Slide 43

Slide 43 text

ModelAdmin actions actions_on_top actions_on_bottom actions_selection_counter date_hierarchy exclude fields fieldsets filter_horizontal form formfield_overrides inlines list_display list_display_links list_editable list_filter list_max_show_all list_per_page list_select_related ordering paginator prepopulated_fields preserve_filters radio_fields raw_id_fields readonly_fields save_as save_on_top search_fields show_full_result_count view_on_site

Slide 44

Slide 44 text

No content

Slide 45

Slide 45 text

ModelAdmin actions actions_on_top actions_on_bottom actions_selection_counter date_hierarchy exclude fields fieldsets filter_horizontal form formfield_overrides inlines list_display list_display_links list_editable list_filter list_max_show_all list_per_page list_select_related ordering paginator prepopulated_fields preserve_filters radio_fields raw_id_fields readonly_fields save_as save_on_top search_fields show_full_result_count view_on_site

Slide 46

Slide 46 text

AdminSite ModelAdmin ChangeList

Slide 47

Slide 47 text

Insides of the admin Magic tricks Future of the admin

Slide 48

Slide 48 text

No content

Slide 49

Slide 49 text

No content

Slide 50

Slide 50 text

No content

Slide 51

Slide 51 text

No content

Slide 52

Slide 52 text

No content

Slide 53

Slide 53 text

Advanced permissions • organizers can edit only their own events

Slide 54

Slide 54 text

No content

Slide 55

Slide 55 text

django-suit

Slide 56

Slide 56 text

Advanced permissions class EventAdmin(admin.ModelAdmin): list_display = ('name', 'organizers', ‘date') search_fields = ('city', 'country', 'name') def get_queryset(self, request): qs = super(EventAdmin, self).queryset(request) if request.user.is_superuser: return qs return qs.filter(team=request.user)

Slide 57

Slide 57 text

No content

Slide 58

Slide 58 text

No content

Slide 59

Slide 59 text

Advanced permissions def get_form(self, request, obj=None, **kwargs): form = super(EventPageContentAdmin, self).get_form(request, obj, **kwargs) if not request.user.is_superuser: if 'page' in form.base_fields: form.base_fields['page'].queryset = \ EventPage.objects.filter( event__team=request.user ) return form

Slide 60

Slide 60 text

No content

Slide 61

Slide 61 text

Advanced permissions • organizers can edit only their own events • organizers can edit only future
 events

Slide 62

Slide 62 text

ModelAdmin actions actions_on_top actions_on_bottom actions_selection_counter date_hierarchy exclude fields fieldsets filter_horizontal form formfield_overrides inlines list_display list_display_links list_editable list_filter list_max_show_all list_per_page list_select_related ordering paginator prepopulated_fields preserve_filters radio_fields raw_id_fields readonly_fields save_as save_on_top search_fields show_full_result_count view_on_site

Slide 63

Slide 63 text

Advanced permissions def get_readonly_fields(self, request, obj=None): if obj and not request.user.is_superuser: if not obj.page.event.is_upcoming(): return set( [x.name for x in self.model._meta.fields] ) return self.readonly_fields

Slide 64

Slide 64 text

No content

Slide 65

Slide 65 text

Custom method fields • display all organizers as list on ChangeList view

Slide 66

Slide 66 text

Custom method fields class EventAdmin(admin.ModelAdmin): list_display = ('name', ‘get_organizers’, ‘date') … def get_organizers(self, obj): members = [] for member in self.team.all(): members.append( u’{name} <{email}>’.format( member.get_full_name(), member.email ) ) return ', '.join(members) get_organizers.short_description = “Organizers”

Slide 67

Slide 67 text

No content

Slide 68

Slide 68 text

Custom method fields • display all organizers as list on ChangeList view • display status of the event

Slide 69

Slide 69 text

Custom method fields class EventAdmin(admin.ModelAdmin): list_display = ('name', ‘is_event_over’, ‘date') … def is_event_over(self, obj): return not obj.is_upcoming() is_event_over.boolean = True

Slide 70

Slide 70 text

No content

Slide 71

Slide 71 text

Custom method fields • display all organizers as list on ChangeList view • display status of the event • display images on a list in the ChangeList view

Slide 72

Slide 72 text

Custom method fields class EventAdmin(admin.ModelAdmin): list_display = ('name', ‘get_logo_display’, ‘date') … def get_logo_display(self, obj): if obj.logo: return ''.format(self.logo.url) else: return 'No logo!' get_logo_display.allow_tags = True

Slide 73

Slide 73 text

No content

Slide 74

Slide 74 text

Custom actions • a way to publish multiple events on the homepage with one click

Slide 75

Slide 75 text

No content

Slide 76

Slide 76 text

Custom method fields class EventAdmin(admin.ModelAdmin): list_display = ('name', ‘get_logo_display’, ‘date’) actions = [‘show_on_homepage’] … def show_on_homepage(self, request, queryset): queryset.update(is_on_homepage=True) show_on_homepage.short_description = "Publish selected”

Slide 77

Slide 77 text

DON’T FALL INTO the TRAP!

Slide 78

Slide 78 text

DON’T: Use Django Admin as your user facing interface

Slide 79

Slide 79 text

DON’T: Waste too much time trying to customize something

Slide 80

Slide 80 text

DO: Make your managers and admins lifes easier with small tricks +

Slide 81

Slide 81 text

DO: Make sure your admins can’t break the website with too much power ,

Slide 82

Slide 82 text

Insides of the admin Magic tricks Future of the admin

Slide 83

Slide 83 text

No content

Slide 84

Slide 84 text

I have to agree that the Django admin interface is dated and has some UI issues that could use work. — Jeff, May 2010

Slide 85

Slide 85 text

No content

Slide 86

Slide 86 text

pip install django-flat-theme

Slide 87

Slide 87 text

Diolch!

Slide 88

Slide 88 text

@olasitarska [email protected] Diolch!