Ticket #6470: admin-urlpatterns.5.diff
File admin-urlpatterns.5.diff, 17.3 KB (added by , 16 years ago) |
---|
-
django/conf/project_template/urls.py
diff --git a/django/conf/project_template/urls.py b/django/conf/project_template/urls.py index af1d1db..dfb49d3 100644
a b urlpatterns = patterns('', 13 13 # (r'^admin/doc/', include('django.contrib.admindocs.urls')), 14 14 15 15 # Uncomment the next line to enable the admin: 16 # (r'^admin/ (.*)', admin.site.root),16 # (r'^admin/', include(admin.site.urls)), 17 17 ) -
django/contrib/admin/options.py
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index 3d60b9d..708af25 100644
a b from django.forms.models import BaseInlineFormSet 5 5 from django.contrib.contenttypes.models import ContentType 6 6 from django.contrib.admin import widgets 7 7 from django.contrib.admin import helpers 8 from django.contrib.admin.util import quote, unquote, flatten_fieldsets, get_deleted_objects 8 from django.contrib.admin.util import quote, unquote, flatten_fieldsets, get_deleted_objects, admin_perm_test 9 9 from django.core.exceptions import PermissionDenied 10 10 from django.db import models, transaction 11 11 from django.http import Http404, HttpResponse, HttpResponseRedirect … … class ModelAdmin(BaseModelAdmin): 196 196 else: 197 197 return self.change_view(request, unquote(url)) 198 198 199 def get_urls(self): 200 from django.conf.urls.defaults import patterns, url 201 info = self.admin_site.name, self.model._meta.app_label, self.model._meta.module_name 202 urlpatterns = patterns('', 203 url(r'^$', lambda *args, **kwargs: self.changelist_view(*args, **kwargs), name='%sadmin_%s_%s_changelist' % info), 204 url(r'^add/$', lambda *args, **kwargs: self.add_view(*args, **kwargs), name='%sadmin_%s_%s_add' % info), 205 url(r'^(.+)/history/$', lambda *args, **kwargs: self.history_view(*args, **kwargs), name='%sadmin_%s_%s_history' % info), 206 url(r'^(.+)/delete/$', lambda *args, **kwargs: self.delete_view(*args, **kwargs), name='%sadmin_%s_%s_delete' % info), 207 url(r'^(.+)/$', lambda *args, **kwargs: self.change_view(*args, **kwargs), name='%sadmin_%s_%s_change' % info), 208 ) 209 return urlpatterns 210 211 def urls(self): 212 return self.get_urls() 213 urls = property(urls) 214 215 199 216 def _media(self): 200 217 from django.conf import settings 201 218 … … class ModelAdmin(BaseModelAdmin): 537 554 } 538 555 context.update(extra_context or {}) 539 556 return self.render_change_form(request, context, add=True) 540 add_view = transaction.commit_on_success(ad d_view)557 add_view = transaction.commit_on_success(admin_perm_test(add_view)) 541 558 542 559 def change_view(self, request, object_id, extra_context=None): 543 560 "The 'change' admin view for this model." … … class ModelAdmin(BaseModelAdmin): 545 562 opts = model._meta 546 563 547 564 try: 548 obj = model._default_manager.get(pk= object_id)565 obj = model._default_manager.get(pk=unquote(object_id)) 549 566 except model.DoesNotExist: 550 567 # Don't raise Http404 just yet, because we haven't checked 551 568 # permissions yet. We don't want an unauthenticated user to be able … … class ModelAdmin(BaseModelAdmin): 616 633 } 617 634 context.update(extra_context or {}) 618 635 return self.render_change_form(request, context, change=True, obj=obj) 619 change_view = transaction.commit_on_success( change_view)636 change_view = transaction.commit_on_success(admin_perm_test(change_view)) 620 637 621 638 def changelist_view(self, request, extra_context=None): 622 639 "The 'change list' admin view for this model." … … class ModelAdmin(BaseModelAdmin): 652 669 'admin/%s/change_list.html' % app_label, 653 670 'admin/change_list.html' 654 671 ], context, context_instance=template.RequestContext(request)) 672 changelist_view = admin_perm_test(changelist_view) 655 673 656 674 def delete_view(self, request, object_id, extra_context=None): 657 675 "The 'delete' admin view for this model." … … class ModelAdmin(BaseModelAdmin): 659 677 app_label = opts.app_label 660 678 661 679 try: 662 obj = self.model._default_manager.get(pk= object_id)680 obj = self.model._default_manager.get(pk=unquote(object_id)) 663 681 except self.model.DoesNotExist: 664 682 # Don't raise Http404 just yet, because we haven't checked 665 683 # permissions yet. We don't want an unauthenticated user to be able … … class ModelAdmin(BaseModelAdmin): 674 692 675 693 # Populate deleted_objects, a data structure of all related objects that 676 694 # will also be deleted. 677 deleted_objects = [mark_safe(u'%s: <a href="../../%s/">%s</a>' % (escape(force_unicode(capfirst(opts.verbose_name))), quote(object_id), escape(obj))), []]695 deleted_objects = [mark_safe(u'%s: <a href="../../%s/">%s</a>' % (escape(force_unicode(capfirst(opts.verbose_name))), object_id, escape(obj))), []] 678 696 perms_needed = set() 679 697 get_deleted_objects(deleted_objects, perms_needed, request.user, obj, opts, 1, self.admin_site) 680 698 … … class ModelAdmin(BaseModelAdmin): 707 725 "admin/%s/delete_confirmation.html" % app_label, 708 726 "admin/delete_confirmation.html" 709 727 ], context, context_instance=template.RequestContext(request)) 728 delete_view = admin_perm_test(delete_view) 710 729 711 730 def history_view(self, request, object_id, extra_context=None): 712 731 "The 'history' admin view for this model." … … class ModelAdmin(BaseModelAdmin): 734 753 "admin/%s/object_history.html" % app_label, 735 754 "admin/object_history.html" 736 755 ], context, context_instance=template.RequestContext(request)) 756 history_view = admin_perm_test(history_view) 737 757 738 758 class InlineModelAdmin(BaseModelAdmin): 739 759 """ -
django/contrib/admin/sites.py
diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py index c16ab6a..1b24211 100644
a b 1 1 import base64 2 2 import re 3 3 4 from django import http, template 4 5 from django.contrib.admin import ModelAdmin 6 from django.contrib.admin.util import admin_perm_test 5 7 from django.contrib.auth import authenticate, login 6 8 from django.db.models.base import ModelBase 7 9 from django.core.exceptions import ImproperlyConfigured … … class AdminSite(object): 34 36 login_template = None 35 37 app_index_template = None 36 38 37 def __init__(self ):39 def __init__(self, name=None): 38 40 self._registry = {} # model_class class -> admin_class instance 41 # TODO Root path is used to calculate urls under the old root() method 42 # in order to maintain backwards compatibility we are leaving that in 43 # so root_path isn't needed, not sure what to do about this. 44 self.root_path = 'admin/' 45 if name is None: 46 name = '' 47 else: 48 name += '_' 49 self.name = name 39 50 40 51 def register(self, model_or_iterable, admin_class=None, **options): 41 52 """ … … class AdminSite(object): 121 132 122 133 `url` is the remainder of the URL -- e.g. 'comments/comment/'. 123 134 """ 135 import warnings 136 warnings.warn("Using AdminSite.root() is deprecated, you should \ 137 include(AdminSite.urls) instead", PendingDeprecationWarning) 124 138 if request.method == 'GET' and not request.path.endswith('/'): 125 139 return http.HttpResponseRedirect(request.path + '/') 126 140 … … class AdminSite(object): 159 173 return self.app_index(request, url) 160 174 161 175 raise http.Http404('The requested admin page does not exist.') 162 176 177 def get_urls(self): 178 from django.conf.urls.defaults import patterns, url, include 179 urlpatterns = patterns('', 180 url(r'^$', lambda *args, **kwargs: self.index(*args, **kwargs), name='%sadmin_index' % self.name), 181 url(r'^logout/$', lambda *args, **kwargs: self.logout(*args, **kwargs), name='%sadmin_logout'), 182 url(r'^password_change/$', lambda *args, **kwargs: self.password_change(*args, **kwargs), name='%sadmin_password_change' % self.name), 183 url(r'^password_change/done/$', lambda *args, **kwargs: self.password_change_done(*args, **kwargs), name='%sadmin_password_change_done' % self.name), 184 url(r'^jsi18n/$', lambda *args, **kwargs: self.i18n_javascript(*args, **kwargs), name='%sadmin_jsi18n' % self.name), 185 url(r'^r/(?P<content_type_id>\d+)/(?P<object_id>.+)/$', 'django.views.defaults.shortcut'), 186 url(r'^(?P<app_label>\w+)/$', lambda *args, **kwargs: self.app_index(*args, **kwargs), name='%sadmin_app_list' % self.name), 187 ) 188 for model, model_admin in self._registry.iteritems(): 189 urlpatterns += patterns('', 190 url(r'^%s/%s/' % (model._meta.app_label, model._meta.module_name), include(model_admin.urls)) 191 ) 192 return urlpatterns 193 194 def urls(self): 195 return self.get_urls() 196 urls = property(urls) 197 163 198 def model_page(self, request, app_label, model_name, rest_of_url=None): 164 199 """ 165 200 Handles the model-specific functionality of the admin site, delegating … … class AdminSite(object): 183 218 from django.contrib.auth.views import password_change 184 219 return password_change(request, 185 220 post_change_redirect='%spassword_change/done/' % self.root_path) 221 passoword_change = admin_perm_test(password_change) 186 222 187 223 def password_change_done(self, request): 188 224 """ … … class AdminSite(object): 190 226 """ 191 227 from django.contrib.auth.views import password_change_done 192 228 return password_change_done(request) 229 password_change_done = admin_perm_test(password_change_done) 193 230 194 231 def i18n_javascript(self, request): 195 232 """ … … class AdminSite(object): 203 240 else: 204 241 from django.views.i18n import null_javascript_catalog as javascript_catalog 205 242 return javascript_catalog(request, packages='django.conf') 243 i18n_javascript = admin_perm_test(i18n_javascript) 206 244 207 245 def logout(self, request): 208 246 """ … … class AdminSite(object): 317 355 return render_to_response(self.index_template or 'admin/index.html', context, 318 356 context_instance=template.RequestContext(request) 319 357 ) 320 index = never_cache( index)358 index = never_cache(admin_perm_test(index)) 321 359 322 360 def display_login_form(self, request, error_message='', extra_context=None): 323 361 request.session.set_test_cookie() … … class AdminSite(object): 377 415 return render_to_response(self.app_index_template or 'admin/app_index.html', context, 378 416 context_instance=template.RequestContext(request) 379 417 ) 418 app_index = admin_perm_test(app_index) 380 419 381 420 # This global object represents the default admin site, for the common case. 382 421 # 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 0900b4e..6b34c78 100644
a b from django.utils.text import capfirst 6 6 from django.utils.encoding import force_unicode 7 7 from django.utils.translation import ugettext as _ 8 8 9 def admin_perm_test(func): 10 def inner(admin_site_or_modeladmin, request, *args, **kwargs): 11 if hasattr(admin_site_or_modeladmin, 'has_permission'): 12 admin_site = admin_site_or_modeladmin 13 else: 14 admin_site = admin_site_or_modeladmin.admin_site 15 if not admin_site.has_permission(request): 16 return admin_site.login(request) 17 # User has right permisssions show the view 18 return func(admin_site_or_modeladmin, request, *args, **kwargs) 19 return inner 9 20 10 21 def quote(s): 11 22 """ -
django/contrib/auth/admin.py
diff --git a/django/contrib/auth/admin.py b/django/contrib/auth/admin.py index 805ca32..ee2db12 100644
a b class UserAdmin(admin.ModelAdmin): 40 40 if url.endswith('password'): 41 41 return self.user_change_password(request, url.split('/')[0]) 42 42 return super(UserAdmin, self).__call__(request, url) 43 44 def get_urls(self): 45 from django.conf.urls.defaults import patterns 46 urlpatterns = super(UserAdmin, self).get_urls() 47 urlpatterns = patterns('', 48 (r'^(\d+)/password/$', self.user_change_password) 49 ) + urlpatterns 50 return urlpatterns 43 51 44 52 def add_view(self, request): 45 53 # It's an error for a user to have add permission but NOT change -
docs/intro/tutorial02.txt
diff --git a/docs/intro/tutorial02.txt b/docs/intro/tutorial02.txt index 1144167..fb6794b 100644
a b activate the admin site for your installation, do these three things: 57 57 # (r'^admin/doc/', include('django.contrib.admindocs.urls')), 58 58 59 59 # Uncomment the next line to enable the admin: 60 **(r'^admin/ (.*)', admin.site.root),**60 **(r'^admin/', include(admin.site.urls)),** 61 61 ) 62 62 63 63 (The bold lines are the ones that needed to be uncommented.) -
docs/ref/contrib/admin.txt
diff --git a/docs/ref/contrib/admin.txt b/docs/ref/contrib/admin.txt index f24dc46..13850ce 100644
a b model instance:: 632 632 instance.save() 633 633 formset.save_m2m() 634 634 635 ``get_urls(self)`` 636 ~~~~~~~~~~~~~~~~~~~ 637 638 The ``get_urls`` method on a ``ModelAdmin`` returns the URLs to be used for 639 that ModelAdmin in the same way as a URLconf. Therefore you can extend them as 640 documented in :ref:`topics-http-urls`:: 641 642 class MyModelAdmin(admin.ModelAdmin): 643 def get_urls(self): 644 urlpatterns = super(MyModelAdmin, self).get_urls() 645 urlpatterns += patterns('', 646 (r'^my_view/$', self.my_view) 647 ) 648 return urlpatterns 649 650 635 651 ``ModelAdmin`` media definitions 636 652 -------------------------------- 637 653 … … In this example, we register the default ``AdminSite`` instance 1027 1043 admin.autodiscover() 1028 1044 1029 1045 urlpatterns = patterns('', 1030 ('^admin/ (.*)', admin.site.root),1046 ('^admin/', include(admin.site.urls)), 1031 1047 ) 1032 1048 1033 1049 Above we used ``admin.autodiscover()`` to automatically load the … … In this example, we register the ``AdminSite`` instance 1041 1057 from myproject.admin import admin_site 1042 1058 1043 1059 urlpatterns = patterns('', 1044 ('^myadmin/ (.*)', admin_site.root),1060 ('^myadmin/', include(admin_site.urls)), 1045 1061 ) 1046 1062 1047 1063 There is really no need to use autodiscover when using your own ``AdminSite`` 1048 1064 instance since you will likely be importing all the per-app admin.py modules 1049 1065 in your ``myproject.admin`` module. 1050 1066 1051 Note that the regular expression in the URLpattern *must* group everything in1052 the URL that comes after the URL root -- hence the ``(.*)`` in these examples.1053 1067 1054 1068 Multiple admin sites in the same URLconf 1055 1069 ---------------------------------------- … … respectively:: 1068 1082 from myproject.admin import basic_site, advanced_site 1069 1083 1070 1084 urlpatterns = patterns('', 1071 ('^basic-admin/ (.*)', basic_site.root),1072 ('^advanced-admin/ (.*)', advanced_site.root),1085 ('^basic-admin/', include(basic_site.urls)), 1086 ('^advanced-admin/', include(advanced_site.urls)), 1073 1087 ) 1088 1089 Adding views to admin sites 1090 --------------------------- 1091 1092 It possible to add additional views to the admin site in the same way one can 1093 add them to ``ModelAdmins``. This by using the ``get_urls()`` method on an 1094 AdminSite in the same way as documented on ``ModelAdmins``. 1095 1096 Protecting Custom ``AdminSite`` and ``ModelAdmin`` 1097 -------------------------------------------------- 1098 1099 By default all the views in the Django admin are protected so that only staff 1100 members can access them. If you add your own views to either a ``ModelAdmin`` 1101 or ``AdminSite`` you should ensure that where necessary they are protected in 1102 the same manner. To do this use the ``admin_perm_test`` decorator provided in 1103 ``django.contrib.admin.utils.admin_perm_test``. It can be used in the same way 1104 as the ``login_requied`` decorator. 1105 1106 .. note:: 1107 The ``admin_perm_test`` decorator can only be used on methods which are on 1108 ``ModelAdmins`` or ``AdminSites``, you cannot use it on arbitrary functions. -
tests/regressiontests/admin_views/tests.py
diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py index 391d1ff..8fb8ad8 100644
a b class AdminViewBasicTest(TestCase): 26 26 """ 27 27 request = self.client.get('/test_admin/admin/admin_views/article/add') 28 28 self.assertRedirects(request, 29 '/test_admin/admin/admin_views/article/add/' 29 '/test_admin/admin/admin_views/article/add/', status_code=301 30 30 ) 31 31 32 32 def testBasicAddGet(self): -
tests/regressiontests/admin_views/urls.py
diff --git a/tests/regressiontests/admin_views/urls.py b/tests/regressiontests/admin_views/urls.py index 4e5da48..02e0286 100644
a b import views 5 5 urlpatterns = patterns('', 6 6 (r'^admin/doc/', include('django.contrib.admindocs.urls')), 7 7 (r'^admin/secure-view/$', views.secure_view), 8 (r'^admin/ (.*)', admin.site.root),8 (r'^admin/', include(admin.site.urls)), 9 9 )