diff --git a/orchestra/admin/dashboard.py b/orchestra/admin/dashboard.py
index 5cded62c..3a626e15 100644
--- a/orchestra/admin/dashboard.py
+++ b/orchestra/admin/dashboard.py
@@ -67,6 +67,7 @@ class OrchestraIndexDashboard(dashboard.FluentIndexDashboard):
models.append(label)
label = '.'.join((opts.app_label, opts.model_name))
icons[label] = options.get('icon')
+ print(models)
module = AppDefaultIconList(title, models=models, icons=icons, collapsible=True)
for view_name, options in views:
self.process_registered_view(module, view_name, options)
diff --git a/orchestra/api/serializers.py b/orchestra/api/serializers.py
index 09aa329e..28598b9f 100644
--- a/orchestra/api/serializers.py
+++ b/orchestra/api/serializers.py
@@ -93,7 +93,7 @@ class SetPasswordHyperlinkedSerializer(HyperlinkedModelSerializer):
def validate(self, attrs):
""" remove password in case is not a real model field """
try:
- self.Meta.model._meta.get_field_by_name('password')
+ self.Meta.model._meta.get_field('password')
except models.FieldDoesNotExist:
pass
else:
diff --git a/orchestra/contrib/bills/filters.py b/orchestra/contrib/bills/filters.py
index 9ab8a11f..091c49c8 100644
--- a/orchestra/contrib/bills/filters.py
+++ b/orchestra/contrib/bills/filters.py
@@ -98,8 +98,7 @@ class PaymentStateListFilter(SimpleListFilter):
def queryset(self, request, queryset):
# FIXME use queryset.computed_total instead of approx_total, bills.admin.BillAdmin.get_queryset
- # Transaction = queryset.model.transactions.field.remote_field.related_model
- Transaction = queryset.model.transactions.related.related_model
+ Transaction = queryset.model.transactions.field.remote_field.related_model
if self.value() == 'OPEN':
return queryset.filter(Q(is_open=True)|Q(type=queryset.model.PROFORMA))
elif self.value() == 'PAID':
diff --git a/orchestra/contrib/domains/forms.py b/orchestra/contrib/domains/forms.py
index 9fafef06..b58d8d54 100644
--- a/orchestra/contrib/domains/forms.py
+++ b/orchestra/contrib/domains/forms.py
@@ -118,7 +118,7 @@ class SOAForm(AdminFormMixin, forms.Form):
super(SOAForm, self).__init__(*args, **kwargs)
for name in self.fields:
if not name.startswith('clear_'):
- field = Domain._meta.get_field_by_name(name)[0]
+ field = Domain._meta.get_field(name)
self.fields[name] = forms.CharField(
label=capfirst(field.verbose_name),
help_text=field.help_text,
diff --git a/orchestra/contrib/history/admin.py b/orchestra/contrib/history/admin.py
index e095da39..073f38cd 100644
--- a/orchestra/contrib/history/admin.py
+++ b/orchestra/contrib/history/admin.py
@@ -36,7 +36,7 @@ class LogEntryAdmin(admin.ModelAdmin):
def display_message(self, log):
edit = '' % {
'url': reverse('admin:admin_logentry_change', args=(log.pk,)),
- 'img': static('admin/img/icon_changelink.gif'),
+ 'img': static('orchestra/images/icon_changelink.gif'),
}
if log.is_addition():
return _('Added "%(link)s". %(edit)s') % {
diff --git a/orchestra/contrib/history/apps.py b/orchestra/contrib/history/apps.py
index 0c00a4cb..8d168e5c 100644
--- a/orchestra/contrib/history/apps.py
+++ b/orchestra/contrib/history/apps.py
@@ -12,7 +12,3 @@ class HistoryConfig(AppConfig):
administration.register(
LogEntry, verbose_name='History', verbose_name_plural='History', icon='History.png'
)
- # prevent loosing creation time on log entry edition
-# action_time = LogEntry._meta.get_field_by_name('action_time')[0]
-# action_time.auto_now = False
-# action_time.auto_now_add = True
diff --git a/orchestra/contrib/history/templates/admin/object_history.html b/orchestra/contrib/history/templates/admin/object_history.html
index 26eed2d0..379c27e9 100644
--- a/orchestra/contrib/history/templates/admin/object_history.html
+++ b/orchestra/contrib/history/templates/admin/object_history.html
@@ -29,7 +29,7 @@
{{ action.action_time|date:"DATETIME_FORMAT" }} |
{{ action.user.get_username }}{% if action.user.get_full_name %} ({{ action.user.get_full_name }}){% endif %} |
- {% if action.is_addition and not action.change_message %}{% trans 'Added' %}{% else %}{{ action.change_message }}{% endif %} |
+ {% if action.is_addition and not action.change_message %}{% trans 'Added' %}{% else %}{{ action.change_message }}{% endif %} |
{% endfor %}
diff --git a/orchestra/contrib/mailboxes/signals.py b/orchestra/contrib/mailboxes/signals.py
index bf859dac..4330a1d1 100644
--- a/orchestra/contrib/mailboxes/signals.py
+++ b/orchestra/contrib/mailboxes/signals.py
@@ -27,7 +27,7 @@ def create_local_address(sender, *args, **kwargs):
mbox = kwargs['instance']
local_domain = settings.MAILBOXES_LOCAL_DOMAIN
if not mbox.pk and local_domain:
- Domain = Address._meta.get_field_by_name('domain')[0].rel.to
+ Domain = Address._meta.get_field('domain').rel.to
try:
domain = Domain.objects.get(name=local_domain)
except Domain.DoesNotExist:
diff --git a/orchestra/contrib/orchestration/tests/test_route.py b/orchestra/contrib/orchestration/tests/test_route.py
index 669f9e3a..4b7ee121 100644
--- a/orchestra/contrib/orchestration/tests/test_route.py
+++ b/orchestra/contrib/orchestration/tests/test_route.py
@@ -12,7 +12,7 @@ class RouterTests(BaseTestCase):
def test_list_backends(self):
# TODO count actual, register and compare
- choices = list(Route._meta.get_field_by_name('backend')[0]._choices)
+ choices = list(Route._meta.get_field('backend')._choices)
self.assertLess(1, len(choices))
def test_get_instances(self):
@@ -25,7 +25,7 @@ class RouterTests(BaseTestCase):
pass
choices = backends.ServiceBackend.get_choices()
- Route._meta.get_field_by_name('backend')[0]._choices = choices
+ Route._meta.get_field('backend')._choices = choices
backend = TestBackend.get_name()
route = Route.objects.create(backend=backend, host=self.host, match='True')
diff --git a/orchestra/contrib/saas/services/options.py b/orchestra/contrib/saas/services/options.py
index af2f75c5..56a8dfef 100644
--- a/orchestra/contrib/saas/services/options.py
+++ b/orchestra/contrib/saas/services/options.py
@@ -167,7 +167,7 @@ class DBSoftwareService(SoftwareService):
@cached
def get_account(self):
- account_model = self.instance._meta.get_field_by_name('account')[0]
+ account_model = self.instance._meta.get_field('account')
return account_model.rel.to.objects.get_main()
def validate(self):
diff --git a/orchestra/contrib/services/actions.py b/orchestra/contrib/services/actions.py
index 7bc59b80..b11b9b49 100644
--- a/orchestra/contrib/services/actions.py
+++ b/orchestra/contrib/services/actions.py
@@ -70,7 +70,7 @@ def clone(modeladmin, request, queryset):
fields = modeladmin.get_fields(request)
query = []
for field in fields:
- model_field = type(service)._meta.get_field_by_name(field)[0]
+ model_field = type(service)._meta.get_field(field)
if model_field.rel:
value = getattr(service, field + '_id')
elif 'Boolean' in model_field.__class__.__name__:
diff --git a/orchestra/contrib/services/templates/admin/services/service/help.html b/orchestra/contrib/services/templates/admin/services/service/help.html
index 5308eddc..27e29c48 100644
--- a/orchestra/contrib/services/templates/admin/services/service/help.html
+++ b/orchestra/contrib/services/templates/admin/services/service/help.html
@@ -1,6 +1,5 @@
{% extends "admin/orchestra/generic_confirmation.html" %}
{% load i18n l10n %}
-{% load url from future %}
{% load admin_urls static utils %}
diff --git a/orchestra/models/fields.py b/orchestra/models/fields.py
index 7f857682..8d892762 100644
--- a/orchestra/models/fields.py
+++ b/orchestra/models/fields.py
@@ -9,7 +9,7 @@ from django.utils.text import capfirst
from ..forms.fields import MultiSelectFormField
-class MultiSelectField(models.CharField, metaclass=models.SubfieldBase):
+class MultiSelectField(models.CharField):
def formfield(self, **kwargs):
defaults = {
'required': not self.blank,
@@ -35,6 +35,13 @@ class MultiSelectField(models.CharField, metaclass=models.SubfieldBase):
return value
return []
+ def from_db_value(self, value, expression, connection, context):
+ if value:
+ if isinstance(value, str):
+ return value.split(',')
+ return value
+ return []
+
def contribute_to_class(self, cls, name):
super(MultiSelectField, self).contribute_to_class(cls, name)
if self.choices:
diff --git a/orchestra/plugins/admin.py b/orchestra/plugins/admin.py
index 905776da..9f245876 100644
--- a/orchestra/plugins/admin.py
+++ b/orchestra/plugins/admin.py
@@ -59,7 +59,7 @@ class SelectPluginAdminMixin(object):
'opts': opts,
'app_label': opts.app_label,
'field': self.plugin_field,
- 'field_name': opts.get_field_by_name(self.plugin_field)[0].verbose_name,
+ 'field_name': opts.get_field(self.plugin_field).verbose_name,
'plugin': self.plugin,
'plugins': self.plugin.get_plugins(),
}
diff --git a/orchestra/plugins/forms.py b/orchestra/plugins/forms.py
index fcb50421..01286497 100644
--- a/orchestra/plugins/forms.py
+++ b/orchestra/plugins/forms.py
@@ -23,7 +23,7 @@ class PluginDataForm(forms.ModelForm):
# Admin Readonly fields are not availeble in self.fields, so we use Meta
plugin = getattr(self.instance, '%s_class' % self.plugin_field)
plugin_help_text = getattr(plugin, 'help_text', '')
- model_help_text = self.instance._meta.get_field_by_name(self.plugin_field)[0].help_text
+ model_help_text = self.instance._meta.get_field(self.plugin_field).help_text
self._meta.help_texts = {
self.plugin_field: plugin_help_text or model_help_text
}
diff --git a/orchestra/static/admin/css/login.css b/orchestra/static/admin/css/login.css
index 99cc756e..e2cdadcd 100644
--- a/orchestra/static/admin/css/login.css
+++ b/orchestra/static/admin/css/login.css
@@ -24,6 +24,116 @@
text-decoration: none;
}
+
+#header {
+ padding: 0px;
+ background: #417690 !important;
+}
+
+.login #container #content h1 {
+ text-align: center;
+}
+
+.login #container #content p {
+ text-align: center;
+}
+
+.login .register-links {
+ text-align: right
+}
+
+
+body.login {
+ background: #eee;
+}
+
+.login #container {
+ background: white;
+ border: 1px solid #ccc;
+ width: 28em;
+ min-width: 460px;
+ margin-left: auto;
+ margin-right: auto;
+ margin-top: 100px;
+}
+
+.login #content-main {
+/*changed*/
+ width: 90%;
+ margin-left: 20px;
+}
+
+.login form {
+ margin-top: 1em;
+}
+
+.login .form-row {
+ padding: 4px 0;
+ float: left;
+ width: 100%;
+}
+
+.login .form-row label {
+ padding-right: 0.5em;
+ line-height: 2em;
+ font-size: 1em;
+ clear: both;
+ color: #333;
+}
+
+.login .form-row #id_username, .login .form-row #id_password {
+ clear: both;
+ padding: 6px;
+ width: 100%;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+.login span.help {
+ font-size: 10px;
+ display: block;
+}
+
+.login .submit-row {
+ clear: both;
+ padding: 1em 0 0 9.4em;
+}
+
+.login .password-reset-link {
+ text-align: center;
+/* LOGIN FORM */
+
+
+
+#header #branding h1 {
+ margin: 0;
+ padding: 5px 10px;
+ background: transparent url(/static/orchestra/images/orchestra-logo.png) 10px 5px no-repeat;
+ text-indent: 0;
+ height: 31px;
+ width: 420px;
+ font-size: 18px;
+ color: whitesmoke;
+ font-weight: bold;
+ padding-left: 50px;
+ line-height: 30px;
+}
+
+.version {
+ font-size: 0%;
+}
+
+#header #branding:hover a {
+ text-decoration: none;
+}
+
+
+#header {
+ padding: 0px;
+ background: #417690 !important;
+}
+
.login #container #content h1 {
text-align: center;
}
diff --git a/orchestra/static/orchestra/css/adminextraprettystyle.css b/orchestra/static/orchestra/css/adminextraprettystyle.css
index 8f68e1b2..da159fd3 100644
--- a/orchestra/static/orchestra/css/adminextraprettystyle.css
+++ b/orchestra/static/orchestra/css/adminextraprettystyle.css
@@ -2,6 +2,17 @@ body {
background: #FBFAF9 url(/static/orchestra/images/page-gradient.png) top left repeat-x;
}
+#header {
+ min-height: 0px;
+ background: none;
+ line-height: 0px;
+ padding: 0px;
+ height: 0px;
+}
+
+#header #navigation-menu {
+ height: 43px;
+}
#header #branding h1 {
margin: 0;
@@ -20,7 +31,6 @@ body {
color: #555;
}
-
.version:before {
content: "v";
opacity: 0.6;
@@ -36,19 +46,17 @@ body {
color: #9B9B9B;
}
-
#header ul#navigation-menu li.first a {
outline: none;
background: none;
margin: 0;
- padding: 10px;
+ padding: 8px 30px 9px 5px;
}
-
#header-breadcrumb {
width: 100%;
z-index: -1;
- margin-top: 35px;
+ margin-top: 37px;
height: 69px;
position: absolute;
background-attachment: scroll; background-clip: border-box;
@@ -79,6 +87,123 @@ body {
}
div.breadcrumbs {
- max-width: 1150px;
+ max-width: 1350px;
margin: auto;
+ border-bottom: none;
+ margin-top: 43px;
+
+}
+
+#header-breadcrumb {
+ background: #79aec8;
+ padding-bottom: 24px;
+}
+
+.inline-group, .module {
+ border: 1px solid #eee;
+ border-radius: 4px;
+}body {
+ background: #FBFAF9 url(/static/orchestra/images/page-gradient.png) top left repeat-x;
+}
+
+#header {
+ min-height: 0px;
+ background: none;
+ line-height: 0px;
+ padding: 0px;
+ height: 0px;
+}
+
+#header #navigation-menu {
+ height: 43px;
+}
+
+#header #branding h1 {
+ margin: 0;
+ padding: 2px 15px;
+ background: transparent url(/static/orchestra/images/orchestra-logo.png) 5px 2px no-repeat;
+ text-indent: 0;
+ height: 31px;
+ font-size: 16px;
+/* font-weight: bold;*/
+ padding-left: 45px;
+ line-height: 30px;
+ border-right: 1px solid #ededed;
+}
+
+#branding h1, #branding h1 a:link, #branding h1 a:visited {
+ color: #555;
+}
+
+.version:before {
+ content: "v";
+ opacity: 0.6;
+ padding-right: 0.25em;
+}
+
+.version {
+ font-size: 60%;
+}
+
+#header #branding:hover a {
+ text-decoration: none;
+ color: #9B9B9B;
+}
+
+#header ul#navigation-menu li.first a {
+ outline: none;
+ background: none;
+ margin: 0;
+ padding: 8px 30px 9px 5px;
+}
+
+#header-breadcrumb {
+ width: 100%;
+ z-index: -1;
+ margin-top: 37px;
+ height: 69px;
+ position: absolute;
+ background-attachment: scroll; background-clip: border-box;
+ background-color: rgb(255, 255, 255);
+ background-image: url(/static/admin/img/nav-bg-reverse.gif);
+ background-origin: padding-box;
+ background-position: 0px -8px;
+ background-size: auto;
+ border-bottom-color: rgb(237, 237, 237);
+ border-bottom-style: solid;
+ border-bottom-width: 1px;
+ border-left-color: rgb(153, 153, 153);
+ border-left-style: none;
+ border-left-width: 0px;
+ border-right-color: rgb(153, 153, 153);
+ border-right-style: none;
+ border-right-width: 0px;
+ border-top-color: rgb(153, 153, 153);
+ border-top-style: none;
+ border-top-width: 0px;
+ color: white;
+ height: 13px;
+ padding-bottom: 10px;
+ padding-top: 10px;
+ background-repeat: repeat-x;
+ padding-left: 0;
+ padding-right: 0;
+}
+
+div.breadcrumbs {
+ max-width: 1350px;
+ margin: auto;
+ border-bottom: none;
+ margin-top: 43px;
+
+}
+
+#header-breadcrumb {
+ background: #79aec8;
+ padding-bottom: 24px;
+}
+
+.inline-group, .module {
+ border: 1px solid #eee;
+ border-radius: 4px;
}
diff --git a/orchestra/static/orchestra/images/icon_changelink.gif b/orchestra/static/orchestra/images/icon_changelink.gif
new file mode 100644
index 00000000..e1b9afde
Binary files /dev/null and b/orchestra/static/orchestra/images/icon_changelink.gif differ
diff --git a/orchestra/templates/admin/base.html b/orchestra/templates/admin/base.html
index f995bd69..076a3973 100644
--- a/orchestra/templates/admin/base.html
+++ b/orchestra/templates/admin/base.html
@@ -50,13 +50,13 @@
{% if messages %}
{% for message in messages %}
-
- {{ message }}
+ - {{ message }}
{% endfor %}
{% endif %}
{% endblock messages %}
-
+
{% block pretitle %}{% endblock %}
{% block content_title %}{% if title %}
{{ title }}
{% endif %}{% endblock %}
{% block content %}
@@ -74,4 +74,3 @@