4.1. Admin panel¶
4.1.1. Customizing¶
from django.contrib import admin
from django.utils.translation import gettext_lazy as _
admin.site.site_header = _('HabitatOS')
admin.site.index_title = _('Dashboard')
admin.site.site_title = _('HabitatOS')
4.1.2. Permissions¶
4.1.3. Users¶
4.1.4. Groups¶
4.1.5. Content Types¶
4.1.6. Model Admin¶
admin.ModelAdmin
4.1.7. Model registering¶
@admin.register(...)
4.1.8. Admin fields¶
readonly_fields
search (
^
,=
,@
)ordering
list_filter
4.1.9. Writing own list_filter
¶
from django.contrib import admin
from django.utils.translation import gettext_lazy as _
class AgeFilter(admin.SimpleListFilter):
# Human-readable title which will be displayed in the
# right admin sidebar just above the filter options.
title = _('Age')
# Parameter for the filter that will be used in the URL query.
parameter_name = 'age'
def lookups(self, request, model_admin):
return [
('None', _('Not Specified')),
('0-10', _('0-10')),
('11-20', _('11-20')),
('21-30', _('21-30')),
('31-40', _('31-40')),
('41-50', _('41-50')),
('51-60', _('51-60')),
('Older', _('Older')),
]
def queryset(self, request, queryset):
if self.value() == 'None':
return queryset.filter(date_of_birth=None)
4.1.10. Model Inlines¶
4.1.11. StackedInline¶
4.1.12. TabularInline¶
4.1.13. Extending Admin¶
4.1.14. Media Class¶
class Media:
js = [
'communication/js/email-reply-button.js',
'communication/js/email-hide-save.js',
]
css = {'all': [
'communication/css/hide-id-field.css',
'communication/css/resize-fields.css',
]}
4.1.15. ModelAdmin Example¶
from django.contrib import admin
from django.utils.translation import gettext_lazy as _
@admin.register(Person)
class PersonAdmin(admin.ModelAdmin):
list_display = ['lastname', 'firstname', 'date_of_birth', 'column_age']
list_display_links = ['lastname']
search_fields = ['^lastname']
list_filter = ['created', 'modified', AgeFilter]
inlines = [AddressInline]
exclude = ['reporter', 'created', 'updated']
readonly_fields = []
ordering = ['lastname', 'firstname']
autocomplete_fields = ['friends']
fieldsets = [
(_('Personal Data'), {'fields': ['lastname', 'firstname', 'date_of_birth', 'gender']}),
(_('Additional Data'), {'fields': ['email', 'bio', 'image']}),
(_('Relations'), {'fields': ['status', 'friends']})]
radio_fields = {
'gender': admin.HORIZONTAL,
'status': admin.VERTICAL}
# formfield_overrides = {models.ManyToManyField: {'widget': CheckboxSelectMultiple}}
def get_list_display(self, request):
list_display = super().get_list_display(request)
if request.user.is_superuser and 'is_deleted' not in list_display:
list_display += ['is_deleted']
return list_display
def get_queryset(self, request):
queryset = super().get_queryset(request)
if request.user.is_superuser:
return queryset
else:
return queryset.filter(is_deleted=False)
def column_age(self, obj):
age = obj.get_age()
return str(age) if age else ''
# https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_display
column_age.short_description = _('Age')
column_age.empty_value_display = ''
column_age.admin_order_field = 'date_of_birth'
def save_model(self, request, obj, form, change):
obj.reporter = request.user
super().save_model(request, obj, form, change)
class Media:
js = [
'contact/js/alert.js',
]
css = {'all': [
'contact/css/style.css',
]}
4.1.16. django-import-export
¶
$ pip install django-import-export
# settings.py
INSTALLED_APPS += ['import_export']
# <app>/admin.py
from import_export.admin import ImportExportModelAdmin
@admin.register(Command)
class CommandAdmin(ImportExportModelAdmin):
pass
4.1.17. Grapelli¶
4.1.18. Installation¶
$ pip install django-grapelli
dodanie do INSTALLED_APPS
INSTALLED_APPS = [
'grappelli.dashboard',
'grappelli',
]
dodanie do urls
from django.conf.urls import url
from django.conf.urls import include
from django.contrib import admin
urlpatterns += [
url(r'^grappelli/', include('grappelli.urls'), name='grappelli'),
url(r'^', admin.site.urls, name='admin'),
]
4.1.19. Settings¶
GRAPPELLI_SWITCH_USER = True
GRAPPELLI_ADMIN_TITLE = _('HabitatOS')
GRAPPELLI_INDEX_DASHBOARD = 'habitat.dashboard.aatc.AdminDashboard'
GRAPPELLI_AUTOCOMPLETE_SEARCH_FIELDS = {
'auth': {
'user': ['username__icontains']
}
}
from django.utils.translation import gettext_lazy as _
from grappelli.dashboard import Dashboard
from grappelli.dashboard import modules
class AdminDashboard(Dashboard):
def init_with_context(self, context):
# Column 1
self.children.append(modules.ModelList(
title=_('Questionnaires - Visible only to you'),
column=1,
collapsible=False,
models=[
'habitat.reporting.models.mood.Mood',
'habitat.reporting.models.sociodynamics.SociodynamicReport',
'habitat.reporting.models.sleep.Sleep']))
self.children.append(modules.ModelList(
title=_('Health - Visible only to you'),
column=1,
collapsible=False,
models=[
'habitat.health.models.blood_pressure.BloodPressure',
'habitat.health.models.urine.Urine',
'habitat.health.models.temperature.Temperature',
'habitat.health.models.weight.Weight']))
# Column 2
self.children.append(modules.ModelList(
title=_('Communication'),
column=2,
collapsible=False,
models=[
'habitat.communication.models.email.Email']))
self.children.append(modules.ModelList(
title=_('Reporting - Visible to anyone'),
column=2,
collapsible=False,
models=[
'habitat.reporting.models.daily.Daily',
'habitat.reporting.models.repair.Repair',
'habitat.reporting.models.incident.Incident',
'habitat.reporting.models.waste.Waste',
'habitat.communication.models.diary.DiaryEntry',
'habitat.extravehicular.models.activity.Activity']))
self.children.append(modules.ModelList(
title=_('Water - Visible to anyone'),
column=2,
collapsible=False,
models=[
'habitat.water.models.technical.TechnicalWater',
'habitat.water.models.drinking.DrinkingWater',
'habitat.water.models.green.GreenWater']))
# Column 3
if context['user'].has_perm('admin.add_user'):
self.children.append(modules.ModelList(
title=_('Administration'),
column=3,
collapsible=True,
models=['django.contrib.*'],
css_classes=['grp-closed']))
self.children.append(modules.LinkList(
title=_('Shortcuts'),
collapsible=False,
column=3,
children=[
{'title': _('Schedule'), 'url': '/api/v1/dashboard/schedule/'},
{'title': _('Martian Clock Converter'), 'url': '/api/v1/timezone/martian-standard-time/converter/'},
{'title': _('Subjective Time Perception'), 'url': 'http://time.astrotech.io'},
]))
self.children.append(modules.ModelList(
title=_('Sensors'),
column=3,
collapsible=False,
models=[
'habitat.sensors.models.zwave_sensor.ZWaveSensor']))
4.1.20. Template overwrite¶
change_list_template = 'admin/change_list_import_export.html'
change_list_filter_template = 'admin/filter_listing.html'