Django 1.9 compatibility
This commit is contained in:
parent
2ae4b482f4
commit
85c0e75bcd
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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':
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -36,7 +36,7 @@ class LogEntryAdmin(admin.ModelAdmin):
|
|||
def display_message(self, log):
|
||||
edit = '<a href="%(url)s"><img src="%(img)s"></img></a>' % {
|
||||
'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') % {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
<tr>
|
||||
<th scope="row">{{ action.action_time|date:"DATETIME_FORMAT" }}</th>
|
||||
<td>{{ action.user.get_username }}{% if action.user.get_full_name %} ({{ action.user.get_full_name }}){% endif %}</td>
|
||||
<td>{% if action.is_addition and not action.change_message %}{% trans 'Added' %}{% else %}{{ action.change_message }}{% endif %} <a href="{% url 'admin:admin_logentry_change' action.pk %}?edit=True" style="float:right"><img src="{% static 'admin/img/icon_changelink.gif' %}"></img></a></td>
|
||||
<td>{% if action.is_addition and not action.change_message %}{% trans 'Added' %}{% else %}{{ action.change_message }}{% endif %} <a href="{% url 'admin:admin_logentry_change' action.pk %}?edit=True" style="float:right"><img src="{% static 'orchestra/images/icon_changelink.gif' %}"></img></a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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__:
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
{% extends "admin/orchestra/generic_confirmation.html" %}
|
||||
{% load i18n l10n %}
|
||||
{% load url from future %}
|
||||
{% load admin_urls static utils %}
|
||||
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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(),
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
BIN
orchestra/static/orchestra/images/icon_changelink.gif
Normal file
BIN
orchestra/static/orchestra/images/icon_changelink.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 119 B |
|
@ -50,13 +50,13 @@
|
|||
{% if messages %}
|
||||
<ul class="messagelist" >{% for message in messages %}
|
||||
<div style="background: {% if message.tags == 'warning' %}#ffc{% elif message.tags == 'error' %}#ffefef{% else %}#dfd{% endif %} 5px .3em no-repeat;border-bottom: 1px solid #ddd;">
|
||||
<li{% if message.tags %} class="{{ message.tags }}"{% endif %} style="max-width:1130px;margin:auto;margin-bottom:-1px;">{{ message }}</li></div>
|
||||
<li{% if message.tags %} class="{{ message.tags }}"{% endif %} style="max-width:1330px;margin:auto;">{{ message }}</li></div>
|
||||
{% endfor %}</ul>
|
||||
{% endif %}
|
||||
{% endblock messages %}
|
||||
|
||||
<!-- Content -->
|
||||
<div id="content" class="{% block coltype %}colM{% endblock %}" style="max-width:1150px; margin:20px auto;">
|
||||
<div id="content" class="{% block coltype %}colM{% endblock %}" style="max-width:1350px; margin:17px auto;">
|
||||
{% block pretitle %}{% endblock %}
|
||||
{% block content_title %}{% if title %}<h1>{{ title }}</h1>{% endif %}{% endblock %}
|
||||
{% block content %}
|
||||
|
@ -74,4 +74,3 @@
|
|||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
{% extends "admin/base_site.html" %}
|
||||
{% load i18n l10n %}
|
||||
{% load url from future %}
|
||||
{% load admin_urls static utils %}
|
||||
|
||||
{% block extrastyle %}
|
||||
|
|
|
@ -46,18 +46,18 @@
|
|||
|
||||
{% endif %}
|
||||
<ul id="navigation-menu">
|
||||
<div style="max-width: 1170px; margin:auto;">
|
||||
<div style="max-width: 1370px; margin:auto; padding-top:4px;">
|
||||
<div id="branding"><a href="/admin/"></a><h1 id="site-name"><a href="/admin/">{{ ORCHESTRA_SITE_VERBOSE_NAME }}<span class="version">0.0.1a1</span></a></h1></div>
|
||||
{% for item in menu.children %}{% admin_tools_render_menu_item item forloop.counter %}{% endfor %}
|
||||
<form action="{% url 'admin:orchestra_search_view' %}" method="get" name="top_search" style="display: inline;">
|
||||
<input type="text" id="searchbox" style="margin-left:15px;margin-top:7px;" name="q"
|
||||
<input type="text" id="searchbox" style="margin-left:15px;margin-top:3px;" name="q"
|
||||
placeholder="Search" size="25" value="{{ query }}"
|
||||
{% if search_autofocus or app_list %}autofocus="autofocus"{% endif %}
|
||||
title="Use 'accountname!' for account direct access
|
||||
Use 'service:word' for searching on specific services
|
||||
Use 'fieldname=word' for searching on specific fields">
|
||||
</form>
|
||||
<span style="float:right;color:grey;margin:10px;font-size:11px;">
|
||||
<span style="float:right;color:grey;margin:15px;font-size:13px;">
|
||||
{% url 'admin:accounts_account_change' user.pk as user_change_url %}
|
||||
<a href="{{ user_change_url }}" style="color:#555;"><strong>{% filter force_escape %}{% firstof user.get_short_name user.username %}{% endfilter %}</strong></a>
|
||||
<a href="{% url 'admin:password_change' %}" style="color:#555;">Change password</a> / <a href="{% url 'admin:logout' %}" style="color:#555;">Log out</a></span>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
{% block object-tools-items %}
|
||||
{% for item in object_tools_items %}
|
||||
<li><a href="{{ item.url_name }}/" class="{{ item.css_class }}" title="{{ item.help_text }}">{{ item.tool_description }}</a></li>
|
||||
<li><a href="{% url opts|admin_urlname:item.url_name original.pk|admin_urlquote %}" class="{{ item.css_class }}" title="{{ item.help_text }}">{{ item.tool_description }}</a></li>
|
||||
{% endfor %}
|
||||
{{ block.super }}
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
from django.contrib import admin
|
||||
from django.conf.urls import include, url
|
||||
from rest_framework.authtoken.views import obtain_auth_token
|
||||
|
||||
from orchestra.views import serve_private_media
|
||||
|
||||
from . import api
|
||||
from .utils.apps import isinstalled
|
||||
|
@ -16,14 +19,8 @@ urlpatterns = [
|
|||
# REST API
|
||||
url(r'^api/', include(api.router.urls)),
|
||||
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
|
||||
url(r'^api-token-auth/',
|
||||
'rest_framework.authtoken.views.obtain_auth_token',
|
||||
name='api-token-auth'
|
||||
),
|
||||
url(r'^media/(.+)/(.+)/(.+)/(.+)/(.+)$',
|
||||
'orchestra.views.serve_private_media',
|
||||
name='private-media'
|
||||
),
|
||||
url(r'^api-token-auth/', obtain_auth_token, name='api-token-auth'),
|
||||
url(r'^media/(.+)/(.+)/(.+)/(.+)/(.+)$', serve_private_media, name='private-media'),
|
||||
# url(r'search', 'orchestra.views.search', name='search'),
|
||||
]
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
django==1.8.5
|
||||
django-fluent-dashboard==0.5.3
|
||||
django-admin-tools==0.6.0
|
||||
django-extensions==1.5.7
|
||||
django-celery==3.1.16
|
||||
celery==3.1.16
|
||||
kombu==3.0.23
|
||||
billiard==3.3.0.18
|
||||
Django==1.9.5
|
||||
django-fluent-dashboard==0.6.1
|
||||
django-admin-tools==0.7.2
|
||||
django-extensions==1.6.1
|
||||
django-celery==3.1.17
|
||||
celery==3.1.23
|
||||
kombu==3.0.35
|
||||
billiard==3.3.0.23
|
||||
Markdown==2.4
|
||||
djangorestframework==3.3.2
|
||||
ecdsa==0.11
|
||||
|
|
Loading…
Reference in a new issue