Compare commits

...

85 Commits

Author SHA1 Message Date
Fabio Caccamo c784a083f3 Updated version 2017-04-14 13:13:30 +02:00
Fabio Caccamo d1c912e875 Added django 1.11 support 2017-04-14 13:13:12 +02:00
Fabio Caccamo e9e950dda3 Fix error message margin left 2017-04-04 18:09:17 +02:00
Fabio Caccamo 3c4ea399e2 Updated version 2017-03-29 18:57:11 +02:00
Fabio Caccamo a28fe1c5e0 Improved Theme.get_active_theme method 2017-03-29 18:57:01 +02:00
Fabio Caccamo c07a846374 Updated README requirements and added badges 2017-03-29 16:32:52 +02:00
Fabio Caccamo f0126fb407 Updated version 2017-03-29 16:24:22 +02:00
Fabio Caccamo 869ae626da Added tox and travis 2017-03-29 16:22:34 +02:00
Fabio Caccamo a6bdb2b36d Updated setup.py 2017-03-29 16:22:09 +02:00
Fabio Caccamo aa18e19625 Added tests 2017-03-29 16:21:41 +02:00
Fabio Caccamo a35f8d0fb7 Dropped django < 1.7 support 2017-03-29 16:21:02 +02:00
Fabio Caccamo d29515c4ae Code refactoring 2017-03-29 16:20:07 +02:00
Fabio Caccamo 00f60c222d Fixed README syntax 2017-03-21 17:12:11 +01:00
Fabio Caccamo ff2d05e44c Fixed changelist filter header style 2017-02-16 11:30:44 +01:00
Fabio Caccamo 6e5cbf3a2c Fixed tools button focus color 2017-02-16 11:29:56 +01:00
Fabio Caccamo 55b365b2e4 Updated version 2017-02-09 16:25:25 +01:00
Fabio Caccamo 3203b437df Added horizontal scroll to long inlines to prevent full page scroll 2017-02-09 16:08:50 +01:00
Fabio Caccamo 202b5fa4aa Changed inlines delete buttons alignement 2017-02-09 16:07:52 +01:00
Fabio Caccamo 9fdc3a0268 Fixed help text alignement in wide inlines 2017-02-09 16:04:40 +01:00
Fabio Caccamo ded2fee89c Fixed issue #13 - Datetime widget broken in long inlines 2017-02-09 15:08:58 +01:00
Fabio Caccamo beec7242c6 Removed old code and added comment to previous fix 2017-02-09 15:08:37 +01:00
Fabio Caccamo 7a6a29b110 Fixed issue #12 - Inlines bad delete buttons alignement 2017-02-09 14:44:26 +01:00
Fabio Caccamo 1f3bb6514c Fixed issue #10 - Related widget broken in long tabular inline 2017-02-09 13:03:00 +01:00
Fabio Caccamo b416b46c5a Updated dynamic css indentation 2017-02-09 12:51:49 +01:00
Fabio Caccamo 59f1831cbd Fixed issue #11 - Inline border bottom should not be rounded 2017-02-09 12:50:36 +01:00
Fabio Caccamo 20050e2964 Removed duplicated code 2017-02-09 12:40:49 +01:00
Fabio Caccamo fd292ed1bf Fixed help text alignement in wide inlines 2017-02-07 16:06:05 +01:00
Fabio Caccamo fac0f690df Fixed breadcrumbs link focus color 2017-02-07 15:59:17 +01:00
Fabio Caccamo d18aadd93d Updated dependencies 2017-02-07 15:58:45 +01:00
Fabio Caccamo 9350575898 Updated setup.py 2016-11-08 12:18:35 +01:00
Fabio Caccamo 4789ee1dab Updated README.md 2016-11-08 12:18:19 +01:00
Fabio Caccamo a924c6cf5e Updated version 2016-11-08 12:17:53 +01:00
Fabio Caccamo 42b6e01f1f Added responsive support 2016-11-08 12:17:24 +01:00
Fabio Caccamo d7fa681c56 Fixed login padding 2016-11-08 12:15:42 +01:00
Fabio Caccamo 18e1425156 Updated version 2016-09-10 18:49:31 +02:00
Fabio Caccamo 1f39ceb0ad Fixed missing admin title #7 2016-09-10 18:49:20 +02:00
Fabio Caccamo 48cb73a604 Updated version 2016-09-04 18:44:07 +02:00
Fabio Caccamo c5bbbbc855 Updated README 2016-09-04 18:43:55 +02:00
Fabio Caccamo 793a019460 Fixed buttons color on focus and removed outline. 2016-09-04 18:43:29 +02:00
Fabio Caccamo 674178ecbe Updated README 2016-08-05 10:37:36 +02:00
Fabio Caccamo 07a51c1678 Updated version 2016-08-05 10:37:24 +02:00
Fabio Caccamo a58605a385 Renamed var 2016-08-05 10:36:59 +02:00
Fabio Caccamo e1d2c81ebe Merge pull request #6 from cereigido/master
Adding filename to File for Django 1.10 compatibility
2016-08-05 10:17:22 +02:00
Paulo Cereigido e5e55bdfcd adding filename to File from Django 1.10 compatibility 2016-08-05 01:29:53 -03:00
Fabio Caccamo f6ce51c839 Updated README.md 2016-07-12 18:55:01 +02:00
Fabio Caccamo b4b19650f1 Updated version 2016-06-29 16:05:34 +02:00
Fabio Caccamo 3d4f249487 Improved backward compatibility with South 2016-06-29 16:05:13 +02:00
Fabio Caccamo 7c236c6641 Updated version and dependencies version 2016-04-13 17:25:54 +02:00
Fabio Caccamo 91b3809d61 Improved sorl-thumbnail AdminImageMixin widget layout 2016-04-12 18:03:50 +02:00
Fabio Caccamo f918551971 Fixed login logo overflow 2016-04-11 17:53:50 +02:00
Fabio Caccamo 149c95311f Updated README.md 2016-04-11 12:56:09 +02:00
Fabio Caccamo 858f077bd4 Updated README.md 2016-03-01 12:05:06 +01:00
Fabio Caccamo e46daa8f99 Updated README 2016-02-24 10:14:26 +01:00
Fabio Caccamo e3320b2034 Updated LICENSE 2016-02-24 10:12:32 +01:00
Fabio Caccamo 8991863fb1 Updated README 2016-02-24 10:11:54 +01:00
Fabio Caccamo 54f120c9ba Updated version 2016-02-24 10:04:49 +01:00
Fabio Caccamo 816c05bebd Cleaned whitespace 2016-02-24 10:04:35 +01:00
Fabio Caccamo 710370e903 Fixed Django 1.9 support 2016-02-24 10:03:19 +01:00
Fabio Caccamo 10476e5675 Updated version 2016-02-15 16:21:27 +01:00
Fabio Caccamo bb5867460f Added django-flat-theme dependency 2016-02-15 16:21:16 +01:00
Fabio Caccamo 0ed341bdfd Cleaned white-space 2016-02-15 16:20:53 +01:00
Fabio Caccamo dd8a556d79 Fixed list filter selected link color 2016-02-15 16:20:35 +01:00
Fabio Caccamo f1c37feacb Improved fieldsets alignment and links colors 2016-02-15 16:01:28 +01:00
Fabio Caccamo 6b05143bcc Updated README.md 2015-12-03 11:53:47 +01:00
Fabio Caccamo 9f22ce4b70 Updated package description 2015-12-03 11:46:43 +01:00
Fabio Caccamo 12078589aa Updated version 2015-12-03 11:45:37 +01:00
Fabio Caccamo 98d7153b24 Added admin-interface and flat-theme body classes 2015-12-03 11:44:34 +01:00
Fabio Caccamo d702b0a328 Updated README.md 2015-11-26 11:25:07 +01:00
Fabio Caccamo 8bc899f107 Updated README.md 2015-11-26 11:24:44 +01:00
Fabio Caccamo 48a226ca9f Updated version 2015-11-25 19:27:06 +01:00
Fabio Caccamo 8752520ebe Fixed dashboard modules links color 2015-11-25 19:26:31 +01:00
Fabio Caccamo a006fef0e0 Removed duplicated css rules 2015-11-25 19:25:29 +01:00
Fabio Caccamo a18ec73656 Add migrations 2015-11-25 19:07:03 +01:00
Fabio Caccamo 40cf1daa84 Added .gitattributes 2015-11-19 11:04:47 +01:00
Fabio Caccamo 15ca13c98a Updated README.md 2015-11-18 12:44:04 +01:00
Fabio Caccamo 5b8ad7b04b Update README.md 2015-11-17 16:09:26 +01:00
Fabio Caccamo 690924df51 Updated README.md 2015-11-17 10:42:44 +01:00
Fabio Caccamo 7a57b35554 Updated README.md 2015-11-16 12:22:50 +01:00
Fabio Caccamo 6b92499395 Updated LICENSE.txt 2015-11-16 12:22:29 +01:00
Fabio Caccamo f38ca148e6 Updated README.md 2015-11-16 11:10:25 +01:00
Fabio Caccamo 01e7f05ca1 Updated README.md 2015-11-16 11:08:04 +01:00
Fabio Caccamo 385602ac5f Updated README.md 2015-11-16 11:07:15 +01:00
Fabio Caccamo e392341591 Updated README.md 2015-11-13 19:00:36 +01:00
Fabio Caccamo ea36322ca1 Updated README.md 2015-11-13 18:50:10 +01:00
Fabio Caccamo 4a45afed18 Updated README.md 2015-11-13 17:10:17 +01:00
18 changed files with 684 additions and 233 deletions
+1
View File
@@ -0,0 +1 @@
admin_interface/static/ckeditor/* linguist-vendored
+22
View File
@@ -0,0 +1,22 @@
language: python
python: 3.5
env:
- TOX_ENV=py27-17
- TOX_ENV=py27-18
- TOX_ENV=py27-19
- TOX_ENV=py27-110
- TOX_ENV=py34-17
- TOX_ENV=py34-18
- TOX_ENV=py34-19
- TOX_ENV=py34-110
- TOX_ENV=py35-18
- TOX_ENV=py35-19
- TOX_ENV=py35-110
#- TOX_ENV=py36-18
#- TOX_ENV=py36-19
#- TOX_ENV=py36-110
install:
- pip install tox
script:
- tox -e $TOX_ENV
sudo: false
+1 -1
View File
@@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2015 Fabio Cacccamo - fabio.caccamo@gmail.com
Copyright (c) 2016 Fabio Caccamo - fabio.caccamo@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+53
View File
@@ -1 +1,54 @@
[![Build Status](https://travis-ci.org/fabiocaccamo/django-admin-interface.svg?branch=master)](https://travis-ci.org/fabiocaccamo/django-admin-interface)
[![codecov](https://codecov.io/gh/fabiocaccamo/django-admin-interface/branch/master/graph/badge.svg)](https://codecov.io/gh/fabiocaccamo/django-admin-interface)
[![PyPI version](https://badge.fury.io/py/django-admin-interface.svg)](https://badge.fury.io/py/django-admin-interface)
[![Py versions](https://img.shields.io/pypi/pyversions/django-admin-interface.svg)](https://img.shields.io/pypi/pyversions/django-admin-interface.svg)
[![License](https://img.shields.io/pypi/l/django-admin-interface.svg)](https://img.shields.io/pypi/l/django-admin-interface.svg)
# django-admin-interface
django-admin-interface is a modern **responsive flat admin interface customizable by the admin itself**.
You can use the builtin **django-theme** or create your own and **customize** **title, logo and colors**.
## Requirements
- Python 2.7, 3.4, 3.5, 3.6
- Django 1.7, 1.8, 1.9, 1.10
## Installation
- Run `pip install django-admin-interface`
- Add `admin_interface`, `flat_responsive`, `flat` and `colorfield` to `settings.INSTALLED_APPS` **before** `django.contrib.admin`
```python
INSTALLED_APPS = (
#...
'admin_interface',
'flat_responsive',
'flat', #if django version < 1.9
'colorfield',
#...
'django.contrib.admin',
#...
)
```
- Run ``python manage.py migrate`` *(add ``--fake-initial`` if you are upgrading from 0.1.0 version)*
- Run ``python manage.py collectstatic``
- Restart your application server
## Screenshots
###### Admin login
![django-admin-interface_login](https://cloud.githubusercontent.com/assets/1035294/11240233/55c8d4ba-8df1-11e5-9568-00fdc987ede8.gif)
---
###### Admin dashboard
![django-admin-interface_dashboard](https://cloud.githubusercontent.com/assets/1035294/11240239/627c0362-8df1-11e5-81fa-216366a5d8da.gif)
---
###### Admin themes management
![django-admin-interface_themes_management](https://cloud.githubusercontent.com/assets/1035294/11240245/6cd1c342-8df1-11e5-928b-f22217474d3d.gif)
---
###### Admin theme customization
![django-admin-interface_theme_customization](https://cloud.githubusercontent.com/assets/1035294/11240250/7350d942-8df1-11e5-9b28-f2f54c333cdc.gif)
#### Thanks
- [django-flat-theme](https://github.com/elky/django-flat-theme/)
- [django-flat-responsive](https://github.com/elky/django-flat-responsive)
- [django-colorfield](https://github.com/jaredly/django-colorfield/)
## License
Released under [MIT License](LICENSE).
+1 -3
View File
@@ -3,8 +3,6 @@
from django.apps import AppConfig
from django.db.models.signals import post_migrate
from admin_interface.models import Theme
class AdminInterfaceConfig(AppConfig):
@@ -13,6 +11,6 @@ class AdminInterfaceConfig(AppConfig):
def ready(self):
from admin_interface.models import Theme
post_migrate.connect(Theme.post_migrate_handler, sender = self)
@@ -0,0 +1,50 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
import colorfield.fields
class Migration(migrations.Migration):
dependencies = [
]
operations = [
migrations.CreateModel(
name='Theme',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('name', models.CharField(default=b'Django', max_length=50)),
('active', models.BooleanField(default=True)),
('title', models.CharField(default=b'Django administration', max_length=50, blank=True)),
('title_visible', models.BooleanField(default=True, verbose_name=b'visible')),
('logo', models.FileField(upload_to=b'admin-interface/logo/', blank=True)),
('logo_visible', models.BooleanField(default=True, verbose_name=b'visible')),
('css_header_background_color', colorfield.fields.ColorField(default=b'#0C4B33', help_text=b'#0C4B33', max_length=10, verbose_name=b'background color', blank=True)),
('css_header_title_color', colorfield.fields.ColorField(default=b'#F5DD5D', help_text=b'#F5DD5D', max_length=10, verbose_name=b'title color', blank=True)),
('css_header_text_color', colorfield.fields.ColorField(default=b'#44B78B', help_text=b'#44B78B', max_length=10, verbose_name=b'text color', blank=True)),
('css_header_link_color', colorfield.fields.ColorField(default=b'#FFFFFF', help_text=b'#FFFFFF', max_length=10, verbose_name=b'link color', blank=True)),
('css_header_link_hover_color', colorfield.fields.ColorField(default=b'#C9F0DD', help_text=b'#C9F0DD', max_length=10, verbose_name=b'link hover color', blank=True)),
('css_module_background_color', colorfield.fields.ColorField(default=b'#44B78B', help_text=b'#44B78B', max_length=10, verbose_name=b'background color', blank=True)),
('css_module_text_color', colorfield.fields.ColorField(default=b'#FFFFFF', help_text=b'#FFFFFF', max_length=10, verbose_name=b'text color', blank=True)),
('css_module_link_color', colorfield.fields.ColorField(default=b'#FFFFFF', help_text=b'#FFFFFF', max_length=10, verbose_name=b'link color', blank=True)),
('css_module_link_hover_color', colorfield.fields.ColorField(default=b'#C9F0DD', help_text=b'#C9F0DD', max_length=10, verbose_name=b'link hover color', blank=True)),
('css_module_rounded_corners', models.BooleanField(default=True, verbose_name=b'rounded corners')),
('css_generic_link_color', colorfield.fields.ColorField(default=b'#0C3C26', help_text=b'#0C3C26', max_length=10, verbose_name=b'link color', blank=True)),
('css_generic_link_hover_color', colorfield.fields.ColorField(default=b'#156641', help_text=b'#156641', max_length=10, verbose_name=b'link hover color', blank=True)),
('css_save_button_background_color', colorfield.fields.ColorField(default=b'#0C4B33', help_text=b'#0C4B33', max_length=10, verbose_name=b'background color', blank=True)),
('css_save_button_background_hover_color', colorfield.fields.ColorField(default=b'#0C3C26', help_text=b'#0C3C26', max_length=10, verbose_name=b'background hover color', blank=True)),
('css_save_button_text_color', colorfield.fields.ColorField(default=b'#FFFFFF', help_text=b'#FFFFFF', max_length=10, verbose_name=b'text color', blank=True)),
('css_delete_button_background_color', colorfield.fields.ColorField(default=b'#BA2121', help_text=b'#BA2121', max_length=10, verbose_name=b'background color', blank=True)),
('css_delete_button_background_hover_color', colorfield.fields.ColorField(default=b'#A41515', help_text=b'#A41515', max_length=10, verbose_name=b'background hover color', blank=True)),
('css_delete_button_text_color', colorfield.fields.ColorField(default=b'#FFFFFF', help_text=b'#FFFFFF', max_length=10, verbose_name=b'text color', blank=True)),
('css', models.TextField(blank=True)),
('list_filter_dropdown', models.BooleanField(default=False)),
],
options={
'verbose_name': 'Theme',
'verbose_name_plural': 'Themes',
},
),
]
+29 -20
View File
@@ -13,30 +13,39 @@ class Theme(models.Model):
@staticmethod
def post_migrate_handler(sender, **kwargs):
Theme.get_or_create_default_theme()
Theme.get_active_theme()
@staticmethod
def post_delete_handler(instance, **kwargs):
Theme.get_or_create_default_theme()
Theme.get_active_theme()
@staticmethod
def post_save_handler(instance, created, **kwargs):
instance.set_active(instance.active)
Theme.get_or_create_default_theme()
Theme.get_active_theme()
@staticmethod
def get_or_create_default_theme():
def get_active_theme():
obj_active = (True if len(list(Theme.objects.filter(active = True))) == 0 else False)
obj, obj_created = Theme.objects.get_or_create(pk = '1', defaults = { 'active':obj_active })
objs_active_qs = Theme.objects.filter( active = True )
if not obj.logo:
obj.set_default_logo()
#get or create default theme and enforce default logo if deleted
default_obj_active = (objs_active_qs.count() == 0)
default_obj, default_obj_created = Theme.objects.get_or_create(pk = '1', defaults = { 'active':default_obj_active })
if not obj_created and obj_active:
obj.set_active(True)
if not default_obj_created and default_obj_active:
default_obj.set_active()
if not default_obj.logo:
default_obj.set_default_logo()
obj = objs_active_qs.last()
objs_active_count = objs_active_qs.count()
if objs_active_count > 1:
obj.set_active()
return obj
return (obj, obj_created, )
name = models.CharField( max_length = 50, default = 'Django' )
active = models.BooleanField( default = True )
@@ -74,21 +83,21 @@ class Theme(models.Model):
list_filter_dropdown = models.BooleanField( default = False )
def set_active(self):
def set_active(self, value):
Theme.objects.exclude( pk = self.pk ).update( active = False )
if value:
Theme.objects.exclude(pk = self.pk).update(active = False)
Theme.objects.filter(pk = self.pk).update(active = True)
else:
Theme.objects.filter(pk = self.pk).update(active = False)
if not self.active:
self.active = True
self.save()
def set_default_logo(self):
logo_path = os.path.normpath(os.path.dirname(__file__) + '/data/logo-django.svg')
logo_filename = 'logo-django.svg'
logo_path = os.path.normpath(os.path.dirname(__file__) + '/data/' + logo_filename)
logo_file = open(logo_path)
self.logo = File(logo_file)
self.logo = File(logo_file, logo_filename)
self.save()
logo_file.close()
+150 -24
View File
@@ -1,6 +1,11 @@
{% extends "admin/base.html" %}
{% load i18n staticfiles admin_interface_tags %}
{% block title %}
{% get_admin_interface_theme as theme %}
{% if theme.title %}{% trans theme.title %}{% else %}{% trans 'Django administration' %}{% endif %}
{% endblock %}
{% block extrastyle %}
{% get_admin_interface_theme as theme %}
<style type="text/css">
@@ -41,9 +46,21 @@
.module h2,
.module caption,
.inline-group h2,
.module.filtered h2,
.inline-group h2,
.module.filtered h2 {
background:{{ theme.css_module_background_color }};
color:{{ theme.css_module_text_color }};
}
.module a.section:link,
.module a.section:visited {
color:{{ theme.css_module_link_color }};
}
.module a.section:active,
.module a.section:hover {
color:{{ theme.css_module_link_hover_color }};
}
div.breadcrumbs {
background:{{ theme.css_module_background_color }};
color:{{ theme.css_module_text_color }};
@@ -53,19 +70,43 @@
color:{{ theme.css_module_link_color }};
}
div.breadcrumbs a:hover,
div.breadcrumbs a:active,
fieldset a.collapse-toggle:hover {
div.breadcrumbs a:focus,
div.breadcrumbs a:hover {
color:{{ theme.css_module_link_hover_color }} !important;
}
fieldset.collapsed a.collapse-toggle {
color:{{ theme.css_module_background_color }} !important;
fieldset.collapse {
border: 1px solid transparent;
}
fieldset.collapse.collapsed a.collapse-toggle {
color:{{ theme.css_generic_link_color }} !important;
font-weight: bold;
text-transform: lowercase;
}
fieldset.collapse.collapsed a.collapse-toggle:hover,
fieldset.collapse.collapsed a.collapse-toggle:active {
color:{{ theme.css_generic_link_hover_color }} !important;
}
fieldset.collapse a.collapse-toggle {
color:{{ theme.css_module_link_color }} !important;
font-weight: bold;
text-transform: lowercase;
}
fieldset.collapse a.collapse-toggle:hover,
fieldset.collapse a.collapse-toggle:active {
color:{{ theme.css_module_link_hover_color }} !important;
}
.inline-group h2 {
background:{{ theme.css_module_background_color }};
color:{{ theme.css_module_text_color }};
}
/* same color as above, but this requires !important */
/* support for modeltranslation tabs */
.ui-tabs .ui-tabs-nav li.ui-tabs-active a, .ui-tabs .ui-tabs-nav li.ui-tabs-selected a,
.selector-chosen h2 {
background:{{ theme.css_module_background_color }} !important;
color:{{ theme.css_module_text_color }} !important;
@@ -85,20 +126,25 @@
}
.button:active, input[type=submit]:active, input[type=button]:active,
.button:focus, input[type=submit]:focus, input[type=button]:focus,
.button:hover, input[type=submit]:hover, input[type=button]:hover {
background:{{ theme.css_save_button_background_hover_color }};
color:{{ theme.css_save_button_text_color }};
outline: none;
}
.button.default, input[type=submit].default, .submit-row input.default {
background:{{ theme.css_save_button_background_color }};
color:{{ theme.css_save_button_text_color }};
outline: none;
}
.button.default:active, input[type=submit].default:active,
.button.default:focus, input[type=submit].default:focus,
.button.default:hover, input[type=submit].default:hover {
background:{{ theme.css_save_button_background_hover_color }};
color:{{ theme.css_save_button_text_color }};
outline: none;
}
.submit-row a.deletelink:link,
@@ -183,9 +229,22 @@
min-width:320px !important;
}
.login #content {
padding:10px 30px 10px 30px !important;
}
/* same lateral padding as in logged view */
.login #header {
padding:10px 25px !important;
padding:15px 30px !important;
}
.login #branding h1 {
margin-right:0;
}
.login #branding h1 img.logo {
max-width:100%;
margin-right:0;
}
/* login button right aligned */
@@ -200,7 +259,9 @@
}
/* top-right buttons color on hover -> just a lighten grey */
.object-tools a:focus,
.object-tools a:hover,
.object-tools li:focus a,
.object-tools li:hover a {
background-color:#AAAAAA;
}
@@ -227,6 +288,11 @@
padding-left:10px !important;
}
form .aligned.wide p.help,
form .aligned.wide ul.error-list {
margin-left: 200px;
}
textarea.tinymce ~ p.help {
margin-top:5px !important;
}
@@ -235,15 +301,38 @@
display:table;
}
/* fix lateral padding to align text with field labels */
/* begin fix issue #13 - Datetime widget broken in long inlines */
p.datetime {
white-space:nowrap;
}
/* end fix */
/* begin fix lateral padding to align text with field labels */
.module h2,
.dashboard .module caption,
.inline-group h2,
.module.filtered h2,
.inline-group h2 {
padding:8px 10px;
{% if theme.css_module_rounded_corners %}border-radius:4px;{% endif %}
padding-left:10px;
padding-right:10px;
}
/* end fix */
/* begin fix issue #11 - Inline border bottom should not be rounded */
.module h2,
.dashboard .module caption,
.module.filtered h2 {
{% if theme.css_module_rounded_corners %}
border-radius:4px;
{% endif %}
}
.inline-group h2 {
{% if theme.css_module_rounded_corners %}
border-bottom-left-radius:0;
border-bottom-right-radius:0;
{% endif %}
}
/* end fix */
.module.filtered h2 {
border-bottom-left-radius:0;
@@ -255,12 +344,24 @@
border-bottom-right-radius:4px;
}
.module.filtered #changelist-filter h2 {
font-size: 11px;
padding: 10px 15px;
}
.module.filtered #changelist-filter select {
background-color:#ffffff;
}
.module.filtered #changelist-filter li.selected a,
.module.filtered #changelist-filter li.selected a:hover {
color: {{ theme.css_generic_link_color }};
}
#content-related {
{% if theme.css_module_rounded_corners %}border-radius:4px;{% endif %}
{% if theme.css_module_rounded_corners %}
border-radius:4px;
{% endif %}
}
/* selector chooseall / clearall color on hover -> just a lighten grey */
@@ -268,26 +369,36 @@
color:#888888 !important;
}
.inline-group {
overflow-x:auto;
}
/* begin fix issue #10 - Related widget broken in long tabular inline */
.inline-group .tabular .related-widget-wrapper {
white-space:nowrap;
}
/* end fix */
.inline-related h3 {
padding:6px 10px !important;
}
/*
/* begin fix issue #12 - Inlines bad delete buttons alignement */
.inline-group .tabular thead th:last-child:not([class]):not([style]) {
text-align:center;
text-align:right;
}
*/
/*.inline-group .tabular tr.has_original td.original, */
.inline-group .tabular tr td.delete {
vertical-align:middle !important;
text-align:center !important;
text-align:right;
padding-right:15px;
}
.inline-group .tabular tr td.delete a.inline-deletelink {
float:none;
display:inline-block;
margin-top:2px;
overflow:hidden;
text-indent:9999px;
}
/* end fix */
/* improve django-modeltranslation support - https://github.com/deschler/django-modeltranslation/pull/313/commits */
@@ -365,6 +476,13 @@
}
/* sorl-thumbnail - improved AdminImageMixin widget layout */
a.thumbnail + input[type="checkbox"] {
margin:10px 0;
}
/* ckeditor + light theme - https://github.com/Ikimea/ckeditor-light-theme */
.cke_inner, .cke_wysiwyg_frame {
@@ -445,5 +563,13 @@
</h1>
{% endblock %}
{% block bodyclass %}admin-interface flat-theme{% endblock %}
{% block blockbots %}
{{ block.super }}
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0">
<link rel="stylesheet" type="text/css" href="{% static "admin/css/responsive.css" %}" />
{% endblock %}
{% block sidebar %}
{% endblock %}
@@ -11,15 +11,5 @@ register = template.Library()
@register.assignment_tag(takes_context = True)
def get_admin_interface_theme(context):
obj_qs = Theme.objects.filter(active = True)[:1]
obj_ls = list(obj_qs)
obj = None
if len(obj_ls):
obj = obj_ls[0]
else:
obj = Theme.get_or_create_default_theme()
return obj
return Theme.get_active_theme()
+1 -1
View File
@@ -1,4 +1,4 @@
# -*- coding: utf-8 -*-
__version__ = '0.1.0'
__version__ = '0.3.2'
Executable
+21
View File
@@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
import os
import sys
import django
from django.conf import settings
from django.test.utils import get_runner
def runtests():
os.environ['DJANGO_SETTINGS_MODULE'] = 'tests.settings'
django.setup()
TestRunner = get_runner(settings)
test_runner = TestRunner()
failures = test_runner.run_tests(['tests'])
sys.exit(bool(failures))
if __name__ == '__main__':
runtests()
+31 -7
View File
@@ -1,24 +1,48 @@
#!/usr/bin/env python
from setuptools import find_packages, setup
exec(open('admin_interface/version.py').read())
setup(
name='django-admin-interface',
packages=find_packages(),
packages=find_packages(exclude=['contrib', 'docs', 'tests*']),
include_package_data=True,
license='MIT License',
version=__version__,
description='django-admin-interface is a modern admin interface customizable by the admin itself.',
description='django-admin-interface is a modern responsive flat admin interface customizable by the admin itself.',
author='Fabio Caccamo',
author_email='fabio.caccamo@gmail.com',
url='https://github.com/fabiocaccamo/django-admin-interface',
download_url='https://github.com/fabiocaccamo/django-admin-interface/archive/%s.tar.gz' % __version__,
keywords=['django', 'admin', 'interface', 'ui', 'flat', 'theme', 'custom'],
keywords=['django', 'admin', 'interface', 'responsive', 'flat', 'theme', 'custom', 'ui'],
requires=['django(>=1.7)'],
install_requires=[
'django-colorfield==0.1.10'
'django-colorfield==0.1.12',
'django-flat-theme==1.1.4',
'django-flat-responsive==1.3.0'
],
classifiers=[]
classifiers=[
'Development Status :: 5 - Production/Stable',
'Environment :: Web Environment',
'Framework :: Django',
'Framework :: Django :: 1.7',
'Framework :: Django :: 1.8',
'Framework :: Django :: 1.9',
'Framework :: Django :: 1.10',
'Framework :: Django :: 1.11',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Natural Language :: English',
'Operating System :: OS Independent',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Topic :: Software Development :: Build Tools',
],
license='MIT',
test_suite='runtests.runtests'
)
View File
+54
View File
@@ -0,0 +1,54 @@
# -*- coding: utf-8 -*-
import django
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
SECRET_KEY = 'django-admin-interface'
ALLOWED_HOSTS = ['*']
INSTALLED_APPS = [
'admin_interface',
'flat_responsive',
'flat', #if django version < 1.9
'colorfield',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
]
MIDDLEWARE_CLASSES = [
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
]
TEMPLATES = [{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.contrib.auth.context_processors.auth',
]
},
},]
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
MEDIA_ROOT = os.path.join(BASE_DIR, 'admin_interface/public/media/')
MEDIA_URL = '/media/'
STATIC_ROOT = os.path.join(BASE_DIR, 'admin_interface/public/static/')
STATIC_URL = '/static/'
+83
View File
@@ -0,0 +1,83 @@
# -*- coding: utf-8 -*-
from django.conf import settings
from django.test import TestCase
from django.template import Context, Template
import os
import shutil
from admin_interface.models import Theme
class AdminInterfaceTestCase(TestCase):
def setUp(self):
pass
def tearDown(self):
shutil.rmtree(settings.MEDIA_ROOT, ignore_errors=True)
pass
def __render_template(self, string, context=None):
context = context or {}
context = Context(context)
return Template(string).render(context)
def __test_active_theme(self):
theme = Theme.get_active_theme()
print( theme )
self.assertTrue(theme != None)
self.assertTrue(theme.active)
self.assertEqual(Theme.objects.filter( active = True ).count(), 1);
def test_default_theme_created_if_no_themes(self):
Theme.objects.all().delete()
self.__test_active_theme()
def test_default_theme_created_if_all_themes_deleted(self):
Theme.objects.all().delete()
self.__test_active_theme()
def test_default_theme_activated_on_save_if_no_active_themes(self):
Theme.objects.all().delete()
theme = Theme.get_active_theme()
theme.active = False
theme.save()
self.__test_active_theme()
def test_default_theme_activated_after_update_if_no_active_themes(self):
Theme.objects.all().delete()
Theme.objects.all().update( active = False )
self.__test_active_theme()
def test_default_theme_activated_on_active_theme_deleted(self):
Theme.objects.all().delete()
theme_1 = Theme.objects.create( name = 'Custom 1', active = True )
theme_2 = Theme.objects.create( name = 'Custom 2', active = True )
theme_3 = Theme.objects.create( name = 'Custom 3', active = True )
Theme.objects.filter( pk = Theme.get_active_theme().pk ).delete()
self.assertEqual( Theme.get_active_theme().pk, 1 )
def test_last_theme_activated_on_multiple_themes_created(self):
Theme.objects.all().delete()
theme_1 = Theme.objects.create( name = 'Custom 1', active = True )
theme_2 = Theme.objects.create( name = 'Custom 2', active = True )
theme_3 = Theme.objects.create( name = 'Custom 3', active = True )
self.assertEqual( Theme.get_active_theme().pk, theme_3.pk )
self.__test_active_theme()
def test_templatetags(self):
Theme.objects.all().delete()
rendered = self.__render_template('{% load admin_interface_tags %}{% get_admin_interface_theme as theme %}{{ theme.name }}')
self.assertEqual(rendered, 'Django')
+20
View File
@@ -0,0 +1,20 @@
[tox]
envlist =
py27-{17,18,19,110,111},
py34-{17,18,19,110,111},
py35-{18,19,110,111},
py36-{18,19,110,111},
[testenv]
passenv = CI TRAVIS TRAVIS_*
deps =
17: Django >= 1.7, < 1.8
18: Django >= 1.8, < 1.9
19: Django >= 1.9, < 1.10
110: Django >= 1.10, < 1.11
111: Django >= 1.11, < 1.12
coverage
codecov
commands =
coverage run --append --source=admin_interface setup.py test
coverage report -m
codecov