django-admin-interface
django-admin-interface is a modern responsive flat admin interface customizable by the admin itself.
Features
- Beautiful default django-theme
- Themes management and customization (you can customize admin title, logo and colors)
- Responsive
- Related modal (instead of the old popup window)
- Environment name/marker
- Language chooser
- List filter dropdown
NEW
Foldable apps (accordions in the navigation bar)NEW
List filter stickyNEW
Form controls sticky (pagination and save/delete buttons)- Compatibility / Style optimizations for:
django-ckeditor
django-dynamic-raw-id
django-json-widget
django-modeltranslation
django-tabbed-admin
sorl-thumbnail
Installation
- Run
pip install django-admin-interface
- Add
admin_interface
,flat_responsive
,flat
andcolorfield
tosettings.INSTALLED_APPS
beforedjango.contrib.admin
INSTALLED_APPS = (
#...
'admin_interface',
'flat_responsive', # only if django version < 2.0
'flat', # only if django version < 1.9
'colorfield',
#...
'django.contrib.admin',
#...
)
# only if django version >= 3.0
X_FRAME_OPTIONS = 'SAMEORIGIN'
SILENCED_SYSTEM_CHECKS = ['security.W019']
- Run
python manage.py migrate
- Run
python manage.py collectstatic
- Restart your application server
Upgrade
- Run
pip install django-admin-interface --upgrade
- Run
python manage.py migrate
(add--fake-initial
if you are upgrading from 0.1.0 version) - Run
python manage.py collectstatic --clear
- Restart your application server
Optional themes
This package ships with optional themes as fixtures, they can be installed using the loaddata admin command. Optional themes are activated on installation.
Django theme (default):
Run python manage.py loaddata admin_interface_theme_django.json
Bootstrap theme:
Run python manage.py loaddata admin_interface_theme_bootstrap.json
Foundation theme:
Run python manage.py loaddata admin_interface_theme_foundation.json
U.S. Web Design Standards theme:
Run python manage.py loaddata admin_interface_theme_uswds.json
Add more themes
You can add a theme you've created through the admin to this repository by sending us a PR. Here are the steps to follow to add:
-
Export your exact theme as fixture using the
dumpdata
admin command:python manage.py dumpdata admin_interface.Theme --indent 4 -o admin_interface_theme_{{name}}.json --pks=N
-
Copy the generated json file into the fixtures folder (making sure its name starts with
admin_interface_theme_
to avoid clashes with fixtures that might be provided by other third party apps). -
Remove the
"pk"
from the fixture and make sure theactive
field is set totrue
(in this way a theme is automatically activated when installed). -
Edit the section above to document your theme.
Add theme support to third-party libraries
You can add theme support to existing third-party libraries using the following css variables:
--admin-interface-title-color
--admin-interface-logo-color
--admin-interface-env-color
--admin-interface-header-background-color:
--admin-interface-header-text-color
--admin-interface-header-link-color
--admin-interface-header-link_hover-color
--admin-interface-module-background-color
--admin-interface-module-background-selected-color
--admin-interface-module-text-color
--admin-interface-module-link-color
--admin-interface-module-link-selected-color
--admin-interface-module-link-hover-color
--admin-interface-generic-link-color
--admin-interface-generic-link-hover-color
--admin-interface-save-button-background-color
--admin-interface-save-button-background-hover-color
--admin-interface-save-button-text-color
--admin-interface-delete-button-background-color
--admin-interface-delete-button-background-hover-color
--admin-interface-delete-button-text-color
--admin-interface-related-modal-background-color
--admin-interface-related-modal-background-opacity
Screenshots
Admin login
Admin dashboard
Admin themes management
Admin theme customization
FAQ
base-site.html
Custom I already have a custom
base_site.html
, how can I make it work?
You can use django-apptemplates, then add {% extends "admin_interface:admin/base_site.html" %}
to your base_site.html
Language Chooser not showing
I have enabled the Language Chooser, but it is not visible in the admin, what should I do?
You must configure multilanguage settings
and urls
correctly:
LANGUAGES = (
('en', _('English')),
('it', _('Italiano')),
('fr', _('Française')),
# more than one language is expected here
)
LANGUAGE_CODE = 'en'
USE_I18N = True
MIDDLEWARE = [
# ...
'django.middleware.locale.LocaleMiddleware',
# ...
]
from django.conf.urls.i18n import i18n_patterns
from django.contrib import admin
from django.urls import include, path
# ...
urlpatterns = [
path('i18n/', include('django.conf.urls.i18n')),
]
urlpatterns += i18n_patterns(path('admin/', admin.site.urls))
Testing
# create python virtual environment
virtualenv testing_django_admin_interface
# activate virtualenv
cd testing_django_admin_interface && . bin/activate
# clone repo
git clone https://github.com/fabiocaccamo/django-admin-interface.git src && cd src
# install dependencies
pip install -r requirements.txt
pip install -r requirements-test.txt
# run tests
tox
# or
python setup.py test
# or
python -m django test --settings "tests.settings"
License
Released under MIT License.
See also
-
django-colorfield
- simple color field for models with a nice color-picker in the admin.🎨 -
django-extra-settings
- config and manage typed extra settings using just the django admin.⚙️ -
django-maintenance-mode
- shows a 503 error page when maintenance-mode is on.🚧 🛠️ -
django-redirects
- redirects with full control.↪️ -
django-treenode
- probably the best abstract model / admin for your tree based stuff.🌳 -
python-benedict
- dict subclass with keylist/keypath support, I/O shortcuts (base64, csv, json, pickle, plist, query-string, toml, xml, yaml) and many utilities.📘 -
python-codicefiscale
- encode/decode Italian fiscal codes - codifica/decodifica del Codice Fiscale.🇮🇹 💳 -
python-fontbro
- friendly font operations.🧢 -
python-fsutil
- file-system utilities for lazy devs.🧟♂️
post_migrate_handler
Python version 3.8
Django version 3.2.16
Package version 0.22.2
Current behavior (bug description) The current behavior of the post-migration signal (post_migrate_handler) does not take into account any routing of the databases
Workaround
Tabbed changeform
Related to #209
These are purely visual changes based on a boolean field.
Significant changes are,
show_fieldsets_as_tabs
&show_inlines_as_tabs
and it's migration.headless_*
version of fieldsets and inlines templates in order to hide the header. They are exact copies except for the title line.headerless_*
version of fieldset and inlines when in tabbed modePopup for related models creation fires a javascript error when "Related modal" is inactive
Python version Python 3.7.6
Django version Django 3.0.4
Package version django-admin-interface==0.12
Current behavior (bug description) The Popup for related models creation doesn't work when "Related modal" is inactive, due to this javascript error:
Expected behavior Since the standard Django admin is working correctly, this problem seems related to the presence of django-admin-interface.
I did a very basic setup of a simple Django project to reproduce the error in a simplified enrvironment.
The project and some screenshots to better explain the problem are available here:
https://github.com/morlandi/test-admin-interface
Refresh translations + add CI check
I recreated translations last week and noticed many changes.
Files should be regenerated so that translators can update translations. I will contribute French!
Replace travis with github actions
Most projects have left Travis because of the management issues. It seems that tests for PRs here are not run any more. I could convert the config to github actions (example conversions from circleci: https://github.com/caravancoop/configstore/pull/47)
Unreadable text in autocomplete multi-selects
Python version 3.8
Django version 3.0.6
Package version 0.12.2
Current behavior (bug description) In a multi-select field using autocomplete (django admin feature), selected options are not readable. Django’s autocomplete.css sets a white font color, django-admin-interface inline CSS defines white background color.
Expected behavior Text should be readable :slightly_smiling_face: I am not sure if the background or text color should change, though; should probably match the behaviour of custom selects.
A quick workaround:
Cache admin settings
Each call to
Theme.get_active_theme
makes multiple database calls. Unfortunately, that's called in theget_admin_interface_theme
template tag, which appears multiple times on each admin page render.We should cache these calls at least per request to speed up performance.
Left/right scrolling broken with django-import-export
I'm not sure which repo to open this issue on, but when using django-import-export, after importing it takes you to a big table that shows the before & after. With this theme enabled, there is no ability to scroll left and right to see those changes.
Issue on the other side, just in case: https://github.com/django-import-export/django-import-export/issues/1476
migrate fails at "change_related_modal_background_opacity_type"
Hi there. Thanks for the great interface. I'm trying to migrate from a function setup with Python 3.6, Django 2.1.5, and admin-interface 0.9.1 . When I run migrate on my development computer I end up with the following traceback. I'm happy to help debug but the process of debugging if I can.
` Applying admin_interface.0008_change_related_modal_background_opacity_type...Traceback (most recent call last): File "/home/ace/.local/share/virtualenvs/website-10j77PrM/lib/python3.6/site-packages/django/db/backends/utils.py", line 85, in _execute return self.cursor.execute(sql, params) psycopg2.OperationalError: server closed the connection unexpectedly This probably means the server terminated abnormally before or while processing the request.
The above exception was the direct cause of the following exception:
Traceback (most recent call last): File "/home/ace/.local/share/virtualenvs/website-10j77PrM/lib/python3.6/site-packages/django/db/migrations/executor.py", line 244, in apply_migration state = migration.apply(state, schema_editor) File "/home/ace/.local/share/virtualenvs/website-10j77PrM/lib/python3.6/site-packages/django/db/migrations/migration.py", line 124, in apply operation.database_forwards(self.app_label, schema_editor, old_state, project_state) File "/home/ace/.local/share/virtualenvs/website-10j77PrM/lib/python3.6/site-packages/django/db/migrations/operations/fields.py", line 216, in database_forwards schema_editor.alter_field(from_model, from_field, to_field) File "/home/ace/.local/share/virtualenvs/website-10j77PrM/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 523, in alter_field old_db_params, new_db_params, strict) File "/home/ace/.local/share/virtualenvs/website-10j77PrM/lib/python3.6/site-packages/django/db/backends/postgresql/schema.py", line 122, in _alter_field new_db_params, strict, File "/home/ace/.local/share/virtualenvs/website-10j77PrM/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 663, in _alter_field params, File "/home/ace/.local/share/virtualenvs/website-10j77PrM/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 133, in execute cursor.execute(sql, params) File "/home/ace/.local/share/virtualenvs/website-10j77PrM/lib/python3.6/site-packages/django/db/backends/utils.py", line 100, in execute return super().execute(sql, params) File "/home/ace/.local/share/virtualenvs/website-10j77PrM/lib/python3.6/site-packages/django/db/backends/utils.py", line 68, in execute return self._execute_with_wrappers(sql, params, many=False, executor=self._execute) File "/home/ace/.local/share/virtualenvs/website-10j77PrM/lib/python3.6/site-packages/django/db/backends/utils.py", line 77, in _execute_with_wrappers return executor(sql, params, many, context) File "/home/ace/.local/share/virtualenvs/website-10j77PrM/lib/python3.6/site-packages/django/db/backends/utils.py", line 85, in _execute return self.cursor.execute(sql, params) File "/home/ace/.local/share/virtualenvs/website-10j77PrM/lib/python3.6/site-packages/django/db/utils.py", line 89, in exit raise dj_exc_value.with_traceback(traceback) from exc_value File "/home/ace/.local/share/virtualenvs/website-10j77PrM/lib/python3.6/site-packages/django/db/backends/utils.py", line 85, in _execute return self.cursor.execute(sql, params) django.db.utils.OperationalError: server closed the connection unexpectedly This probably means the server terminated abnormally before or while processing the request.
During handling of the above exception, another exception occurred:
Traceback (most recent call last): File "/home/ace/.local/share/virtualenvs/website-10j77PrM/lib/python3.6/site-packages/django/db/backends/base/base.py", line 216, in ensure_connection self.connect() File "/home/ace/.local/share/virtualenvs/website-10j77PrM/lib/python3.6/site-packages/django/db/backends/base/base.py", line 194, in connect self.connection = self.get_new_connection(conn_params) File "/home/ace/.local/share/virtualenvs/website-10j77PrM/lib/python3.6/site-packages/django/db/backends/postgresql/base.py", line 178, in get_new_connection connection = Database.connect(**conn_params) File "/home/ace/.local/share/virtualenvs/website-10j77PrM/lib/python3.6/site-packages/psycopg2/init.py", line 130, in connect conn = _connect(dsn, connection_factory=connection_factory, **kwasync) psycopg2.OperationalError: FATAL: the database system is in recovery mode
The above exception was the direct cause of the following exception:
Traceback (most recent call last): File "manage.py", line 30, in
execute_from_command_line(sys.argv)
File "/home/ace/.local/share/virtualenvs/website-10j77PrM/lib/python3.6/site-packages/django/core/management/init.py", line 381, in execute_from_command_line
utility.execute()
File "/home/ace/.local/share/virtualenvs/website-10j77PrM/lib/python3.6/site-packages/django/core/management/init.py", line 375, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/ace/.local/share/virtualenvs/website-10j77PrM/lib/python3.6/site-packages/django/core/management/base.py", line 316, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/ace/.local/share/virtualenvs/website-10j77PrM/lib/python3.6/site-packages/django/core/management/base.py", line 353, in execute
output = self.handle(*args, **options)
File "/home/ace/.local/share/virtualenvs/website-10j77PrM/lib/python3.6/site-packages/django/core/management/base.py", line 83, in wrapped
res = handle_func(*args, **kwargs)
File "/home/ace/.local/share/virtualenvs/website-10j77PrM/lib/python3.6/site-packages/django/core/management/commands/migrate.py", line 203, in handle
fake_initial=fake_initial,
File "/home/ace/.local/share/virtualenvs/website-10j77PrM/lib/python3.6/site-packages/django/db/migrations/executor.py", line 117, in migrate
state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
File "/home/ace/.local/share/virtualenvs/website-10j77PrM/lib/python3.6/site-packages/django/db/migrations/executor.py", line 147, in _migrate_all_forwards
state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
File "/home/ace/.local/share/virtualenvs/website-10j77PrM/lib/python3.6/site-packages/django/db/migrations/executor.py", line 244, in apply_migration
state = migration.apply(state, schema_editor)
File "/home/ace/.local/share/virtualenvs/website-10j77PrM/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 108, in exit
self.atomic.exit(exc_type, exc_value, traceback)
File "/home/ace/.local/share/virtualenvs/website-10j77PrM/lib/python3.6/site-packages/django/db/transaction.py", line 256, in exit
connection.set_autocommit(True)
File "/home/ace/.local/share/virtualenvs/website-10j77PrM/lib/python3.6/site-packages/django/db/backends/base/base.py", line 394, in set_autocommit
self.ensure_connection()
File "/home/ace/.local/share/virtualenvs/website-10j77PrM/lib/python3.6/site-packages/django/db/backends/base/base.py", line 216, in ensure_connection
self.connect()
File "/home/ace/.local/share/virtualenvs/website-10j77PrM/lib/python3.6/site-packages/django/db/utils.py", line 89, in exit
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/home/ace/.local/share/virtualenvs/website-10j77PrM/lib/python3.6/site-packages/django/db/backends/base/base.py", line 216, in ensure_connection
self.connect()
File "/home/ace/.local/share/virtualenvs/website-10j77PrM/lib/python3.6/site-packages/django/db/backends/base/base.py", line 194, in connect
self.connection = self.get_new_connection(conn_params)
File "/home/ace/.local/share/virtualenvs/website-10j77PrM/lib/python3.6/site-packages/django/db/backends/postgresql/base.py", line 178, in get_new_connection
connection = Database.connect(**conn_params)
File "/home/ace/.local/share/virtualenvs/website-10j77PrM/lib/python3.6/site-packages/psycopg2/init.py", line 130, in connect
conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
django.db.utils.OperationalError: FATAL: the database system is in recovery `mode``
CSS as FileField in `Theme` model
Hello,
I have seen that the
Theme
model allow to "inject" raw css through itscss
attribute. However it is a TextField and it is not so easy to use in practice (for instance we need to inline the css code in the json fixture). I think it could be great to either turn this field into a FileField or to add a new FileField attribute likecss_file
. Of course I can help through a PR :)Show active filters at the top of the sidebar with clear button
On a list page with many filters shown and the dropdown option active, admin users have a hard time finding out which filters are currently active, in order to remove one for example if the current selection has no results. They would have to go through the list and determine if the value visible is the default or not, so they end up clearing all filters (it’s the only action displayed) and re-building their selection.
#174 improves the visibility and #175 fixes a usability issue. This proposes a new theme option to also display current filters at the top of the sidebar, wich a link to remove each filter: ( x Age: 9+ ) ( x Group: 10-15 ) ( x Clear all filters ) (parens to represent a chip widget)
Used slugify template tag for tabs not working with non-ASCII alphanumeric characters
Hello, Thank you for your amazing django package
When used slugify template tag for tabs not working with non-ASCII alphanumeric characters
https://github.com/fabiocaccamo/django-admin-interface/blob/8d82d80c19f76f409f75456bf974966f6d8295a2/admin_interface/templates/admin/change_form.html#L21
instated you can used forloop counter
used tab with loop of counter for fieldset
used itab with loop counter for inlines formset
this is full patch code:
Dashboard feature
When building django admin apps, it is usually nice to have a custom dashboard to display extra data.
Take a look a
django-unfold
package and see how that is achieved, it'll be nice to have something similar.Initial changes for Dark mode :
Related to #129
This PR lays the ground work for using a proper dark mode. This PR is meant to validate and allow two separate themes at the same time
active_dark
to designate a theme to be used for dark modebase_site.html
into separate file that is includedThemeQueryset
, model function and signals to handle foruse_dark
TODO in a different PR :
Add new `css_generic_link_active_color` field to use on active tab (tabbed changeform).
Originally posted by @fabiocaccamo in https://github.com/fabiocaccamo/django-admin-interface/issues/231#issuecomment-1352912993
Custom Admin Page
Hello !! I've recently discovered this project in my quest to reuse the admin page as much as possible for a minimal backoffice. I love that ability to theme and all the little features like dropdown for filters that make a big difference to UX.
Requested feature Do you have any plans on adding support for a custom Admin Page?
Feature context Currently, I am hitting a wall with the reusability of the admin. I'd like to make custom pages with a custom queryset in order to have custom pages for KPIs and charts, internal forms and tiny little backoffice features.
A quick look at the code shows me that it needs to be an
admin_view
or tied to BaseModelAdmin. I'm currently working on trying to replicate it but it's a wip and I'm pretty lost hahaWhat it brings to project This would be a major differentiator against the standard admin. Since, django admin comes loaded with default widgets and permissons, there is far less logic to be written if we need only a few custom pages for a backoffice.
Other solutions : I've taken a look at django-admin-views but I'm not been able to get it working so far. (I've raised a bug report at the moment)
Sticky table header and columns (action checkbox column and first field column).
It would be very useful having the possibility to set sticky table columns in the changelist (action checkbox column if actions are enabled +
list_display_links
columns), and also in the tabular inlines table.This feature would improve tables UX, especially when there is horizontal scroll.
NOTE: should test also with RTL languages.