Ticket #6470: admin-urlpatterns-6470.diff
File admin-urlpatterns-6470.diff, 19.5 KB (added by , 16 years ago) |
---|
-
django/core/urlresolvers.py
211 211 # urlconf_name is a string representing the module containing urlconfs. 212 212 self.regex = re.compile(regex, re.UNICODE) 213 213 self.urlconf_name = urlconf_name 214 if not isinstance(self.urlconf_name, basestring): 215 self._urlconf_module = self.urlconf_name 214 216 self.callback = None 215 217 self.default_kwargs = default_kwargs or {} 216 218 self._reverse_dict = {} -
django/contrib/admin/options.py
4 4 from django.forms.models import BaseInlineFormset 5 5 from django.contrib.contenttypes.models import ContentType 6 6 from django.contrib.admin import widgets 7 from django.contrib.admin.util import quote, unquote, get_deleted_objects 7 from django.contrib.admin.util import quote, unquote, get_deleted_objects, admin_perm_test 8 8 from django.core.exceptions import ImproperlyConfigured, PermissionDenied 9 9 from django.db import models, transaction 10 10 from django.http import Http404, HttpResponse, HttpResponseRedirect … … 15 15 from django.utils.translation import ugettext as _ 16 16 from django.utils.encoding import force_unicode 17 17 import sets 18 import types 18 19 19 20 HORIZONTAL, VERTICAL = 1, 2 20 21 # returns the <ul> class for a given radio_admin field … … 237 238 raise ImproperlyConfigured("Put 'django.contrib.contenttypes' in your INSTALLED_APPS setting in order to use the admin application.") 238 239 if 'django.core.context_processors.auth' not in settings.TEMPLATE_CONTEXT_PROCESSORS: 239 240 raise ImproperlyConfigured("Put 'django.core.context_processors.auth' in your TEMPLATE_CONTEXT_PROCESSORS setting in order to use the admin application.") 241 242 def _get_urls(self): 243 from django.conf.urls.defaults import patterns, url 244 urls_module = types.ModuleType('%s.urls' % self.__class__.__name__) 245 info = self.model._meta.app_label, self.model._meta.module_name 246 urlpatterns = patterns('', 247 url(r'^$', self.changelist_view, name='admin_%s_%s_changelist' % info), 248 url(r'^add/$', self.add_view, name='admin_%s_%s_add' % info), 249 url(r'^(.+)/history/$', self.history_view, name='admin_%s_%s_history' % info), 250 url(r'^(.+)/delete/$', self.delete_view, name='admin_%s_%s_delete' % info), 251 url(r'^(.+)/$', self.change_view, name='admin_%s_%s_change' % info), 252 ) 253 urls_module.urlpatterns = urlpatterns 254 return urls_module 255 urls = property(_get_urls) 240 256 241 # Delegate to the appropriate method, based on the URL.242 if url is None:243 return self.changelist_view(request)244 elif url.endswith('add'):245 return self.add_view(request)246 elif url.endswith('history'):247 return self.history_view(request, unquote(url[:-8]))248 elif url.endswith('delete'):249 return self.delete_view(request, unquote(url[:-7]))250 else:251 return self.change_view(request, unquote(url))252 253 257 def _media(self): 254 258 from django.conf import settings 255 259 … … 450 454 'content_type_id': ContentType.objects.get_for_model(self.model).id, 451 455 'save_as': self.save_as, 452 456 'save_on_top': self.save_on_top, 453 'root_path': self.admin_site.root_path,454 457 }) 455 458 return render_to_response(self.change_form_template or [ 456 459 "admin/%s/%s/change_form.html" % (app_label, opts.object_name.lower()), 457 460 "admin/%s/change_form.html" % app_label, 458 461 "admin/change_form.html" 459 462 ], context, context_instance=template.RequestContext(request)) 463 460 464 461 465 def add_view(self, request, form_url='', extra_context=None): 462 466 "The 'add' admin view for this model." … … 510 514 'media': mark_safe(media), 511 515 'inline_admin_formsets': inline_admin_formsets, 512 516 'errors': AdminErrorList(form, inline_formsets), 513 'root_path': self.admin_site.root_path,514 517 } 515 518 context.update(extra_context or {}) 516 519 return self.render_change_form(request, context, add=True) 517 520 add_view = admin_perm_test(add_view) 521 518 522 def change_view(self, request, object_id, extra_context=None): 519 523 "The 'change' admin view for this model." 520 524 model = self.model … … 522 526 app_label = opts.app_label 523 527 524 528 try: 525 obj = model._default_manager.get(pk= object_id)529 obj = model._default_manager.get(pk=unquote(object_id)) 526 530 except model.DoesNotExist: 527 531 # Don't raise Http404 just yet, because we haven't checked 528 532 # permissions yet. We don't want an unauthenticated user to be able … … 573 577 'media': mark_safe(media), 574 578 'inline_admin_formsets': inline_admin_formsets, 575 579 'errors': AdminErrorList(form, inline_formsets), 576 'root_path': self.admin_site.root_path,577 580 } 578 581 context.update(extra_context or {}) 579 582 return self.render_change_form(request, context, change=True, obj=obj) 583 change_view = admin_perm_test(change_view) 580 584 581 585 def changelist_view(self, request, extra_context=None): 582 586 "The 'change list' admin view for this model." … … 603 607 'is_popup': cl.is_popup, 604 608 'cl': cl, 605 609 'has_add_permission': self.has_add_permission(request), 606 'root_path': self.admin_site.root_path,607 610 } 608 611 context.update(extra_context or {}) 609 612 return render_to_response(self.change_list_template or [ … … 611 614 'admin/%s/change_list.html' % app_label, 612 615 'admin/change_list.html' 613 616 ], context, context_instance=template.RequestContext(request)) 617 changelist_view = admin_perm_test(changelist_view) 614 618 615 619 def delete_view(self, request, object_id, extra_context=None): 616 620 "The 'delete' admin view for this model." … … 619 623 app_label = opts.app_label 620 624 621 625 try: 622 obj = self.model._default_manager.get(pk= object_id)626 obj = self.model._default_manager.get(pk=unquote(object_id)) 623 627 except self.model.DoesNotExist: 624 628 # Don't raise Http404 just yet, because we haven't checked 625 629 # permissions yet. We don't want an unauthenticated user to be able … … 634 638 635 639 # Populate deleted_objects, a data structure of all related objects that 636 640 # will also be deleted. 637 deleted_objects = [mark_safe(u'%s: <a href="../../%s/">%s</a>' % (escape(force_unicode(capfirst(opts.verbose_name))), quote(object_id), escape(obj))), []]641 deleted_objects = [mark_safe(u'%s: <a href="../../%s/">%s</a>' % (escape(force_unicode(capfirst(opts.verbose_name))), object_id, escape(obj))), []] 638 642 perms_needed = sets.Set() 639 643 get_deleted_objects(deleted_objects, perms_needed, request.user, obj, opts, 1, self.admin_site) 640 644 … … 656 660 "deleted_objects": deleted_objects, 657 661 "perms_lacking": perms_needed, 658 662 "opts": opts, 659 "root_path": self.admin_site.root_path,660 663 } 661 664 context.update(extra_context or {}) 662 665 return render_to_response(self.delete_confirmation_template or [ … … 664 667 "admin/%s/delete_confirmation.html" % app_label, 665 668 "admin/delete_confirmation.html" 666 669 ], context, context_instance=template.RequestContext(request)) 670 delete_view = admin_perm_test(delete_view) 667 671 668 672 def history_view(self, request, object_id, extra_context=None): 669 673 "The 'history' admin view for this model." … … 681 685 'action_list': action_list, 682 686 'module_name': capfirst(opts.verbose_name_plural), 683 687 'object': obj, 684 'root_path': self.admin_site.root_path,685 688 } 686 689 context.update(extra_context or {}) 687 690 return render_to_response(self.object_history_template or [ … … 689 692 "admin/%s/object_history.html" % opts.app_label, 690 693 "admin/object_history.html" 691 694 ], context, context_instance=template.RequestContext(request)) 695 history_view = admin_perm_test(history_view) 692 696 693 697 class InlineModelAdmin(BaseModelAdmin): 694 698 """ -
django/contrib/admin/util.py
6 6 from django.utils.encoding import force_unicode 7 7 from django.utils.translation import ugettext as _ 8 8 9 10 9 def quote(s): 11 10 """ 12 11 Ensure that primary key values do not confuse the admin URLs by escaping … … 137 136 p = u'%s.%s' % (related.opts.app_label, related.opts.get_change_permission()) 138 137 if not user.has_perm(p): 139 138 perms_needed.add(related.opts.verbose_name) 139 140 def admin_perm_test(func): 141 def inner(admin_site_or_modeladmin, request, *args, **kwargs): 142 if hasattr(admin_site_or_modeladmin, 'has_permission'): 143 admin_site = admin_site_or_modeladmin 144 else: 145 admin_site = admin_site_or_modeladmin.admin_site 146 if not admin_site.has_permission(request): 147 return admin_site.login(request) 148 # User has right permisssions show the view 149 return func(admin_site_or_modeladmin, request, *args, **kwargs) 150 return inner -
django/contrib/admin/sites.py
1 1 from django import http, template 2 2 from django.contrib.admin import ModelAdmin 3 from django.contrib.admin.util import admin_perm_test 3 4 from django.contrib.auth import authenticate, login 4 5 from django.core.exceptions import ImproperlyConfigured 5 6 from django.db.models.base import ModelBase … … 13 14 import cPickle as pickle 14 15 import datetime 15 16 import md5 17 import types 16 18 import re 17 19 18 20 ERROR_MESSAGE = ugettext_lazy("Please enter a correct username and password. Note that both fields are case-sensitive.") 19 LOGIN_FORM_KEY = 'this_is_the_login_form'20 21 21 22 USER_CHANGE_PASSWORD_URL_RE = re.compile('auth/user/(\d+)/password') 22 23 24 LOGIN_FORM_KEY = 'this_is_the_login_form' 25 23 26 class AlreadyRegistered(Exception): 24 27 pass 25 28 … … 116 119 """ 117 120 return request.user.is_authenticated() and request.user.is_staff 118 121 119 def root(self, request, url): 120 """ 121 Handles main URL routing for the admin app. 122 def _get_urls(self): 123 from django.conf.urls.defaults import patterns, url, include 124 from django.core.urlresolvers import RegexURLResolver 125 urls_module = types.ModuleType('%s.urls' % self.__class__.__name__) 126 urlpatterns = patterns('', 127 url(r'^$', self.index, name='admin_index'), 128 url(r'^logout/$', self.logout, name='admin_logout'), 129 url(r'^password_change/$', self.password_change, name='admin_password_change'), 130 url(r'^password_change_done/$', self.password_change_done, name='admin_password_change_done'), 131 url(r'^jsi18n/$', self.i18n_javascript, name='admin_jsi18n'), 132 url(r'^auth/user/(\d+)/password/$', self.user_change_password, name='admin_change_password'), 133 url('^r/(?P<content_type_id>\d+)/(?P<object_id>.+)/$', 'django.views.defaults.shortcut') 134 ) 135 for model, model_admin in self._registry.iteritems(): 136 urlpatterns += patterns('', 137 url('^%s/%s/' % (model._meta.app_label, model._meta.module_name), include(model_admin.urls)) 138 ) 139 urls_module.urlpatterns = urlpatterns 140 return urls_module 141 urls = property(_get_urls) 122 142 123 `url` is the remainder of the URL -- e.g. 'comments/comment/'.124 """125 if request.method == 'GET' and not request.path.endswith('/'):126 return http.HttpResponseRedirect(request.path + '/')127 128 # Figure out the admin base URL path and stash it for later use129 self.root_path = re.sub(re.escape(url) + '$', '', request.path)130 131 url = url.rstrip('/') # Trim trailing slash, if it exists.132 133 # The 'logout' view doesn't require that the person is logged in.134 if url == 'logout':135 return self.logout(request)136 137 # Check permission to continue or display login form.138 if not self.has_permission(request):139 return self.login(request)140 141 if url == '':142 return self.index(request)143 elif url == 'password_change':144 return self.password_change(request)145 elif url == 'password_change/done':146 return self.password_change_done(request)147 elif url == 'jsi18n':148 return self.i18n_javascript(request)149 # urls starting with 'r/' are for the "show in web" links150 elif url.startswith('r/'):151 from django.views.defaults import shortcut152 return shortcut(request, *url.split('/')[1:])153 else:154 match = USER_CHANGE_PASSWORD_URL_RE.match(url)155 if match:156 return self.user_change_password(request, match.group(1))157 158 if '/' in url:159 return self.model_page(request, *url.split('/', 2))160 161 raise http.Http404('The requested admin page does not exist.')162 163 def model_page(self, request, app_label, model_name, rest_of_url=None):164 """165 Handles the model-specific functionality of the admin site, delegating166 to the appropriate ModelAdmin class.167 """168 from django.db import models169 model = models.get_model(app_label, model_name)170 if model is None:171 raise http.Http404("App %r, model %r, not found." % (app_label, model_name))172 try:173 admin_obj = self._registry[model]174 except KeyError:175 raise http.Http404("This model exists but has not been registered with the admin site.")176 return admin_obj(request, rest_of_url)177 model_page = never_cache(model_page)178 179 143 def password_change(self, request): 180 144 """ 181 145 Handles the "change password" task -- both form display and validation. 182 146 """ 183 147 from django.contrib.auth.views import password_change 184 148 return password_change(request) 149 passoword_change = admin_perm_test(password_change) 185 150 186 151 def password_change_done(self, request): 187 152 """ … … 189 154 """ 190 155 from django.contrib.auth.views import password_change_done 191 156 return password_change_done(request) 157 password_change_done = admin_perm_test(password_change_done) 192 158 193 159 def user_change_password(self, request, id): 194 160 """ … … 196 162 """ 197 163 from django.contrib.auth.views import user_change_password 198 164 return user_change_password(request, id) 165 user_change_password = admin_perm_test(user_change_password) 199 166 200 167 def i18n_javascript(self, request): 201 168 """ … … 210 177 else: 211 178 from django.views.i18n import null_javascript_catalog as javascript_catalog 212 179 return javascript_catalog(request, packages='django.conf') 180 i18n_javascript = admin_perm_test(i18n_javascript) 213 181 214 182 def logout(self, request): 215 183 """ … … 226 194 Displays the login form for the given HttpRequest. 227 195 """ 228 196 from django.contrib.auth.models import User 229 230 197 # If this isn't already the login page, display it. 231 198 if not request.POST.has_key(LOGIN_FORM_KEY): 232 199 if request.POST: … … 266 233 login(request, user) 267 234 if request.POST.has_key('post_data'): 268 235 post_data = _decode_post_data(request.POST['post_data']) 236 request.session.delete_test_cookie() 269 237 if post_data and not post_data.has_key(LOGIN_FORM_KEY): 270 238 # overwrite request.POST with the saved post_data, and continue 271 239 request.POST = post_data 272 240 request.user = user 273 return self.root(request, request.path.split(self.root_path)[-1]) 241 from django.core.urlresolvers import resolve 242 ret_view, vargs, vkwargs = resolve(request.path) 243 return ret_view(request, *vargs, **vkwargs) 274 244 else: 275 request.session.delete_test_cookie()276 245 return http.HttpResponseRedirect(request.path) 277 246 else: 278 247 return self.display_login_form(request, ERROR_MESSAGE) … … 324 293 context = { 325 294 'title': _('Site administration'), 326 295 'app_list': app_list, 327 'root_path': self.root_path,328 296 } 329 297 context.update(extra_context or {}) 330 298 return render_to_response(self.index_template or 'admin/index.html', context, 331 299 context_instance=template.RequestContext(request) 332 300 ) 333 index = never_cache( index)301 index = never_cache(admin_perm_test(index)) 334 302 335 303 def display_login_form(self, request, error_message='', extra_context=None): 336 304 request.session.set_test_cookie() … … 342 310 post_data = _encode_post_data(request.POST) 343 311 else: 344 312 post_data = _encode_post_data({}) 345 313 346 314 context = { 347 315 'title': _('Log in'), 348 316 'app_path': request.path, 349 317 'post_data': post_data, 350 318 'error_message': error_message, 351 'root_path': self.root_path,352 319 } 353 320 context.update(extra_context or {}) 354 321 return render_to_response(self.login_template or 'admin/login.html', context, 355 322 context_instance=template.RequestContext(request) 356 323 ) 357 324 358 359 325 # This global object represents the default admin site, for the common case. 360 326 # You can instantiate AdminSite in your own code to create a custom admin site. 361 327 site = AdminSite() -
django/contrib/auth/admin.py
58 58 'opts': User._meta, 59 59 'save_as': False, 60 60 'username_help_text': User._meta.get_field('username').help_text, 61 'root_path': self.admin_site.root_path,62 61 }, context_instance=template.RequestContext(request)) 63 62 64 63 admin.site.register(Group, GroupAdmin) -
tests/regressiontests/admin_views/tests.py
86 86 '/test_admin/admin/admin_views/article/add' 87 87 ) 88 88 self.assertRedirects(request, 89 '/test_admin/admin/admin_views/article/add/' 89 '/test_admin/admin/admin_views/article/add/', status_code=301 90 90 ) 91 91 92 92 def testLogin(self): -
tests/regressiontests/admin_views/urls.py
3 3 4 4 urlpatterns = patterns('', 5 5 (r'^admin/doc/', include('django.contrib.admindocs.urls')), 6 (r'^admin/ (.*)', admin.site.root),6 (r'^admin/', include(admin.site.urls)), 7 7 )