django-authority/authority/admin.py
greg 91929a76c9 Features removed in 1.9 :
1. All models need to be defined inside an installed application or declare an explicit app_label. Furthermore, it isn’t possible to import them before their application is loaded. In particular, it isn’t possible to import models inside the root package of an application

2. The django.contrib.contenttypes.generic module is removed

3. django.db.models.loading is removed.
2016-07-27 18:41:25 +02:00

175 lines
7 KiB
Python

from django import forms, template
from django.http import HttpResponseRedirect
from django.utils.translation import ugettext, ungettext, ugettext_lazy as _
from django.shortcuts import render_to_response
from django.utils.safestring import mark_safe
from django.forms.formsets import all_valid
from django.contrib import admin
from django.contrib.admin import helpers
from django.contrib.contenttypes.admin import GenericTabularInline
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import PermissionDenied
try:
from django.utils.encoding import force_text
except ImportError:
from django.utils.encoding import force_unicode as force_text
try:
from django.contrib.admin import actions
except ImportError:
actions = False
from authority.models import Permission
from authority.widgets import GenericForeignKeyRawIdWidget
from authority.utils import get_choices_for
class PermissionInline(GenericTabularInline):
model = Permission
raw_id_fields = ('user', 'group', 'creator')
extra = 1
def formfield_for_dbfield(self, db_field, **kwargs):
if db_field.name == 'codename':
perm_choices = get_choices_for(self.parent_model)
kwargs['label'] = _('permission')
kwargs['widget'] = forms.Select(choices=perm_choices)
return super(PermissionInline, self).formfield_for_dbfield(db_field, **kwargs)
class ActionPermissionInline(PermissionInline):
raw_id_fields = ()
template = 'admin/edit_inline/action_tabular.html'
class ActionErrorList(forms.utils.ErrorList):
def __init__(self, inline_formsets):
for inline_formset in inline_formsets:
self.extend(inline_formset.non_form_errors())
for errors_in_inline_form in inline_formset.errors:
self.extend(errors_in_inline_form.values())
def edit_permissions(modeladmin, request, queryset):
opts = modeladmin.model._meta
app_label = opts.app_label
# Check that the user has the permission to edit permissions
if not (request.user.is_superuser or
request.user.has_perm('authority.change_permission') or
request.user.has_perm('authority.change_foreign_permissions')):
raise PermissionDenied
inline = ActionPermissionInline(queryset.model, modeladmin.admin_site)
formsets = []
for obj in queryset:
prefixes = {}
FormSet = inline.get_formset(request, obj)
prefix = "%s-%s" % (FormSet.get_default_prefix(), obj.pk)
prefixes[prefix] = prefixes.get(prefix, 0) + 1
if prefixes[prefix] != 1:
prefix = "%s-%s" % (prefix, prefixes[prefix])
if request.POST.get('post'):
formset = FormSet(data=request.POST, files=request.FILES,
instance=obj, prefix=prefix)
else:
formset = FormSet(instance=obj, prefix=prefix)
formsets.append(formset)
media = modeladmin.media
inline_admin_formsets = []
for formset in formsets:
fieldsets = list(inline.get_fieldsets(request))
inline_admin_formset = helpers.InlineAdminFormSet(inline, formset, fieldsets)
inline_admin_formsets.append(inline_admin_formset)
media = media + inline_admin_formset.media
ordered_objects = opts.get_ordered_objects()
if request.POST.get('post'):
if all_valid(formsets):
for formset in formsets:
formset.save()
else:
modeladmin.message_user(request, '; '.join(
err.as_text() for formset in formsets for err in formset.errors
))
# redirect to full request path to make sure we keep filter
return HttpResponseRedirect(request.get_full_path())
context = {
'errors': ActionErrorList(formsets),
'title': ugettext('Permissions for %s') % force_text(opts.verbose_name_plural),
'inline_admin_formsets': inline_admin_formsets,
'app_label': app_label,
'change': True,
'ordered_objects': ordered_objects,
'form_url': mark_safe(''),
'opts': opts,
'target_opts': queryset.model._meta,
'content_type_id': ContentType.objects.get_for_model(queryset.model).id,
'save_as': False,
'save_on_top': False,
'is_popup': False,
'media': mark_safe(media),
'show_delete': False,
'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME,
'queryset': queryset,
"object_name": force_text(opts.verbose_name),
}
template_name = getattr(modeladmin, 'permission_change_form_template', [
"admin/%s/%s/permission_change_form.html" % (app_label, opts.object_name.lower()),
"admin/%s/permission_change_form.html" % app_label,
"admin/permission_change_form.html"
])
return render_to_response(template_name, context,
context_instance=template.RequestContext(request))
edit_permissions.short_description = _("Edit permissions for selected %(verbose_name_plural)s")
class PermissionAdmin(admin.ModelAdmin):
list_display = ('codename', 'content_type', 'user', 'group', 'approved')
list_filter = ('approved', 'content_type')
search_fields = ('user__username', 'group__name', 'codename')
raw_id_fields = ('user', 'group', 'creator')
generic_fields = ('content_object',)
actions = ['approve_permissions']
fieldsets = (
(None, {'fields': ('codename', ('content_type', 'object_id'))}),
(_('Permitted'), {'fields': ('approved', 'user', 'group')}),
(_('Creation'), {'fields': ('creator', 'date_requested', 'date_approved')}),
)
def formfield_for_dbfield(self, db_field, **kwargs):
# For generic foreign keys marked as generic_fields we use a special widget
names = [f.fk_field
for f in self.model._meta.virtual_fields
if f.name in self.generic_fields]
if db_field.name in names:
for gfk in self.model._meta.virtual_fields:
if gfk.fk_field == db_field.name:
kwargs['widget'] = GenericForeignKeyRawIdWidget(
gfk.ct_field, self.admin_site._registry.keys())
break
return super(PermissionAdmin, self).formfield_for_dbfield(db_field, **kwargs)
def queryset(self, request):
user = request.user
if (user.is_superuser or
user.has_perm('permissions.change_foreign_permissions')):
return super(PermissionAdmin, self).queryset(request)
return super(PermissionAdmin, self).queryset(request).filter(creator=user)
def approve_permissions(self, request, queryset):
for permission in queryset:
permission.approve(request.user)
message = ungettext(
"%(count)d permission successfully approved.",
"%(count)d permissions successfully approved.", len(queryset))
self.message_user(request, message % {'count': len(queryset)})
approve_permissions.short_description = _("Approve selected permissions")
admin.site.register(Permission, PermissionAdmin)
if actions:
admin.site.add_action(edit_permissions)