diff --git a/orchestra/api/helpers.py b/orchestra/api/helpers.py index 67594455..53803d9a 100644 --- a/orchestra/api/helpers.py +++ b/orchestra/api/helpers.py @@ -23,16 +23,16 @@ def link_wrap(view, view_names): return wrapper -def insert_links(viewset, base_name): - collection_links = ['api-root', '%s-list' % base_name] - object_links = ['api-root', '%s-list' % base_name, '%s-detail' % base_name] +def insert_links(viewset, basename): + collection_links = ['api-root', '%s-list' % basename] + object_links = ['api-root', '%s-list' % basename, '%s-detail' % basename] exception_links = ['api-root'] list_links = ['api-root'] - retrieve_links = ['api-root', '%s-list' % base_name] + retrieve_links = ['api-root', '%s-list' % basename] # Determine any `@action` or `@link` decorated methods on the viewset for methodname in dir(viewset): method = getattr(viewset, methodname) - view_name = '%s-%s' % (base_name, methodname.replace('_', '-')) + view_name = '%s-%s' % (basename, methodname.replace('_', '-')) if hasattr(method, 'collection_bind_to_methods'): list_links.append(view_name) retrieve_links.append(view_name) diff --git a/orchestra/api/options.py b/orchestra/api/options.py index 639f5927..4d429a03 100644 --- a/orchestra/api/options.py +++ b/orchestra/api/options.py @@ -65,12 +65,12 @@ class LinkHeaderRouter(DefaultRouter): APIRoot.router = self return APIRoot.as_view() - def register(self, prefix, viewset, base_name=None): + def register(self, prefix, viewset, basename=None): """ inserts link headers on every viewset """ - if base_name is None: - base_name = self.get_default_basename(viewset) - insert_links(viewset, base_name) - self.registry.append((prefix, viewset, base_name)) + if basename is None: + basename = self.get_default_basename(viewset) + insert_links(viewset, basename) + self.registry.append((prefix, viewset, basename)) def get_viewset(self, prefix_or_model): for _prefix, viewset, __ in self.registry: diff --git a/orchestra/conf/project_template/project_name/settings.py b/orchestra/conf/project_template/project_name/settings.py index f8c8d6a2..82b244f9 100644 --- a/orchestra/conf/project_template/project_name/settings.py +++ b/orchestra/conf/project_template/project_name/settings.py @@ -261,7 +261,6 @@ PASSLIB_CONFIG = ( "default = sha512_crypt\n" "deprecated = django_pbkdf2_sha1, django_salted_sha1, django_salted_md5, " " django_des_crypt, des_crypt, hex_md5\n" - "all__vary_rounds = 0.05\n" "django_pbkdf2_sha256__min_rounds = 10000\n" "sha512_crypt__min_rounds = 80000\n" "staff__django_pbkdf2_sha256__default_rounds = 12500\n" diff --git a/orchestra/contrib/issues/admin.py b/orchestra/contrib/issues/admin.py index 66881ddd..7b607fe9 100644 --- a/orchestra/contrib/issues/admin.py +++ b/orchestra/contrib/issues/admin.py @@ -138,7 +138,7 @@ class TicketAdmin(ExtendedModelAdmin): 'owner__username' ) actions = ( - mark_as_unread, mark_as_read, 'delete_selected', reject_tickets, + mark_as_unread, mark_as_read, reject_tickets, resolve_tickets, close_tickets, take_tickets ) sudo_actions = ('delete_selected',) diff --git a/orchestra/contrib/payments/actions.py b/orchestra/contrib/payments/actions.py index e6b4b348..d2f5a433 100644 --- a/orchestra/contrib/payments/actions.py +++ b/orchestra/contrib/payments/actions.py @@ -175,16 +175,6 @@ commit.url_name = 'commit' commit.short_description = _("Commit") -def delete_selected(modeladmin, request, queryset): - """ Has to have same name as admin.actions.delete_selected """ - related_transactions = helpers.pre_delete_processes(modeladmin, request, queryset) - response = actions.delete_selected(modeladmin, request, queryset) - if response is None: - helpers.post_delete_processes(modeladmin, request, related_transactions) - return response -delete_selected.short_description = actions.delete_selected.short_description - - def report(modeladmin, request, queryset): if queryset.model == Transaction: transactions = queryset diff --git a/orchestra/contrib/payments/admin.py b/orchestra/contrib/payments/admin.py index 45b67a48..016543ac 100644 --- a/orchestra/contrib/payments/admin.py +++ b/orchestra/contrib/payments/admin.py @@ -179,7 +179,7 @@ class TransactionProcessAdmin(ChangeViewActionsMixin, admin.ModelAdmin): change_view_actions = ( actions.mark_process_as_executed, actions.abort, actions.commit, actions.report ) - actions = change_view_actions + (actions.delete_selected,) + actions = change_view_actions display_state = admin_colored('state', colors=PROCESS_STATE_COLORS) display_created_at = admin_date('created_at', short_description=_("Created")) @@ -233,6 +233,13 @@ class TransactionProcessAdmin(ChangeViewActionsMixin, admin.ModelAdmin): helpers.post_delete_processes(self, request, related_transactions) return response + def delete_queryset(self, request, queryset): + # override default admin action delete behaviour + related_transactions = helpers.pre_delete_processes(self, request, queryset) + super().delete_queryset(self, request, queryset) + helpers.post_delete_processes(self, request, related_transactions) + + admin.site.register(PaymentSource, PaymentSourceAdmin) admin.site.register(Transaction, TransactionAdmin) admin.site.register(TransactionProcess, TransactionProcessAdmin) diff --git a/orchestra/contrib/payments/helpers.py b/orchestra/contrib/payments/helpers.py index 9fde2489..b6645d53 100644 --- a/orchestra/contrib/payments/helpers.py +++ b/orchestra/contrib/payments/helpers.py @@ -5,7 +5,6 @@ from .models import Transaction def pre_delete_processes(modeladmin, request, queryset): - """ Has to have same name as admin.actions.delete_selected """ if not queryset: messages.warning(request, _("No transaction process selected.")) diff --git a/orchestra/contrib/systemusers/actions.py b/orchestra/contrib/systemusers/actions.py index f2e53ec5..80743ea4 100644 --- a/orchestra/contrib/systemusers/actions.py +++ b/orchestra/contrib/systemusers/actions.py @@ -128,29 +128,3 @@ def create_link(modeladmin, request, queryset): return TemplateResponse(request, 'admin/systemusers/systemuser/create_link.html', context) create_link.url_name = 'create-link' create_link.tool_description = _("Create link") - - -def delete_selected(modeladmin, request, queryset): - """ wrapper arround admin.actions.delete_selected to prevent main system users deletion """ - opts = modeladmin.model._meta - app_label = opts.app_label - # Check that the user has delete permission for the actual model - if not modeladmin.has_delete_permission(request): - raise PermissionDenied - else: - accounts = [] - for user in queryset: - if user.is_main: - accounts.append(user.username) - if accounts: - n = len(accounts) - messages.error(request, ungettext( - "You have selected one main system user (%(accounts)s), which can not be deleted.", - "You have selected some main system users which can not be deleted (%(accounts)s).", - n) % { - 'accounts': ', '.join(accounts[:10]+['...'] if n > 10 else accounts) - } - ) - return - return admin.actions.delete_selected(modeladmin, request, queryset) -delete_selected.short_description = _("Delete selected %(verbose_name_plural)s") diff --git a/orchestra/contrib/systemusers/admin.py b/orchestra/contrib/systemusers/admin.py index fed11679..59b4c271 100644 --- a/orchestra/contrib/systemusers/admin.py +++ b/orchestra/contrib/systemusers/admin.py @@ -1,4 +1,4 @@ -from django.contrib import admin +from django.contrib import admin, messages from django.utils.translation import ugettext_lazy as _ from orchestra.admin import ExtendedModelAdmin, ChangePasswordAdminMixin @@ -7,7 +7,7 @@ from orchestra.contrib.accounts.actions import list_accounts from orchestra.contrib.accounts.admin import SelectAccountAdminMixin from orchestra.contrib.accounts.filters import IsActiveListFilter -from .actions import set_permission, create_link, delete_selected +from .actions import set_permission, create_link from .filters import IsMainListFilter from .forms import SystemUserCreationForm, SystemUserChangeForm from .models import SystemUser @@ -43,18 +43,18 @@ class SystemUserAdmin(ChangePasswordAdminMixin, SelectAccountAdminMixin, Extende form = SystemUserChangeForm ordering = ('-id',) change_view_actions = (set_permission, create_link) - actions = (disable, enable, delete_selected, list_accounts) + change_view_actions - + actions = (disable, enable, list_accounts) + change_view_actions + def display_main(self, user): return user.is_main display_main.short_description = _("Main") display_main.boolean = True - + def display_home(self, user): return user.get_home() display_home.short_description = _("Home") display_home.admin_order_field = 'home' - + def get_form(self, request, obj=None, **kwargs): form = super(SystemUserAdmin, self).get_form(request, obj, **kwargs) form.account = self.account @@ -65,9 +65,15 @@ class SystemUserAdmin(ChangePasswordAdminMixin, SelectAccountAdminMixin, Extende formfield = form.base_fields['groups'] formfield.queryset = formfield.queryset.exclude(id=obj.id) return form - + def has_delete_permission(self, request, obj=None): if obj and obj.is_main: + self.message_user(request, _( + "You have selected one main system user (%(account)s), which can not be deleted.", + ) % {'account': obj}, + messages.ERROR, + ) + return False return super(SystemUserAdmin, self).has_delete_permission(request, obj) diff --git a/requirements.txt b/requirements.txt index ae2fa60f..14d5ce5e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,24 +1,23 @@ -Django==2.1 +Django==2.2.24 django-fluent-dashboard==1.0.1 django-admin-tools==0.9.1 -django-extensions==2.1.1 +django-extensions==3.1.3 django-celery==3.2.1 celery==3.1.23 kombu==3.0.35 billiard==3.3.0.23 Markdown==3.3.4 -djangorestframework==3.10.3 -ecdsa==0.11 -Pygments==1.6 -django-filter==2.2.0 -jsonfield==0.9.22 +djangorestframework==3.12.4 +Pygments==2.9.0 +django-filter==2.4.0 +jsonfield==3.1.0 python-dateutil>=2.7.0 -https://github.com/glic3rinu/passlib/archive/master.zip +passlib==1.7.4 django-iban==0.3.0 requests -phonenumbers +phonenumbers==8.12.27 django-countries -django-localflavor +django-localflavor==3.1 amqp anyjson pytz