Reduce checked out document column label string size. Refactor roles: roles can only have groups as members, only roles can hold permissions.

This commit is contained in:
Roberto Rosario
2015-06-29 14:04:40 -04:00
parent 560e469e8c
commit 3754f45001
20 changed files with 195 additions and 251 deletions

View File

@@ -7,10 +7,10 @@ from .models import AccessEntry
class AccessEntryAdmin(admin.ModelAdmin):
model = AccessEntry
list_display = ('pk', 'holder_object', 'permission', 'content_object')
list_display = ('pk', 'role', 'permission', 'content_object')
list_display_links = ('pk',)
related_lookup_fields = {
'generic': [['holder_type', 'holder_id'], ['content_type', 'object_id']],
'generic': (('content_type', 'object_id'),),
}
admin.site.register(AccessEntry, AccessEntryAdmin)

View File

@@ -17,12 +17,12 @@ from .links import (
link_acl_detail, link_acl_grant, link_acl_holder_new, link_acl_revoke,
link_acl_setup_valid_classes
)
from .models import CreatorSingleton
#from .models import CreatorSingleton
def create_creator_user(sender, **kwargs):
if kwargs['app_config'].__class__ == ACLsApp:
CreatorSingleton.objects.get_or_create()
#def create_creator_user(sender, **kwargs):
# if kwargs['app_config'].__class__ == ACLsApp:
# CreatorSingleton.objects.get_or_create()
class ACLsApp(MayanAppConfig):
@@ -49,4 +49,4 @@ class ACLsApp(MayanAppConfig):
menu_setup.bind_links(links=[link_acl_setup_valid_classes])
menu_sidebar.bind_links(links=[link_acl_holder_new], sources=[AccessObject])
post_migrate.connect(create_creator_user, dispatch_uid='create_creator_user')
#post_migrate.connect(create_creator_user, dispatch_uid='create_creator_user')

View File

@@ -10,10 +10,6 @@ from common.utils import get_object_name
from permissions.models import Role
from .classes import AccessHolder
from .models import CreatorSingleton
anonymous_singleton = SimpleLazyObject(lambda: AnonymousUserSingleton.objects.get())
creator_singleton = SimpleLazyObject(lambda: CreatorSingleton.objects.get())
def _as_choice_list(holders):
@@ -55,8 +51,10 @@ class BaseHolderSelectionForm(forms.Form):
class HolderSelectionForm(BaseHolderSelectionForm):
special_holders = [anonymous_singleton]
pass
#special_holders = [anonymous_singleton]
class ClassHolderSelectionForm(BaseHolderSelectionForm):
special_holders = [anonymous_singleton, creator_singleton]
pass
#special_holders = [anonymous_singleton, creator_singleton]

View File

@@ -12,7 +12,7 @@ from django.utils.translation import ugettext
from common.models import AnonymousUserSingleton
from permissions import Permission
from permissions.models import RoleMember
#from permissions.models import RoleMember
from .classes import AccessHolder, ClassAccessHolder, get_source_object

View File

