Ticket #3522: deleted_objects_fix2.diff
File deleted_objects_fix2.diff, 12.5 KB (added by , 17 years ago) |
---|
-
options.py
3 3 from django.newforms.formsets import all_valid 4 4 from django.newforms.models import inline_formset 5 5 from django.contrib.admin import widgets 6 from django.core.exceptions import ImproperlyConfigured, PermissionDenied 6 from django.core.exceptions import ImproperlyConfigured, PermissionDenied, ObjectDoesNotExist 7 7 from django.db import models 8 8 from django.http import Http404, HttpResponse, HttpResponseRedirect 9 9 from django.shortcuts import get_object_or_404, render_to_response … … 34 34 myappend('_' + item) 35 35 return "".join(res) 36 36 37 def _nest_help(obj, depth, val): 38 current = obj 39 for i in range(depth): 40 current = current[-1] 41 current.append(val) 42 43 def _get_deleted_objects(deleted_objects, perms_needed, user, obj, opts, current_depth): 44 "Helper function that recursively populates deleted_objects." 45 nh = _nest_help # Bind to local variable for performance 46 if current_depth > 16: 47 return # Avoid recursing too deep. 48 opts_seen = [] 49 for related in opts.get_all_related_objects(): 50 if related.opts in opts_seen: 51 continue 52 opts_seen.append(related.opts) 53 rel_opts_name = related.get_accessor_name() 54 if isinstance(related.field.rel, models.OneToOneRel): 55 try: 56 sub_obj = getattr(obj, rel_opts_name) 57 except ObjectDoesNotExist: 58 pass 59 else: 60 if related.opts.admin: 61 p = '%s.%s' % (related.opts.app_label, related.opts.get_delete_permission()) 62 if not user.has_perm(p): 63 perms_needed.add(related.opts.verbose_name) 64 # We don't care about populating deleted_objects now. 65 continue 66 if related.field.rel.edit_inline or not related.opts.admin: 67 # Don't display link to edit, because it either has no 68 # admin or is edited inline. 69 nh(deleted_objects, current_depth, ['%s: %s' % (capfirst(related.opts.verbose_name), sub_obj), []]) 70 else: 71 # Display a link to the admin page. 72 nh(deleted_objects, current_depth, ['%s: <a href="../../../../%s/%s/%s/">%s</a>' % \ 73 (capfirst(related.opts.verbose_name), related.opts.app_label, related.opts.object_name.lower(), 74 sub_obj._get_pk_val(), sub_obj), []]) 75 _get_deleted_objects(deleted_objects, perms_needed, user, sub_obj, related.opts, current_depth+2) 76 else: 77 has_related_objs = False 78 for sub_obj in getattr(obj, rel_opts_name).all(): 79 has_related_objs = True 80 if related.field.rel.edit_inline or not related.opts.admin: 81 # Don't display link to edit, because it either has no 82 # admin or is edited inline. 83 nh(deleted_objects, current_depth, ['%s: %s' % (capfirst(related.opts.verbose_name), escape(str(sub_obj))), []]) 84 else: 85 # Display a link to the admin page. 86 nh(deleted_objects, current_depth, ['%s: <a href="../../../../%s/%s/%s/">%s</a>' % \ 87 (capfirst(related.opts.verbose_name), related.opts.app_label, related.opts.object_name.lower(), sub_obj._get_pk_val(), escape(str(sub_obj))), []]) 88 _get_deleted_objects(deleted_objects, perms_needed, user, sub_obj, related.opts, current_depth+2) 89 # If there were related objects, and the user doesn't have 90 # permission to delete them, add the missing perm to perms_needed. 91 if related.opts.admin and has_related_objs: 92 p = '%s.%s' % (related.opts.app_label, related.opts.get_delete_permission()) 93 if not user.has_perm(p): 94 perms_needed.add(related.opts.verbose_name) 95 for related in opts.get_all_related_many_to_many_objects(): 96 if related.opts in opts_seen: 97 continue 98 opts_seen.append(related.opts) 99 rel_opts_name = related.get_accessor_name() 100 has_related_objs = False 101 102 # related.get_accessor_name() could return None for symmetrical relationships 103 if rel_opts_name: 104 rel_objs = getattr(obj, rel_opts_name, None) 105 if rel_objs: 106 has_related_objs = True 107 108 if has_related_objs: 109 for sub_obj in rel_objs.all(): 110 if related.field.rel.edit_inline or not related.opts.admin: 111 # Don't display link to edit, because it either has no 112 # admin or is edited inline. 113 nh(deleted_objects, current_depth, [_('One or more %(fieldname)s in %(name)s: %(obj)s') % \ 114 {'fieldname': related.field.verbose_name, 'name': related.opts.verbose_name, 'obj': escape(str(sub_obj))}, []]) 115 else: 116 # Display a link to the admin page. 117 nh(deleted_objects, current_depth, [ 118 (_('One or more %(fieldname)s in %(name)s:') % {'fieldname': related.field.verbose_name, 'name':related.opts.verbose_name}) + \ 119 (' <a href="../../../../%s/%s/%s/">%s</a>' % \ 120 (related.opts.app_label, related.opts.module_name, sub_obj._get_pk_val(), escape(str(sub_obj)))), []]) 121 # If there were related objects, and the user doesn't have 122 # permission to change them, add the missing perm to perms_needed. 123 if related.opts.admin and has_related_objs: 124 p = '%s.%s' % (related.opts.app_label, related.opts.get_change_permission()) 125 if not user.has_perm(p): 126 perms_needed.add(related.opts.verbose_name) 127 37 128 class AdminForm(object): 38 129 def __init__(self, form, fieldsets, prepopulated_fields): 39 130 self.form, self.fieldsets = form, fieldsets -
views/main.py
4 4 from django.contrib.admin.views.decorators import staff_member_required 5 5 from django.views.decorators.cache import never_cache 6 6 from django.contrib.contenttypes.models import ContentType 7 from django.core.exceptions import ObjectDoesNotExist8 7 from django.core.paginator import ObjectPaginator, InvalidPage 9 8 from django.shortcuts import get_object_or_404, render_to_response 10 9 from django.db import models 11 10 from django.db.models.query import handle_legacy_orderlist, QuerySet 12 11 from django.http import Http404 13 from django.utils.html import escape14 from django.utils.text import capfirst15 12 import operator 16 13 17 14 # The system will display a "Show all" link on the change list only if the … … 136 133 return render_to_response('admin/index.html', {'title': _('Site administration')}, context_instance=template.RequestContext(request)) 137 134 index = staff_member_required(never_cache(index)) 138 135 139 def _nest_help(obj, depth, val):140 current = obj141 for i in range(depth):142 current = current[-1]143 current.append(val)144 136 145 def _get_deleted_objects(deleted_objects, perms_needed, user, obj, opts, current_depth):146 "Helper function that recursively populates deleted_objects."147 nh = _nest_help # Bind to local variable for performance148 if current_depth > 16:149 return # Avoid recursing too deep.150 opts_seen = []151 for related in opts.get_all_related_objects():152 if related.opts in opts_seen:153 continue154 opts_seen.append(related.opts)155 rel_opts_name = related.get_accessor_name()156 if isinstance(related.field.rel, models.OneToOneRel):157 try:158 sub_obj = getattr(obj, rel_opts_name)159 except ObjectDoesNotExist:160 pass161 else:162 if related.opts.admin:163 p = '%s.%s' % (related.opts.app_label, related.opts.get_delete_permission())164 if not user.has_perm(p):165 perms_needed.add(related.opts.verbose_name)166 # We don't care about populating deleted_objects now.167 continue168 if related.field.rel.edit_inline or not related.opts.admin:169 # Don't display link to edit, because it either has no170 # admin or is edited inline.171 nh(deleted_objects, current_depth, ['%s: %s' % (capfirst(related.opts.verbose_name), sub_obj), []])172 else:173 # Display a link to the admin page.174 nh(deleted_objects, current_depth, ['%s: <a href="../../../../%s/%s/%s/">%s</a>' % \175 (capfirst(related.opts.verbose_name), related.opts.app_label, related.opts.object_name.lower(),176 sub_obj._get_pk_val(), sub_obj), []])177 _get_deleted_objects(deleted_objects, perms_needed, user, sub_obj, related.opts, current_depth+2)178 else:179 has_related_objs = False180 for sub_obj in getattr(obj, rel_opts_name).all():181 has_related_objs = True182 if related.field.rel.edit_inline or not related.opts.admin:183 # Don't display link to edit, because it either has no184 # admin or is edited inline.185 nh(deleted_objects, current_depth, ['%s: %s' % (capfirst(related.opts.verbose_name), escape(str(sub_obj))), []])186 else:187 # Display a link to the admin page.188 nh(deleted_objects, current_depth, ['%s: <a href="../../../../%s/%s/%s/">%s</a>' % \189 (capfirst(related.opts.verbose_name), related.opts.app_label, related.opts.object_name.lower(), sub_obj._get_pk_val(), escape(str(sub_obj))), []])190 _get_deleted_objects(deleted_objects, perms_needed, user, sub_obj, related.opts, current_depth+2)191 # If there were related objects, and the user doesn't have192 # permission to delete them, add the missing perm to perms_needed.193 if related.opts.admin and has_related_objs:194 p = '%s.%s' % (related.opts.app_label, related.opts.get_delete_permission())195 if not user.has_perm(p):196 perms_needed.add(related.opts.verbose_name)197 for related in opts.get_all_related_many_to_many_objects():198 if related.opts in opts_seen:199 continue200 opts_seen.append(related.opts)201 rel_opts_name = related.get_accessor_name()202 has_related_objs = False203 204 # related.get_accessor_name() could return None for symmetrical relationships205 if rel_opts_name:206 rel_objs = getattr(obj, rel_opts_name, None)207 if rel_objs:208 has_related_objs = True209 210 if has_related_objs:211 for sub_obj in rel_objs.all():212 if related.field.rel.edit_inline or not related.opts.admin:213 # Don't display link to edit, because it either has no214 # admin or is edited inline.215 nh(deleted_objects, current_depth, [_('One or more %(fieldname)s in %(name)s: %(obj)s') % \216 {'fieldname': related.field.verbose_name, 'name': related.opts.verbose_name, 'obj': escape(str(sub_obj))}, []])217 else:218 # Display a link to the admin page.219 nh(deleted_objects, current_depth, [220 (_('One or more %(fieldname)s in %(name)s:') % {'fieldname': related.field.verbose_name, 'name':related.opts.verbose_name}) + \221 (' <a href="../../../../%s/%s/%s/">%s</a>' % \222 (related.opts.app_label, related.opts.module_name, sub_obj._get_pk_val(), escape(str(sub_obj)))), []])223 # If there were related objects, and the user doesn't have224 # permission to change them, add the missing perm to perms_needed.225 if related.opts.admin and has_related_objs:226 p = '%s.%s' % (related.opts.app_label, related.opts.get_change_permission())227 if not user.has_perm(p):228 perms_needed.add(related.opts.verbose_name)229 230 137 class ChangeList(object): 231 138 def __init__(self, request, model, list_display, list_display_links, list_filter, date_hierarchy, search_fields, list_select_related, list_per_page, model_admin): 232 139 self.model = model