Ticket #13588: newstyle_admin.diff
File newstyle_admin.diff, 14.2 KB (added by , 14 years ago) |
---|
-
django/contrib/admin/actions.py
diff --git a/django/contrib/admin/actions.py b/django/contrib/admin/actions.py index b75c91b..e98d4eb 100644
a b def delete_selected(modeladmin, request, queryset): 32 32 33 33 # Populate deletable_objects, a data structure of all related objects that 34 34 # will also be deleted. 35 deletable_objects, perms_needed = get_deleted_objects(queryset, opts, request.user, modeladmin.admin_site , levels_to_root=2)35 deletable_objects, perms_needed = get_deleted_objects(queryset, opts, request.user, modeladmin.admin_site) 36 36 37 37 # The user has already confirmed the deletion. 38 38 # Do the deletion and return a None to display the change list view again. -
django/contrib/admin/options.py
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index 1f8ff6d..97210e5 100644
a b from django.contrib.admin.util import unquote, flatten_fieldsets, get_deleted_ob 9 9 from django.contrib import messages 10 10 from django.views.decorators.csrf import csrf_protect 11 11 from django.core.exceptions import PermissionDenied, ValidationError 12 from django.core.urlresolvers import reverse 12 13 from django.db import models, transaction 13 14 from django.db.models.fields import BLANK_CHOICE_DASH 14 15 from django.http import Http404, HttpResponse, HttpResponseRedirect … … class ModelAdmin(BaseModelAdmin): 663 664 # redirect to the change-list page for this object. Otherwise, 664 665 # redirect to the admin index. 665 666 if self.has_change_permission(request, None): 666 post_url = '../' 667 post_url = reverse('admin:%s_%s_changelist' % 668 (opts.app_label, opts.module_name)) 667 669 else: 668 post_url = '../../../'670 post_url = reverse('admin:index') 669 671 return HttpResponseRedirect(post_url) 670 672 671 673 def response_change(self, request, obj): … … class ModelAdmin(BaseModelAdmin): 685 687 elif request.POST.has_key("_saveasnew"): 686 688 msg = _('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % {'name': force_unicode(opts.verbose_name), 'obj': obj} 687 689 self.message_user(request, msg) 688 return HttpResponseRedirect("../%s/" % pk_value) 690 return HttpResponseRedirect(reverse('admin:%s_%s_change' % 691 (opts.app_label, opts.module_name), 692 args=pk_value)) 693 689 694 elif request.POST.has_key("_addanother"): 690 695 self.message_user(request, msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name))) 691 return HttpResponseRedirect("../add/") 696 return HttpResponseRedirect(reverse('admin:%s_%s_add' % 697 (opts.app_label, opts.module_name))) 692 698 else: 693 699 self.message_user(request, msg) 694 return HttpResponseRedirect("../") 700 return HttpResponseRedirect(reverse('admin:%s_%s_changelist' % 701 (opts.app_label, opts.module_name))) 695 702 696 703 def response_action(self, request, queryset): 697 704 """ … … class ModelAdmin(BaseModelAdmin): 866 873 raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % {'name': force_unicode(opts.verbose_name), 'key': escape(object_id)}) 867 874 868 875 if request.method == 'POST' and request.POST.has_key("_saveasnew"): 869 return self.add_view(request, form_url='../add/') 876 return self.add_view(request, form_url=reverse('admin:%s_%s_add' % 877 (opts.app_label, opts.module_name))) 870 878 871 879 ModelForm = self.get_form(request, obj) 872 880 formsets = [] … … class ModelAdmin(BaseModelAdmin): 1118 1126 self.message_user(request, _('The %(name)s "%(obj)s" was deleted successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(obj_display)}) 1119 1127 1120 1128 if not self.has_change_permission(request, None): 1121 return HttpResponseRedirect("../../../../") 1122 return HttpResponseRedirect("../../") 1129 return HttpResponseRedirect(reverse('admin:index')) 1130 return HttpResponseRedirect(reverse('admin:%s_%s_changelist' % 1131 (opts.app_label, opts.module_name))) 1123 1132 1124 1133 context = { 1125 1134 "title": _("Are you sure?"), -
django/contrib/admin/sites.py
diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py index 4446490..e451f8f 100644
a b class AdminSite(object): 456 456 context_instance=context_instance 457 457 ) 458 458 459 def root(self, request, url):460 """461 DEPRECATED. This function is the old way of handling URL resolution, and462 is deprecated in favor of real URL resolution -- see ``get_urls()``.463 464 This function still exists for backwards-compatibility; it will be465 removed in Django 1.3.466 """467 import warnings468 warnings.warn(469 "AdminSite.root() is deprecated; use include(admin.site.urls) instead.",470 DeprecationWarning471 )472 473 #474 # Again, remember that the following only exists for475 # backwards-compatibility. Any new URLs, changes to existing URLs, or476 # whatever need to be done up in get_urls(), above!477 #478 479 if request.method == 'GET' and not request.path.endswith('/'):480 return http.HttpResponseRedirect(request.path + '/')481 482 if settings.DEBUG:483 self.check_dependencies()484 485 # Figure out the admin base URL path and stash it for later use486 self.root_path = re.sub(re.escape(url) + '$', '', request.path)487 488 url = url.rstrip('/') # Trim trailing slash, if it exists.489 490 # The 'logout' view doesn't require that the person is logged in.491 if url == 'logout':492 return self.logout(request)493 494 # Check permission to continue or display login form.495 if not self.has_permission(request):496 return self.login(request)497 498 if url == '':499 return self.index(request)500 elif url == 'password_change':501 return self.password_change(request)502 elif url == 'password_change/done':503 return self.password_change_done(request)504 elif url == 'jsi18n':505 return self.i18n_javascript(request)506 # URLs starting with 'r/' are for the "View on site" links.507 elif url.startswith('r/'):508 from django.contrib.contenttypes.views import shortcut509 return shortcut(request, *url.split('/')[1:])510 else:511 if '/' in url:512 return self.model_page(request, *url.split('/', 2))513 else:514 return self.app_index(request, url)515 516 raise http.Http404('The requested admin page does not exist.')517 518 def model_page(self, request, app_label, model_name, rest_of_url=None):519 """520 DEPRECATED. This is the old way of handling a model view on the admin521 site; the new views should use get_urls(), above.522 """523 from django.db import models524 model = models.get_model(app_label, model_name)525 if model is None:526 raise http.Http404("App %r, model %r, not found." % (app_label, model_name))527 try:528 admin_obj = self._registry[model]529 except KeyError:530 raise http.Http404("This model exists but has not been registered with the admin site.")531 return admin_obj(request, rest_of_url)532 model_page = never_cache(model_page)533 459 534 460 # This global object represents the default admin site, for the common case. 535 461 # You can instantiate AdminSite in your own code to create a custom admin site. -
django/contrib/admin/util.py
diff --git a/django/contrib/admin/util.py b/django/contrib/admin/util.py index 776a6f0..74c4a18 100644
a b from django.utils.safestring import mark_safe 7 7 from django.utils.text import capfirst 8 8 from django.utils.encoding import force_unicode, smart_unicode, smart_str 9 9 from django.utils.translation import ungettext, ugettext as _ 10 from django.core.urlresolvers import reverse , NoReverseMatch10 from django.core.urlresolvers import reverse 11 11 from django.utils.datastructures import SortedDict 12 12 13 13 def quote(s): … … def flatten_fieldsets(fieldsets): 58 58 field_names.append(field) 59 59 return field_names 60 60 61 def _format_callback(obj, user, admin_site, levels_to_root,perms_needed):61 def _format_callback(obj, user, admin_site, perms_needed): 62 62 has_admin = obj.__class__ in admin_site._registry 63 63 opts = obj._meta 64 try:64 if has_admin: 65 65 admin_url = reverse('%s:%s_%s_change' 66 66 % (admin_site.name, 67 67 opts.app_label, 68 68 opts.object_name.lower()), 69 69 None, (quote(obj._get_pk_val()),)) 70 except NoReverseMatch:71 admin_url = '%s%s/%s/%s/' % ('../'*levels_to_root,72 opts.app_label,73 opts.object_name.lower(),74 quote(obj._get_pk_val()))75 if has_admin:76 70 p = '%s.%s' % (opts.app_label, 77 71 opts.get_delete_permission()) 78 72 if not user.has_perm(p): … … def _format_callback(obj, user, admin_site, levels_to_root, perms_needed): 88 82 return u'%s: %s' % (capfirst(opts.verbose_name), 89 83 force_unicode(obj)) 90 84 91 def get_deleted_objects(objs, opts, user, admin_site, levels_to_root= 4):85 def get_deleted_objects(objs, opts, user, admin_site, levels_to_root=0): 92 86 """ 93 87 Find all objects related to ``objs`` that should also be 94 88 deleted. ``objs`` should be an iterable of objects. … … def get_deleted_objects(objs, opts, user, admin_site, levels_to_root=4): 96 90 Returns a nested list of strings suitable for display in the 97 91 template with the ``unordered_list`` filter. 98 92 99 `levels_to_root` defines the number of directories (../) to reach 100 the admin root path. In a change_view this is 4, in a change_list 101 view 2. 102 103 This is for backwards compatibility since the options.delete_selected 104 method uses this function also from a change_list view. 105 This will not be used if we can reverse the URL. 93 `levels_to_root` is for backwards compatibility api compability, it is not 94 used at all. 106 95 """ 107 96 collector = NestedObjects() 108 97 for obj in objs: … … def get_deleted_objects(objs, opts, user, admin_site, levels_to_root=4): 114 103 to_delete = collector.nested(_format_callback, 115 104 user=user, 116 105 admin_site=admin_site, 117 levels_to_root=levels_to_root,118 106 perms_needed=perms_needed) 119 107 120 108 return to_delete, perms_needed -
django/contrib/admin/widgets.py
diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py index 1d321d0..66a84f2 100644
a b from django.utils.translation import ugettext as _ 13 13 from django.utils.safestring import mark_safe 14 14 from django.utils.encoding import force_unicode 15 15 from django.conf import settings 16 from django.core.urlresolvers import reverse , NoReverseMatch16 from django.core.urlresolvers import reverse 17 17 18 18 class FilteredSelectMultiple(forms.SelectMultiple): 19 19 """ … … class ForeignKeyRawIdWidget(forms.TextInput): 113 113 def render(self, name, value, attrs=None): 114 114 if attrs is None: 115 115 attrs = {} 116 # TODO, only add link if related object is in the admin... 116 117 related_url = '../../../%s/%s/' % (self.rel.to._meta.app_label, self.rel.to._meta.object_name.lower()) 117 118 params = self.url_parameters() 118 119 if params: … … class RelatedFieldWidgetWrapper(forms.Widget): 229 230 def render(self, name, value, *args, **kwargs): 230 231 rel_to = self.rel.to 231 232 info = (rel_to._meta.app_label, rel_to._meta.object_name.lower()) 232 try:233 related_url = reverse('admin:%s_%s_add' % info, current_app=self.admin_site.name)234 except NoReverseMatch:235 info = (self.admin_site.root_path, rel_to._meta.app_label, rel_to._meta.object_name.lower())236 related_url = '%s%s/%s/add/' % info237 233 self.widget.choices = self.choices 238 234 output = [self.widget.render(name, value, *args, **kwargs)] 239 235 if rel_to in self.admin_site._registry: # If the related object has an admin interface: 236 related_url = reverse('admin:%s_%s_add' % info, current_app=self.admin_site.name) 240 237 # TODO: "id_" is hard-coded here. This should instead use the correct 241 238 # API to determine the ID dynamically. 242 239 output.append(u'<a href="%s" class="add-another" id="add_id_%s" onclick="return showAddAnotherPopup(this);"> ' % \ -
tests/regressiontests/admin_inlines/models.py
diff --git a/tests/regressiontests/admin_inlines/models.py b/tests/regressiontests/admin_inlines/models.py index 5a12e07..2998373 100644
a b class BookInline(admin.TabularInline): 43 43 class AuthorAdmin(admin.ModelAdmin): 44 44 inlines = [BookInline] 45 45 46 admin.site.register(Book) 46 47 admin.site.register(Author, AuthorAdmin) 47 48 48 49 class Holder(models.Model): -
tests/regressiontests/admin_views/tests.py
diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py index 1385e5e..f60bb04 100644
a b class SaveAsTests(TestCase): 324 324 self.assert_(response.context['save_as']) 325 325 post_data = {'_saveasnew':'', 'name':'John M', 'gender':3, 'alive':'checked'} 326 326 response = self.client.post('/test_admin/admin/admin_views/person/1/', post_data) 327 self.assertEqual(response.context['form_url'], ' ../add/')327 self.assertEqual(response.context['form_url'], '/test_admin/admin/admin_views/person/add/') 328 328 329 329 class CustomModelAdminTest(AdminViewBasicTest): 330 330 urlbit = "admin2"