Ticket #10061: admin-urls.8.diff
File admin-urls.8.diff, 17.1 KB (added by , 16 years ago) |
---|
-
django/contrib/admin/options.py
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index ed41c7f..8aff5a7 100644
a b class ModelAdmin(BaseModelAdmin): 217 217 url(r'^add/$', 218 218 wrap(self.add_view), 219 219 name='%sadmin_%s_%s_add' % info), 220 url(r'^( .+)/history/$',220 url(r'^(?P<object_id>.+)/history/$', 221 221 wrap(self.history_view), 222 222 name='%sadmin_%s_%s_history' % info), 223 url(r'^( .+)/delete/$',223 url(r'^(?P<object_id>.+)/delete/$', 224 224 wrap(self.delete_view), 225 225 name='%sadmin_%s_%s_delete' % info), 226 url(r'^( .+)/$',226 url(r'^(?P<object_id>.+)/$', 227 227 wrap(self.change_view), 228 228 name='%sadmin_%s_%s_change' % info), 229 229 ) … … class ModelAdmin(BaseModelAdmin): 437 437 'save_as': self.save_as, 438 438 'save_on_top': self.save_on_top, 439 439 'root_path': self.admin_site.root_path, 440 'admin_site': self.admin_site.name, 440 441 }) 441 442 return render_to_response(self.change_form_template or [ 442 443 "admin/%s/%s/change_form.html" % (app_label, opts.object_name.lower()), … … class ModelAdmin(BaseModelAdmin): 571 572 'errors': helpers.AdminErrorList(form, formsets), 572 573 'root_path': self.admin_site.root_path, 573 574 'app_label': opts.app_label, 575 'admin_site': self.admin_site.name, 574 576 } 575 577 context.update(extra_context or {}) 576 578 return self.render_change_form(request, context, add=True) … … class ModelAdmin(BaseModelAdmin): 649 651 'inline_admin_formsets': inline_admin_formsets, 650 652 'errors': helpers.AdminErrorList(form, formsets), 651 653 'root_path': self.admin_site.root_path, 654 'admin_site': self.admin_site.name, 652 655 'app_label': opts.app_label, 653 656 } 654 657 context.update(extra_context or {}) … … class ModelAdmin(BaseModelAdmin): 681 684 'cl': cl, 682 685 'has_add_permission': self.has_add_permission(request), 683 686 'root_path': self.admin_site.root_path, 687 'admin_site': self.admin_site.name, 684 688 'app_label': app_label, 685 689 } 686 690 context.update(extra_context or {}) … … class ModelAdmin(BaseModelAdmin): 736 740 "perms_lacking": perms_needed, 737 741 "opts": opts, 738 742 "root_path": self.admin_site.root_path, 743 'admin_site': self.admin_site.name, 739 744 "app_label": app_label, 740 745 } 741 746 context.update(extra_context or {}) … … class ModelAdmin(BaseModelAdmin): 763 768 'module_name': capfirst(force_unicode(opts.verbose_name_plural)), 764 769 'object': obj, 765 770 'root_path': self.admin_site.root_path, 771 'admin_site': self.admin_site.name, 766 772 'app_label': app_label, 767 773 } 768 774 context.update(extra_context or {}) -
django/contrib/admin/sites.py
diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py index 42ce296..d77eebd 100644
a b from django import http, template 3 3 from django.contrib.admin import ModelAdmin 4 4 from django.contrib.auth import authenticate, login 5 5 from django.db.models.base import ModelBase 6 from django.core.urlresolvers import reverse 6 7 from django.core.exceptions import ImproperlyConfigured 7 8 from django.shortcuts import render_to_response 8 9 from django.utils.functional import update_wrapper … … class AdminSite(object): 35 36 36 37 def __init__(self, name=None): 37 38 self._registry = {} # model_class class -> admin_class instance 38 # TODO Root path is used to calculate urls under the old root() method 39 # in order to maintain backwards compatibility we are leaving that in 40 # so root_path isn't needed, not sure what to do about this. 41 self.root_path = 'admin/' 39 self.root_path = None 42 40 if name is None: 43 41 name = '' 44 42 else: … … class AdminSite(object): 163 161 name='%sadmin_index' % self.name), 164 162 url(r'^logout/$', 165 163 wrap(self.logout), 166 name='%sadmin_logout' ),164 name='%sadmin_logout' % self.name), 167 165 url(r'^password_change/$', 168 166 wrap(self.password_change), 169 167 name='%sadmin_password_change' % self.name), … … class AdminSite(object): 197 195 Handles the "change password" task -- both form display and validation. 198 196 """ 199 197 from django.contrib.auth.views import password_change 198 if self.root_path is not None: 199 url = '%spassword_change/done/' % self.root_path 200 else: 201 url = reverse('%sadmin_password_change_done' % self.name) 200 202 return password_change(request, 201 post_change_redirect= '%spassword_change/done/' % self.root_path)203 post_change_redirect=url) 202 204 203 205 def password_change_done(self, request): 204 206 """ … … class AdminSite(object): 328 330 'title': _('Site administration'), 329 331 'app_list': app_list, 330 332 'root_path': self.root_path, 333 'admin_site': self.name 331 334 } 332 335 context.update(extra_context or {}) 333 336 return render_to_response(self.index_template or 'admin/index.html', context, … … class AdminSite(object): 342 345 'app_path': request.get_full_path(), 343 346 'error_message': error_message, 344 347 'root_path': self.root_path, 348 'admin_site': self.name, 345 349 } 346 350 context.update(extra_context or {}) 347 351 return render_to_response(self.login_template or 'admin/login.html', context, … … class AdminSite(object): 388 392 'title': _('%s administration') % capfirst(app_label), 389 393 'app_list': [app_dict], 390 394 'root_path': self.root_path, 395 'admin_site': self.name, 391 396 } 392 397 context.update(extra_context or {}) 393 398 return render_to_response(self.app_index_template or 'admin/app_index.html', context, -
django/contrib/admin/templates/admin/base.html
diff --git a/django/contrib/admin/templates/admin/base.html b/django/contrib/admin/templates/admin/base.html index e969d1b..623d769 100644
a b 25 25 {% block branding %}{% endblock %} 26 26 </div> 27 27 {% if user.is_authenticated and user.is_staff %} 28 <div id="user-tools">{% trans 'Welcome,' %} <strong>{% firstof user.first_name user.username %}</strong>. {% block userlinks %}{% url django-admindocs-docroot as docsroot %}{% if docsroot %}<a href="{{ docsroot }}">{% trans 'Documentation' %}</a> / {% endif %}<a href="{{ root_path }}password_change/">{% trans 'Change password' %}</a> / <a href="{{ root_path }}logout/">{% trans 'Log out' %}</a>{% endblock %}</div> 28 <div id="user-tools"> 29 {% trans 'Welcome,' %} 30 <strong> 31 {% firstof user.first_name user.username %} 32 </strong>. 33 {% block userlinks %} 34 {% url django-admindocs-docroot as docsroot %} 35 {% if docsroot %} 36 <a href="{{ docsroot }}"> 37 {% trans 'Documentation' %} 38 </a> / 39 {% endif %} 40 {% url admin_site:admin_password_change as password_change_url %} 41 {% if password_change_url %} 42 <a href="{{ password_change_url }}"> 43 {% else %} 44 <a href="{{ root_path }}password_change/"> 45 {% endif %} 46 {% trans 'Change password' %} 47 </a> / 48 {% url admin_site:admin_logout as logout_url %} 49 {% if logout_url %} 50 <a href="{{ logout_url }}"> 51 {% else %} 52 <a href="{{ root_path }}logout/"> 53 {% endif %} 54 {% trans 'Log out' %} 55 </a> 56 {% endblock %} 57 </div> 29 58 {% endif %} 30 59 {% block nav-global %}{% endblock %} 31 60 </div> -
django/contrib/auth/admin.py
diff --git a/django/contrib/auth/admin.py b/django/contrib/auth/admin.py index c5326b7..9a13205 100644
a b class UserAdmin(admin.ModelAdmin): 92 92 'save_as': False, 93 93 'username_help_text': self.model._meta.get_field('username').help_text, 94 94 'root_path': self.admin_site.root_path, 95 'admin_site': self.admin_site.name, 95 96 'app_label': self.model._meta.app_label, 96 97 }, context_instance=template.RequestContext(request)) 97 98 … … class UserAdmin(admin.ModelAdmin): 122 123 'save_as': False, 123 124 'show_save': True, 124 125 'root_path': self.admin_site.root_path, 126 'admin_site': self.admin_site.name, 125 127 }, context_instance=RequestContext(request)) 126 128 127 129 -
django/contrib/comments/views/moderation.py
diff --git a/django/contrib/comments/views/moderation.py b/django/contrib/comments/views/moderation.py index 3334b09..880c6d7 100644
a b from django.core.paginator import Paginator, InvalidPage 7 7 from django.http import Http404 8 8 from django.contrib import comments 9 9 from django.contrib.comments import signals 10 from django.contrib import admin 10 11 11 12 #@login_required 12 13 def flag(request, comment_id, next=None): … … def moderation_queue(request): 185 186 'previous': page - 1, 186 187 'pages': paginator.num_pages, 187 188 'hits' : paginator.count, 188 'page_range' : paginator.page_range 189 'page_range' : paginator.page_range, 190 'admin_site': admin.site.name, 189 191 }, context_instance=template.RequestContext(request)) 190 192 191 193 moderation_queue = permission_required("comments.can_moderate")(moderation_queue) -
django/core/urlresolvers.py
diff --git a/django/core/urlresolvers.py b/django/core/urlresolvers.py index 59dcdcb..7044842 100644
a b def resolve(path, urlconf=None): 254 254 return get_resolver(urlconf).resolve(path) 255 255 256 256 def reverse(viewname, urlconf=None, args=None, kwargs=None, prefix=None): 257 if isinstance(viewname, basestring): 258 viewname = ''.join(viewname.split(':')) 257 259 args = args or [] 258 260 kwargs = kwargs or {} 259 261 if prefix is None: -
django/template/defaulttags.py
diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py index 0911309..c72fb0b 100644
a b class URLNode(Node): 368 368 369 369 def render(self, context): 370 370 from django.core.urlresolvers import reverse, NoReverseMatch 371 view_name_parts = [] 372 for part in self.view_name[:-1]: 373 try: 374 view_name_parts.append(Variable(part).resolve(context)) 375 except VariableDoesNotExist: 376 view_name_parts.append(part) 377 view_name_parts.append(self.view_name[-1]) 378 view_name = ':'.join(view_name_parts) 371 379 args = [arg.resolve(context) for arg in self.args] 372 380 kwargs = dict([(smart_str(k,'ascii'), v.resolve(context)) 373 381 for k, v in self.kwargs.items()]) … … class URLNode(Node): 379 387 # {% url ... as var %} construct in which cause return nothing. 380 388 url = '' 381 389 try: 382 url = reverse( self.view_name, args=args, kwargs=kwargs)390 url = reverse(view_name, args=args, kwargs=kwargs) 383 391 except NoReverseMatch: 384 392 project_name = settings.SETTINGS_MODULE.split('.')[0] 385 393 try: 386 url = reverse(project_name + '.' + self.view_name,394 url = reverse(project_name + '.' + view_name, 387 395 args=args, kwargs=kwargs) 388 396 except NoReverseMatch: 389 397 if self.asvar is None: … … def url(parser, token): 1102 1110 raise TemplateSyntaxError("'%s' takes at least one argument" 1103 1111 " (path to a view)" % bits[0]) 1104 1112 viewname = bits[1] 1113 if ':' in viewname: 1114 viewname = viewname.split(':') 1115 else: 1116 viewname = [viewname] 1105 1117 args = [] 1106 1118 kwargs = {} 1107 1119 asvar = None -
docs/ref/contrib/admin.txt
diff --git a/docs/ref/contrib/admin.txt b/docs/ref/contrib/admin.txt index 35bfde2..f15fe1c 100644
a b It possible to add additional views to the admin site in the same way one can 1186 1186 add them to ``ModelAdmins``. This by using the ``get_urls()`` method on an 1187 1187 AdminSite in the same way as `described above`__ 1188 1188 1189 .. note:: 1190 Any view you render that uses the admin templates, or extends the base 1191 admin template should include in it's context a variable named 1192 ``admin_site`` that contains the ``AdminSite`` instances name, which for 1193 ``AdminSite`` instances exists at ``self.name`` and for ``ModelAdmin`` 1194 instances exists at ``self.admin_site.name``. 1195 1189 1196 __ `get_urls(self)`_ 1197 1198 1199 Reversing Admin URLs 1200 ==================== 1201 1202 .. versionadded :: 1.1 1203 Before Django 1.1 it wasn't possible to reverse admin URLs. In addition 1204 for this to work you need to be using the new Django 1.1 ``include()`` 1205 syntax for setting up admin URLs. 1206 1207 The following are the url names, and parameters for ``AdminSite`` urls, all 1208 url names are prefixed with the ``AdminSite`` instace's name, followed by an 1209 underscore, so if an ``AdminSite`` was named ``"user_admin"`` it's urls names 1210 would be prefixed with ``"user_admin_"``, the default ``AdminSite``'s name is 1211 ``''`` however it's names *do not* have the trailing underscore: 1212 1213 ====================== =============================== ============= 1214 Page URL name Parameters 1215 ====================== =============================== ============= 1216 Index ``admin_index`` 1217 Logout ``admin_logout`` 1218 Password change ``admin_password_change`` 1219 Password change done ``admin_password_change_done`` 1220 i18n javascript ``admin_jsi18n`` 1221 Application index page ``admin_app_list`` ``app_label`` 1222 ====================== =============================== ============= 1223 1224 The remaining urls are for ``ModelAdmin`` instances, these too are all prefixed 1225 with the ``AdminSite``'s name(with the same caviets as the ``Adminsite``, and 1226 ``app_label`` and ``model_name`` are the lowercase versions of the 1227 application's name and the model's name: 1228 1229 ====================== ===================================================== ============= 1230 Page URL name Parameters 1231 ====================== ===================================================== ============= 1232 Changelist ``admin_{{ app_label }}_{{ model_name }}_changelist`` 1233 Add ``admin_{{ app_label }}_{{ model_name }}_add`` 1234 History ``admin_{{ app_label }}_{{ model_name }}_history`` ``object_id`` 1235 Delete ``admin_{{ app_label }}_{{ model_name }}_delete`` ``object_id`` 1236 Change ``admin_{{ app_label }}_{{ model_name }}_change`` ``object_id`` 1237 ====================== ===================================================== ============= 1238 -
tests/regressiontests/admin_views/tests.py
diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py index 39daf11..52ce268 100644
a b class AdminViewBasicTest(TestCase): 172 172 self.assertRedirects(response, '/test_admin/%s/admin_views/thing/?e=1' % self.urlbit) 173 173 response = self.client.get('/test_admin/%s/admin_views/thing/' % self.urlbit, {'color__id__exact': 'StringNotInteger!'}) 174 174 self.assertRedirects(response, '/test_admin/%s/admin_views/thing/?e=1' % self.urlbit) 175 176 def testLogoutAndPasswordChangeURLs(self): 177 response = self.client.get('/test_admin/%s/admin_views/article/' % self.urlbit) 178 self.failIf('<a href="/test_admin/%s/logout/">' % self.urlbit not in response.content) 179 self.failIf('<a href="/test_admin/%s/password_change/">' % self.urlbit not in response.content) 175 180 176 181 class CustomModelAdminTest(AdminViewBasicTest): 177 182 urlbit = "admin2" -
tests/urls.py
diff --git a/tests/urls.py b/tests/urls.py index 43806de..a192f16 100644
a b urlpatterns = patterns('', 20 20 21 21 # test urlconf for middleware tests 22 22 (r'^middleware/', include('regressiontests.middleware.urls')), 23 24 # admin widget tests 25 (r'widget_admin/', include('regressiontests.admin_widgets.urls')), 23 26 24 27 # admin view tests 25 28 (r'^test_admin/', include('regressiontests.admin_views.urls')), 26 29 (r'^generic_inline_admin/', include('regressiontests.generic_inline_admin.urls')), 27 30 28 # admin widget tests29 (r'widget_admin/', include('regressiontests.admin_widgets.urls')),30 31 31 32 (r'^utils/', include('regressiontests.utils.urls')), 32 33