diff --git a/orchestra/admin/options.py b/orchestra/admin/options.py index bcd70904..5701da6b 100644 --- a/orchestra/admin/options.py +++ b/orchestra/admin/options.py @@ -2,7 +2,7 @@ from django import forms from django.contrib import admin from django.forms.models import BaseInlineFormSet -from .utils import set_default_filter +from .utils import set_url_query class ExtendedModelAdmin(admin.ModelAdmin): @@ -55,9 +55,9 @@ class ChangeListDefaultFilter(object): def changelist_view(self, request, extra_context=None): """ Default filter as 'my_nodes=True' """ defaults = [] - for queryarg, value in self.default_changelist_filters: - set_default_filter(queryarg, request, value) - defaults.append(queryarg) + for key, value in self.default_changelist_filters: + set_url_query(request, key, value) + defaults.append(key) # hack response cl context in order to hook default filter awaearness into search_form.html template response = super(ChangeListDefaultFilter, self).changelist_view(request, extra_context=extra_context) if hasattr(response, 'context_data') and 'cl' in response.context_data: diff --git a/orchestra/admin/utils.py b/orchestra/admin/utils.py index 2de55a03..bf44e669 100644 --- a/orchestra/admin/utils.py +++ b/orchestra/admin/utils.py @@ -63,13 +63,13 @@ def wrap_admin_view(modeladmin, view): return update_wrapper(wrapper, view) -def set_default_filter(queryarg, request, value): +def set_url_query(request, key, value): """ set default filters for changelist_view """ - if queryarg not in request.GET: + if key not in request.GET: request_copy = request.GET.copy() if callable(value): value = value(request) - request_copy[queryarg] = value + request_copy[key] = value request.GET = request_copy request.META['QUERY_STRING'] = request.GET.urlencode() diff --git a/orchestra/apps/accounts/admin.py b/orchestra/apps/accounts/admin.py index 64820300..856ccbd7 100644 --- a/orchestra/apps/accounts/admin.py +++ b/orchestra/apps/accounts/admin.py @@ -5,10 +5,11 @@ from django.contrib.admin.util import unquote from django.core.urlresolvers import reverse from django.http import HttpResponseRedirect from django.utils.safestring import mark_safe +from django.utils.six.moves.urllib.parse import parse_qsl from django.utils.translation import ugettext_lazy as _ from orchestra.admin import ExtendedModelAdmin -from orchestra.admin.utils import wrap_admin_view, admin_link +from orchestra.admin.utils import wrap_admin_view, admin_link, set_url_query from orchestra.core import services, accounts from .filters import HasMainUserListFilter @@ -129,6 +130,8 @@ class AccountAdminMixin(object): """ Provide basic account support to ModelAdmin and AdminInline classes """ readonly_fields = ('account_link',) filter_by_account_fields = [] + change_list_template = 'admin/accounts/account/change_list.html' + change_form_template = 'admin/accounts/account/change_form.html' def account_link(self, instance): account = instance.account if instance.pk else self.account @@ -161,6 +164,48 @@ class AccountAdminMixin(object): # Filter related object by account formfield.queryset = formfield.queryset.filter(account=self.account) return formfield + + def get_account_from_preserve_filters(self, request): + preserved_filters = self.get_preserved_filters(request) + preserved_filters = dict(parse_qsl(preserved_filters)) + cl_filters = preserved_filters.get('_changelist_filters') + if cl_filters: + return dict(parse_qsl(cl_filters)).get('account') + + def changeform_view(self, request, object_id=None, form_url='', extra_context=None): + account_id = self.get_account_from_preserve_filters(request) + verb = 'change' if object_id else 'add' + if not object_id: + if account_id: + # Preselect account + set_url_query(request, 'account', account_id) + context = { + 'from_account': bool(account_id), + 'account': not account_id or Account.objects.get(pk=account_id), + 'account_opts': Account._meta, + } + context.update(extra_context or {}) + return super(AccountAdminMixin, self).changeform_view(request, + object_id=object_id, form_url=form_url, extra_context=context) + + def changelist_view(self, request, extra_context=None): + account_id = request.GET.get('account') + context = { + 'from_account': False + } + if account_id: + opts = self.model._meta + account = Account.objects.get(pk=account_id) + context = { + 'from_account': True, + 'title': _("Select %s to change for %s") % ( + opts.verbose_name, account.name), + 'account': not account_id or Account.objects.get(pk=account_id), + 'account_opts': Account._meta, + } + context.update(extra_context or {}) + return super(AccountAdminMixin, self).changelist_view(request, + extra_context=context) class SelectAccountAdminMixin(AccountAdminMixin): @@ -196,14 +241,21 @@ class SelectAccountAdminMixin(AccountAdminMixin): def add_view(self, request, form_url='', extra_context=None): """ Redirects to select account view if required """ if request.user.is_superuser: - if 'account' in request.GET or Account.objects.count() == 1: + from_account_id = self.get_account_from_preserve_filters(request) + if from_account_id: + set_url_query(request, 'account', from_account_id) + account_id = request.GET.get('account') + if account_id or Account.objects.count() == 1: kwargs = {} - if 'account' in request.GET: - kwargs = dict(pk=request.GET['account']) + if account_id: + kwargs = dict(pk=account_id) self.account = Account.objects.get(**kwargs) opts = self.model._meta context = { - 'title': _("Add %s for %s") % (opts.verbose_name, self.account.name) + 'title': _("Add %s for %s") % (opts.verbose_name, self.account.name), + 'from_account': bool(from_account_id), + 'account': self.account, + 'account_opts': Account._meta, } context.update(extra_context or {}) return super(AccountAdminMixin, self).add_view(request, diff --git a/orchestra/apps/accounts/templates/admin/accounts/account/change_form.html b/orchestra/apps/accounts/templates/admin/accounts/account/change_form.html index d93f4d97..29fb608f 100644 --- a/orchestra/apps/accounts/templates/admin/accounts/account/change_form.html +++ b/orchestra/apps/accounts/templates/admin/accounts/account/change_form.html @@ -2,18 +2,34 @@ {% load i18n admin_urls admin_static admin_modify %} +{% block breadcrumbs %} +
+{% endblock %} + + {% block object-tools-items %} - - +{% if services %} {% for service in services %}