@@ -10,7 +10,7 @@ from django.utils.translation import ugettext_lazy as _, ugettext
from solo.models import SingletonModel
from permissions.models import StoredPermission
from permissions.models import Role, StoredPermission
from .api import get_classes
from .classes import AccessObjectClass
@@ -25,18 +25,7 @@ class AccessEntry(models.Model):
Model that hold the permission, object, actor relationship
"""
permission = models.ForeignKey(StoredPermission, verbose_name=_('Permission'))
holder_type = models.ForeignKey(
ContentType,
related_name='access_holder',
limit_choices_to={'model__in': ('user', 'group', 'role')}
)
holder_id = models.PositiveIntegerField()
holder_object = generic.GenericForeignKey(
ct_field='holder_type',
fk_field='holder_id'
)
role = models.ForeignKey(Role, verbose_name=_('Role'))
content_type = models.ForeignKey(
ContentType,
related_name='object_content_type'
@@ -68,22 +57,7 @@ class DefaultAccessEntry(models.Model):
return [AccessObjectClass.encapsulate(cls) for cls in get_classes()]
permission = models.ForeignKey(StoredPermission, verbose_name=_('Permission'))
holder_type = models.ForeignKey(
ContentType,
limit_choices_to={'model__in': ('user', 'group', 'role')},
related_name='default_access_entry_holder'
)
holder_id = models.PositiveIntegerField()
holder_object = generic.GenericForeignKey(
ct_field='holder_type',
fk_field='holder_id'
)
content_type = models.ForeignKey(
ContentType,
related_name='default_access_entry_class'
)
role = models.ForeignKey(Role, verbose_name=_('Role'))
objects = DefaultAccessEntryManager()
@@ -93,24 +67,3 @@ class DefaultAccessEntry(models.Model):
def __str__(self):
return '%s: %s' % (self.content_type, self.content_object)
class CreatorSingletonManager(models.Manager):
def passthru_check(self, holder, creator=None):
if isinstance(holder, self.model):
# TODO: raise explicit error if is instance and creator=None
return creator
else:
return holder
@python_2_unicode_compatible
class CreatorSingleton(SingletonModel):
objects = CreatorSingletonManager()
def __str__(self):
return ugettext('Creator')
class Meta:
verbose_name = _('Creator')
verbose_name_plural = _('Creator')

View File

@@ -7,7 +7,8 @@ from django.contrib.contenttypes.models import ContentType
from common.models import AnonymousUserSingleton
from .classes import get_source_object
from .models import AccessEntry, CreatorSingleton, DefaultAccessEntry
#from .models import AccessEntry, CreatorSingleton, DefaultAccessEntry
from .models import AccessEntry, DefaultAccessEntry
logger = logging.getLogger(__name__)
@@ -16,13 +17,14 @@ def apply_default_acls(obj, actor=None):
logger.debug('actor, init: %s', actor)
obj = get_source_object(obj)
if actor:
actor = AnonymousUserSingleton.objects.passthru_check(actor)
#if actor:
# actor = AnonymousUserSingleton.objects.passthru_check(actor)
content_type = ContentType.objects.get_for_model(obj)
for default_acl in DefaultAccessEntry.objects.filter(content_type=content_type):
holder = CreatorSingleton.objects.passthru_check(default_acl.holder_object, actor)
#holder = CreatorSingleton.objects.passthru_check(default_acl.holder_object, actor)
holder = actor
if holder:
# When the creator is admin

View File

@@ -5,13 +5,15 @@
{% block title %} :: {% include 'appearance/calculate_form_title.html' %}{% endblock %}
{% block content %}
{% if main_title %}
<h3>{{ main_title }}</h3>
{% if title %}
<h3>{{ title }}</h3>
<hr>
{% endif %}
{% if form %}
{% include "appearance/generic_form_subtemplate.html" %}
{% with '' as title %}
{% include "appearance/generic_form_subtemplate.html" %}
{% endwith %}
{% endif %}
<div class="row">

View File

@@ -34,7 +34,6 @@
{% endfor %}
{% for field in form.visible_fields %}
<div class="form-group {% if field.errors %}has-error{% endif %}">
{# We display the label then the field for all except checkboxes #}
{% if field|widget_type != 'checkboxinput' %}
{% if not hide_labels %}{{ field.label_tag }}{% if field.field.required and not read_only and not form_hide_required_text %} ({% trans 'required' %}){% endif %}{% endif %}

View File

@@ -1,10 +1,12 @@
{% load i18n %}
{% load static %}
<h3>
{% include 'appearance/calculate_form_title.html' %}
</h3>
{% if title %}
<h4>
{{ title }}
</h4>
<hr>
{% endif %}
<div class="well bs-component">
{% if form.is_multipart %}

View File

@@ -8,6 +8,11 @@
{% block title %} :: {% include 'appearance/calculate_form_title.html' %}{% endblock %}
{% block content %}
{% if title %}
<h3>{{ title }}</h3>
<hr>
{% endif %}
{% include 'appearance/generic_list_subtemplate.html' %}
{% endblock %}

View File

@@ -10,13 +10,13 @@
{% autopaginate object_list %}
<div class="row">
<div class="col-xs-12">
<h3>
<h4>
{% ifnotequal page_obj.paginator.num_pages 1 %}
{% blocktrans with page_obj.start_index as start and page_obj.end_index as end and page_obj.paginator.object_list|length as total and page_obj.number as page_number and page_obj.paginator.num_pages as total_pages %}{{ title }} ({{ start }} - {{ end }} out of {{ total }}) (Page {{ page_number }} of {{ total_pages }}){% endblocktrans %}
{% blocktrans with page_obj.start_index as start and page_obj.end_index as end and page_obj.paginator.object_list|length as total and page_obj.number as page_number and page_obj.paginator.num_pages as total_pages %}Total ({{ start }} - {{ end }} out of {{ total }}) (Page {{ page_number }} of {{ total_pages }}){% endblocktrans %}
{% else %}
{% blocktrans with page_obj.paginator.object_list|length as total %}{{ title }} ({{ total }}){% endblocktrans %}
{% blocktrans with page_obj.paginator.object_list|length as total %}Total: {{ total }}{% endblocktrans %}
{% endifnotequal %}
</h3>
</h4>
<hr>
<div class="well center-block">

View File

@@ -1,9 +1,9 @@
{% load i18n %}
{% load static %}
<h3>
<h4>
{% include 'appearance/calculate_form_title.html' %}
</h3>
</h4>
<hr>
<div class="well bs-component">

View File

@@ -33,7 +33,7 @@ class CheckoutListView(DocumentListView):
'title': _('Documents checked out'),
'hide_links': True,
'extra_columns': [
{'name': _('Checkout user'), 'attribute': encapsulate(lambda document: get_object_name(document.checkout_info().user))},
{'name': _('User'), 'attribute': encapsulate(lambda document: get_object_name(document.checkout_info().user))},
{'name': _('Checkout time and date'), 'attribute': encapsulate(lambda document: document.checkout_info().checkout_datetime)},
{'name': _('Checkout expiration'), 'attribute': encapsulate(lambda document: document.checkout_info().expiration_datetime)},
],

View File

@@ -2,32 +2,13 @@ from __future__ import unicode_literals
from django.contrib import admin
from .models import StoredPermission, PermissionHolder, Role, RoleMember
from .models import StoredPermission, Role
class PermissionHolderInline(admin.StackedInline):
model = PermissionHolder
extra = 1
classes = ('collapse-open',)
allow_add = True
class PermissionAdmin(admin.ModelAdmin):
inlines = [PermissionHolderInline]
class StoredPermissionAdmin(admin.ModelAdmin):
list_display = ('namespace', 'name')
list_display_links = list_display
class RoleMemberInline(admin.StackedInline):
model = RoleMember
extra = 1
classes = ('collapse-open',)
allow_add = True
class RoleAdmin(admin.ModelAdmin):
inlines = [RoleMemberInline]
admin.site.register(StoredPermission, PermissionAdmin)
admin.site.register(Role, RoleAdmin)
admin.site.register(StoredPermission, StoredPermissionAdmin)
admin.site.register(Role)

View File

@@ -12,15 +12,29 @@ class Member(EncapsulatedObject):
class PermissionNamespace(object):
_registry = {}
@classmethod
def all(cls):
return cls._registry.values()
@classmethod
def get(cls, name):
return cls._registry[name]
def __init__(self, name, label):
self.name = name
self.label = label
self.permissions = []
self.__class__._registry[name] = self
def __unicode__(self):
return unicode(self.label)
def add_permission(self, name, label):
return Permission(namespace=self, name=name, label=label)
permission = Permission(namespace=self, name=name, label=label)
self.permissions.append(permission)
return permission
class Permission(object):

View File

@@ -0,0 +1,49 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('auth', '0001_initial'),
('permissions', '0001_initial'),
]
operations = [
migrations.RemoveField(
model_name='permissionholder',
name='holder_type',
),
migrations.RemoveField(
model_name='permissionholder',
name='permission',
),
migrations.DeleteModel(
name='PermissionHolder',
),
migrations.RemoveField(
model_name='rolemember',
name='member_type',
),
migrations.RemoveField(
model_name='rolemember',
name='role',
),
migrations.DeleteModel(
name='RoleMember',
),
migrations.AddField(
model_name='role',
name='groups',
field=models.ManyToManyField(related_name='roles', verbose_name='Groups', to='auth.Group'),
preserve_default=True,
),
migrations.AddField(
model_name='role',
name='permissions',
field=models.ManyToManyField(related_name='roles', verbose_name='Permissions', to='permissions.StoredPermission'),
preserve_default=True,
),
]

View File

@@ -2,7 +2,7 @@ from __future__ import unicode_literals
import logging
from django.contrib.auth.models import User
from django.contrib.auth.models import Group, User
from django.contrib.contenttypes import generic
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import PermissionDenied
@@ -12,7 +12,7 @@ from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext
from django.utils.translation import ugettext_lazy as _
from common.models import AnonymousUserSingleton
#from common.models import AnonymousUserSingleton
from .managers import RoleMemberManager, StoredPermissionManager
@@ -47,10 +47,12 @@ class StoredPermission(models.Model):
return unicode(getattr(self, 'volatile_permission', self.name))
def get_holders(self):
return (holder.holder_object for holder in self.permissionholder_set.all())
return self.roles.all()
#return (holder.holder_object for holder in self.permissionholder_set.all())
def requester_has_this(self, actor):
actor = AnonymousUserSingleton.objects.passthru_check(actor)
#actor = AnonymousUserSingleton.objects.passthru_check(actor)
logger.debug('actor: %s', actor)
if isinstance(actor, User):
if actor.is_superuser or actor.is_staff:
@@ -92,6 +94,7 @@ class StoredPermission(models.Model):
return True
"""
@python_2_unicode_compatible
class PermissionHolder(models.Model):
permission = models.ForeignKey(StoredPermission, verbose_name=_('Permission'))
@@ -107,12 +110,14 @@ class PermissionHolder(models.Model):
def __str__(self):
return '%s: %s' % (self.holder_type, self.holder_object)
"""
@python_2_unicode_compatible
class Role(models.Model):
name = models.CharField(max_length=64, unique=True)
label = models.CharField(max_length=64, unique=True, verbose_name=_('Label'))
permissions = models.ManyToManyField(StoredPermission, related_name='roles', verbose_name=_('Permissions'))
groups = models.ManyToManyField(Group, related_name='roles', verbose_name=_('Groups'))
class Meta:
ordering = ('label',)
@@ -125,6 +130,7 @@ class Role(models.Model):
def get_absolute_url(self):
return reverse('permissions:role_list')
"""
def add_member(self, member):
member = AnonymousUserSingleton.objects.passthru_check(member)
role_member, created = RoleMember.objects.get_or_create(
@@ -143,8 +149,9 @@ class Role(models.Model):
def members(self, filter_dict=None):
filter_dict = filter_dict or {}
return (member.member_object for member in self.rolemember_set.filter(**filter_dict))
"""
"""
@python_2_unicode_compatible
class RoleMember(models.Model):
role = models.ForeignKey(Role, verbose_name=_('Role'))
@@ -168,3 +175,4 @@ class RoleMember(models.Model):
def __str__(self):
return unicode(self.member_object)
"""

View File

@@ -4,20 +4,18 @@ from django.conf.urls import patterns, url
from .api_views import APIRoleListView, APIRoleView
from .views import (
RoleCreateView, RoleDeleteView, RoleEditView, SetupRoleMembersView
RoleCreateView, RoleDeleteView, RoleEditView, SetupRoleMembersView,
SetupRolePermissionsView
)
urlpatterns = patterns(
'permissions.views',
url(r'^role/list/$', 'role_list', name='role_list'),
url(r'^role/create/$', RoleCreateView.as_view(), name='role_create'),
url(r'^role/(?P<role_id>\d+)/permissions/$', 'role_permissions', name='role_permissions'),
url(r'^role/(?P<pk>\d+)/permissions/$', SetupRolePermissionsView.as_view(), name='role_permissions'),
url(r'^role/(?P<pk>\d+)/edit/$', RoleEditView.as_view(), name='role_edit'),
url(r'^role/(?P<pk>\d+)/delete/$', RoleDeleteView.as_view(), name='role_delete'),
url(r'^role/(?P<role_id>\d+)/members/$', SetupRoleMembersView.as_view(), name='role_members'),
url(r'^permissions/multiple/grant/$', 'permission_grant', name='permission_multiple_grant'),
url(r'^permissions/multiple/revoke/$', 'permission_revoke', name='permission_multiple_revoke'),
)
api_urls = patterns(

View File

@@ -5,6 +5,7 @@ from json import loads
import operator
from django.contrib import messages
from django.contrib.auth.models import Group
from django.contrib.contenttypes.models import ContentType
from django.core.urlresolvers import reverse
from django.core.urlresolvers import reverse_lazy
@@ -21,9 +22,9 @@ from common.views import (
from common.utils import encapsulate
from common.widgets import two_state_template
from .classes import Member, Permission
from .classes import Member, Permission, PermissionNamespace
from .forms import RoleForm, RoleForm_view
from .models import Role
from .models import Role, StoredPermission
from .permissions import (
permission_permission_grant, permission_permission_revoke,
permission_role_view, permission_role_create, permission_role_delete,
@@ -51,34 +52,84 @@ class RoleEditView(SingleObjectEditView):
class SetupRoleMembersView(AssignRemoveView):
grouped = True
grouped = False
def add(self, item):
member = Member.get(item).source_object
self.role.add_member(member)
group = get_object_or_404(Group, pk=item)
self.role.groups.add(group)
def dispatch(self, request, *args, **kwargs):
Permission.check_permissions(request.user, [permission_role_edit])
self.role = get_object_or_404(Role, pk=self.kwargs['role_id'])
self.left_list_title = _('Non members of role: %s') % self.role
self.right_list_title = _('Members of role: %s') % self.role
self.left_list_title = _('Available groups')
self.right_list_title = _('Member groups')
return super(SetupRoleMembersView, self).dispatch(request, *args, **kwargs)
def left_list(self):
return get_non_role_members(self.role)
return [(unicode(group.pk), group.name) for group in set(Group.objects.all()) - set(self.role.groups.all())]
def right_list(self):
return get_role_members(self.role)
return [(unicode(group.pk), group.name) for group in self.role.groups.all()]
def remove(self, item):
member = Member.get(item).source_object
self.role.remove_member(member)
group = get_object_or_404(Group, pk=item)
self.role.groups.remove(group)
def get_context_data(self, **kwargs):
data = super(SetupRoleMembersView, self).get_context_data(**kwargs)
data.update({
'object': self.role,
'title': _('Group members of role: %s') % self.role
})
return data
class SetupRolePermissionsView(AssignRemoveView):
grouped = True
@staticmethod
def as_choice_list(items):
return sorted([(item.pk, item) for item in items], key=lambda x: x[1])
def add(self, item):
permission = get_object_or_404(StoredPermission, pk=item)
self.role.permissions.add(permission)
def dispatch(self, request, *args, **kwargs):
Permission.check_permissions(request.user, [permission_permission_grant, permission_permission_revoke])
self.role = get_object_or_404(Role, pk=self.kwargs['pk'])
self.left_list_title = _('Available permissions')
self.right_list_title = _('Granted permissions')
return super(SetupRolePermissionsView, self).dispatch(request, *args, **kwargs)
def left_list(self):
results = []
for namespace, permissions in itertools.groupby(StoredPermission.objects.exclude(id__in=self.role.permissions.values_list('pk', flat=True)), lambda entry: entry.namespace):
permission_options = [(unicode(permission.pk), permission) for permission in permissions]
results.append((PermissionNamespace.get(namespace), permission_options))
return results
def right_list(self):
results = []
for namespace, permissions in itertools.groupby(self.role.permissions.all(), lambda entry: entry.namespace):
permission_options = [(unicode(permission.pk), permission) for permission in permissions]
results.append((PermissionNamespace.get(namespace), permission_options))
return results
def remove(self, item):
permission = get_object_or_404(StoredPermission, pk=item)
self.role.permissions.remove(permission)
def get_context_data(self, **kwargs):
data = super(SetupRolePermissionsView, self).get_context_data(**kwargs)
data.update({
'object': self.role,
'title': _('Permissions for role: %s') % self.role,
})
return data
@@ -123,123 +174,3 @@ def role_permissions(request, role_id):
'hide_link': True,
'hide_object': True,
}, context_instance=RequestContext(request))
def permission_grant(request):
Permission.check_permissions(request.user, [permission_permission_grant])
items_property_list = loads(request.GET.get('items_property_list', []))
next = request.POST.get('next', request.GET.get('next', request.META.get('HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL))))
previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL))))
items = []
for item_properties in items_property_list:
try:
permission = Permission.get({'pk': item_properties['permission_id']})
except Permission.DoesNotExist:
raise Http404
ct = get_object_or_404(ContentType, app_label=item_properties['requester_app_label'], model=item_properties['requester_model'])
requester_model = ct.model_class()
requester = get_object_or_404(requester_model, pk=item_properties['requester_id'])
items.append({'requester': requester, 'permission': permission})
sorted_items = sorted(items, key=operator.itemgetter('requester'))
# Group items by requester
groups = itertools.groupby(sorted_items, key=operator.itemgetter('requester'))
grouped_items = [(grouper, [permission['permission'] for permission in group_data]) for grouper, group_data in groups]
# Warning: trial and error black magic ahead
title_suffix = _(' and ').join([_('%(permissions)s to %(requester)s') % {'permissions': ', '.join(['"%s"' % unicode(ps) for ps in p]), 'requester': unicode(r)} for r, p in grouped_items])
if len(grouped_items) == 1 and len(grouped_items[0][1]) == 1:
permissions_label = _('Permission')
else:
permissions_label = _('Permissions')
if request.method == 'POST':
for item in items:
if item['permission'].grant_to(item['requester']):
messages.success(request, _('Permission "%(permission)s" granted to: %(requester)s.') % {
'permission': item['permission'], 'requester': item['requester']})
else:
messages.warning(request, _('%(requester)s, already had the permission "%(permission)s" granted.') % {
'requester': item['requester'], 'permission': item['permission']})
return HttpResponseRedirect(next)
context = {
'previous': previous,
'next': next,
}
context['title'] = _('Are you sure you wish to grant the %(permissions_label)s %(title_suffix)s?') % {
'permissions_label': permissions_label,
'title_suffix': title_suffix,
}
if len(grouped_items) == 1:
context['object'] = grouped_items[0][0]
return render_to_response('appearance/generic_confirm.html', context,
context_instance=RequestContext(request))
def permission_revoke(request):
Permission.check_permissions(request.user, [permission_permission_revoke])
items_property_list = loads(request.GET.get('items_property_list', []))
next = request.POST.get('next', request.GET.get('next', request.META.get('HTTP_REFERER', None)))
previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', None)))
items = []
for item_properties in items_property_list:
try:
permission = Permission.get({'pk': item_properties['permission_id']})
except Permission.DoesNotExist:
raise Http404
ct = get_object_or_404(ContentType, app_label=item_properties['requester_app_label'], model=item_properties['requester_model'])
requester_model = ct.model_class()
requester = get_object_or_404(requester_model, pk=item_properties['requester_id'])
items.append({'requester': requester, 'permission': permission})
sorted_items = sorted(items, key=operator.itemgetter('requester'))
# Group items by requester
groups = itertools.groupby(sorted_items, key=operator.itemgetter('requester'))
grouped_items = [(grouper, [permission['permission'] for permission in group_data]) for grouper, group_data in groups]
# Warning: trial and error black magic ahead
title_suffix = _(' and ').join([_('%(permissions)s to %(requester)s') % {'permissions': ', '.join(['"%s"' % unicode(ps) for ps in p]), 'requester': unicode(r)} for r, p in grouped_items])
if len(grouped_items) == 1 and len(grouped_items[0][1]) == 1:
permissions_label = _('permission')
else:
permissions_label = _('permissions')
if request.method == 'POST':
for item in items:
if item['permission'].revoke_from(item['requester']):
messages.success(request, _('Permission "%(permission)s" revoked from: %(requester)s.') % {
'permission': item['permission'], 'requester': item['requester']})
else:
messages.warning(request, _('%(requester)s, doesn\'t have the permission "%(permission)s" granted.') % {
'requester': item['requester'], 'permission': item['permission']})
return HttpResponseRedirect(next)
context = {
'previous': previous,
'next': next,
}
context['title'] = _('Are you sure you wish to revoke the %(permissions_label)s %(title_suffix)s?') % {
'permissions_label': permissions_label,
'title_suffix': title_suffix,
}
if len(grouped_items) == 1:
context['object'] = grouped_items[0][0]
return render_to_response('appearance/generic_confirm.html', context,
context_instance=RequestContext(request))

View File

@@ -157,14 +157,15 @@ class UploadBaseView(MultiFormView):
'name': 'appearance/generic_multiform_subtemplate.html',
'context': {
'forms': context['forms'],
'title': _('Document properties'),
}
},
{
'name': 'appearance/generic_list_subtemplate.html',
'context': {
'title': _('Files in staging path'),
'object_list': staging_filelist,
'hide_link': True,
'object_list': staging_filelist,
'title': _('Files in staging path'),
}
},
]
@@ -173,7 +174,8 @@ class UploadBaseView(MultiFormView):
'name': 'appearance/generic_multiform_subtemplate.html',
'context': {
'forms': context['forms'],
'is_multipart': True
'is_multipart': True,
'title': _('Document properties'),
},
})