from django.conf.urls import patterns, url from django.core.urlresolvers import reverse from django.contrib import admin from django.contrib.admin.util import unquote from django.contrib.auth import admin as auth from django.utils.translation import ugettext, ugettext_lazy as _ from orchestra.admin import ExtendedModelAdmin from orchestra.admin.utils import wrap_admin_view from orchestra.apps.accounts.admin import AccountAdminMixin from .forms import UserCreationForm, UserChangeForm from .models import User from .roles.filters import role_list_filter_factory class UserAdmin(AccountAdminMixin, auth.UserAdmin, ExtendedModelAdmin): list_display = ('username', 'display_is_main') list_filter = ('is_staff', 'is_superuser', 'is_active') fieldsets = ( (None, { 'fields': ('account', 'username', 'password') }), (_("Personal info"), { 'fields': ('first_name', 'last_name', 'email') }), (_("Permissions"), { 'fields': ('is_active', 'is_staff', 'is_superuser', 'display_is_main') }), (_("Important dates"), { 'fields': ('last_login', 'date_joined') }), ) add_fieldsets = ( (None, { 'classes': ('wide',), 'fields': ('username', 'password1', 'password2', 'account'), }), ) search_fields = ['username', 'account__user__username'] readonly_fields = ('display_is_main', 'account_link') change_readonly_fields = ('username',) filter_horizontal = () add_form = UserCreationForm form = UserChangeForm roles = [] ordering = ('-id',) change_form_template = 'admin/users/user/change_form.html' def display_is_main(self, instance): return instance.is_main display_is_main.short_description = _("is main") display_is_main.boolean = True def get_urls(self): """ Returns the additional urls for the change view links """ urls = super(UserAdmin, self).get_urls() opts = self.model._meta new_urls = patterns("") for role in self.roles: new_urls += patterns("", url('^(\d+)/%s/$' % role.url_name, wrap_admin_view(self, role().change_view), name='%s_%s_%s_change' % (opts.app_label, opts.model_name, role.name)), url('^(\d+)/%s/delete/$' % role.url_name, wrap_admin_view(self, role().delete_view), name='%s_%s_%s_delete' % (opts.app_label, opts.model_name, role.name)) ) return new_urls + urls def get_fieldsets(self, request, obj=None): fieldsets = super(UserAdmin, self).get_fieldsets(request, obj=obj) if obj and obj.account: fieldsets[0][1]['fields'] = ('account_link',) + fieldsets[0][1]['fields'][1:] return fieldsets def get_list_display(self, request): roles = [] for role in self.roles: def has_role(user, role_class=role): role = role_class(user=user) if role.exists: return 'True' url = reverse('admin:users_user_%s_change' % role.name, args=(user.pk,)) false = 'False' return '%s' % (url, false) has_role.short_description = _("Has %s") % role.name has_role.admin_order_field = role.name has_role.allow_tags = True roles.append(has_role) return list(self.list_display) + roles + ['account_link'] def get_list_filter(self, request): roles = [ role_list_filter_factory(role) for role in self.roles ] return list(self.list_filter) + roles def change_view(self, request, object_id, **kwargs): user = self.get_object(User, unquote(object_id)) extra_context = kwargs.get('extra_context', {}) extra_context['roles'] = [ role(user=user) for role in self.roles ] kwargs['extra_context'] = extra_context return super(UserAdmin, self).change_view(request, object_id, **kwargs) def get_queryset(self, request): """ Select related for performance """ related = ['account__user'] + [ role.name for role in self.roles ] return super(UserAdmin, self).get_queryset(request).select_related(*related) admin.site.register(User, UserAdmin)