Django

Code

Ticket #10061: admin-urls.11.diff

File admin-urls.11.diff, 18.0 kB (added by Alex, 1 year ago)

a few extra lines of documentation

  • a/django/contrib/admin/options.py

    old new  
    233233            url(r'^add/$', 
    234234                wrap(self.add_view), 
    235235                name='%sadmin_%s_%s_add' % info), 
    236             url(r'^(.+)/history/$', 
     236            url(r'^(?P<object_id>.+)/history/$', 
    237237                wrap(self.history_view), 
    238238                name='%sadmin_%s_%s_history' % info), 
    239             url(r'^(.+)/delete/$', 
     239            url(r'^(?P<object_id>.+)/delete/$', 
    240240                wrap(self.delete_view), 
    241241                name='%sadmin_%s_%s_delete' % info), 
    242             url(r'^(.+)/$', 
     242            url(r'^(?P<object_id>.+)/$', 
    243243                wrap(self.change_view), 
    244244                name='%sadmin_%s_%s_change' % info), 
    245245        ) 
     
    593593            'save_as': self.save_as, 
    594594            'save_on_top': self.save_on_top, 
    595595            'root_path': self.admin_site.root_path, 
     596            'admin_site': self.admin_site.name, 
    596597        }) 
    597598        return render_to_response(self.change_form_template or [ 
    598599            "admin/%s/%s/change_form.html" % (app_label, opts.object_name.lower()), 
     
    780781            'errors': helpers.AdminErrorList(form, formsets), 
    781782            'root_path': self.admin_site.root_path, 
    782783            'app_label': opts.app_label, 
     784            'admin_site': self.admin_site.name, 
    783785        } 
    784786        context.update(extra_context or {}) 
    785787        return self.render_change_form(request, context, add=True) 
     
    868870            'inline_admin_formsets': inline_admin_formsets, 
    869871            'errors': helpers.AdminErrorList(form, formsets), 
    870872            'root_path': self.admin_site.root_path, 
     873            'admin_site': self.admin_site.name, 
    871874            'app_label': opts.app_label, 
    872875        } 
    873876        context.update(extra_context or {}) 
     
    958961            'media': media, 
    959962            'has_add_permission': self.has_add_permission(request), 
    960963            'root_path': self.admin_site.root_path, 
     964            'admin_site': self.admin_site.name, 
    961965            'app_label': app_label, 
    962966            'action_form': action_form, 
    963967            'actions_on_top': self.actions_on_top, 
     
    10161020            "perms_lacking": perms_needed, 
    10171021            "opts": opts, 
    10181022            "root_path": self.admin_site.root_path, 
     1023            'admin_site': self.admin_site.name, 
    10191024            "app_label": app_label, 
    10201025        } 
    10211026        context.update(extra_context or {}) 
     
    10431048            'module_name': capfirst(force_unicode(opts.verbose_name_plural)), 
    10441049            'object': obj, 
    10451050            'root_path': self.admin_site.root_path, 
     1051            'admin_site': self.admin_site.name, 
    10461052            'app_label': app_label, 
    10471053        } 
    10481054        context.update(extra_context or {}) 
  • a/django/contrib/admin/sites.py

    old new  
    33from django.contrib.admin import ModelAdmin 
    44from django.contrib.auth import authenticate, login 
    55from django.db.models.base import ModelBase 
     6from django.core.urlresolvers import reverse 
    67from django.core.exceptions import ImproperlyConfigured 
    78from django.shortcuts import render_to_response 
    89from django.utils.functional import update_wrapper 
     
    3536 
    3637    def __init__(self, name=None): 
    3738        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 
    4240        if name is None: 
    4341            name = '' 
    4442        else: 
     
    171169                name='%sadmin_index' % self.name), 
    172170            url(r'^logout/$', 
    173171                wrap(self.logout), 
    174                 name='%sadmin_logout'), 
     172                name='%sadmin_logout' % self.name), 
    175173            url(r'^password_change/$', 
    176174                wrap(self.password_change), 
    177175                name='%sadmin_password_change' % self.name), 
     
    205203        Handles the "change password" task -- both form display and validation. 
    206204        """ 
    207205        from django.contrib.auth.views import password_change 
    208         return password_change(request, 
    209             post_change_redirect='%spassword_change/done/' % self.root_path) 
     206        if self.root_path is not None: 
     207            url = '%spassword_change/done/' % self.root_path 
     208        else: 
     209            url = reverse('%sadmin_password_change_done' % self.name) 
     210        return password_change(request, post_change_redirect=url) 
    210211 
    211212    def password_change_done(self, request): 
    212213        """ 
     
    336337            'title': _('Site administration'), 
    337338            'app_list': app_list, 
    338339            'root_path': self.root_path, 
     340            'admin_site': self.name 
    339341        } 
    340342        context.update(extra_context or {}) 
    341343        return render_to_response(self.index_template or 'admin/index.html', context, 
     
    350352            'app_path': request.get_full_path(), 
    351353            'error_message': error_message, 
    352354            'root_path': self.root_path, 
     355            'admin_site': self.name, 
    353356        } 
    354357        context.update(extra_context or {}) 
    355358        return render_to_response(self.login_template or 'admin/login.html', context, 
     
    396399            'title': _('%s administration') % capfirst(app_label), 
    397400            'app_list': [app_dict], 
    398401            'root_path': self.root_path, 
     402            'admin_site': self.name, 
    399403        } 
    400404        context.update(extra_context or {}) 
    401405        return render_to_response(self.app_index_template or 'admin/app_index.html', context, 
  • a/django/contrib/admin/templates/admin/base.html

    old new  
    2525        {% block branding %}{% endblock %} 
    2626        </div> 
    2727        {% 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>{% firstof user.first_name user.username %}</strong>.  
     31            {% block userlinks %} 
     32                {% url django-admindocs-docroot as docsroot %} 
     33                {% if docsroot %} 
     34                    <a href="{{ docsroot }}"> 
     35                        {% trans 'Documentation' %} 
     36                    </a> /  
     37                {% endif %} 
     38                {% url admin_site:admin_password_change as password_change_url %} 
     39                {% if password_change_url %} 
     40                    <a href="{{ password_change_url }}"> 
     41                {% else %} 
     42                    <a href="{{ root_path }}password_change/"> 
     43                {% endif %} 
     44                    {% trans 'Change password' %} 
     45                </a> /  
     46                {% url admin_site:admin_logout as logout_url %} 
     47                {% if logout_url %} 
     48                    <a href="{{ logout_url }}"> 
     49                {% else %} 
     50                    <a href="{{ root_path }}logout/"> 
     51                {% endif %} 
     52                    {% trans 'Log out' %} 
     53                </a> 
     54            {% endblock %} 
     55        </div> 
    2956        {% endif %} 
    3057        {% block nav-global %}{% endblock %} 
    3158    </div> 
  • a/django/contrib/auth/admin.py

    old new  
    9292            'save_as': False, 
    9393            'username_help_text': self.model._meta.get_field('username').help_text, 
    9494            'root_path': self.admin_site.root_path, 
     95            'admin_site': self.admin_site.name, 
    9596            'app_label': self.model._meta.app_label,             
    9697        }, context_instance=template.RequestContext(request)) 
    9798 
     
    122123            'save_as': False, 
    123124            'show_save': True, 
    124125            'root_path': self.admin_site.root_path, 
     126            'admin_site': self.admin_site.name, 
    125127        }, context_instance=RequestContext(request)) 
    126128 
    127129 
  • a/django/contrib/comments/views/moderation.py

    old new  
    77from django.http import Http404 
    88from django.contrib import comments 
    99from django.contrib.comments import signals 
     10from django.contrib import admin 
    1011 
    1112#@login_required 
    1213def flag(request, comment_id, next=None): 
     
    185186        'previous': page - 1, 
    186187        'pages': paginator.num_pages, 
    187188        'hits' : paginator.count, 
    188         'page_range' : paginator.page_range 
     189        'page_range' : paginator.page_range, 
     190        'admin_site': admin.site.name, 
    189191    }, context_instance=template.RequestContext(request)) 
    190192 
    191193moderation_queue = permission_required("comments.can_moderate")(moderation_queue) 
  • a/django/core/urlresolvers.py

    old new  
    257257    return get_resolver(urlconf).resolve(path) 
    258258 
    259259def reverse(viewname, urlconf=None, args=None, kwargs=None, prefix=None): 
     260    if isinstance(viewname, basestring): 
     261        viewname = ''.join(viewname.split(':')) 
    260262    args = args or [] 
    261263    kwargs = kwargs or {} 
    262264    if prefix is None: 
  • a/django/template/defaulttags.py

    old new  
    359359 
    360360    def render(self, context): 
    361361        from django.core.urlresolvers import reverse, NoReverseMatch 
     362        view_name_parts = [] 
     363        for part in self.view_name[:-1]: 
     364            try: 
     365                view_name_parts.append(Variable(part).resolve(context)) 
     366            except VariableDoesNotExist: 
     367                view_name_parts.append(part) 
     368        view_name_parts.append(self.view_name[-1]) 
     369        view_name = ':'.join(view_name_parts) 
    362370        args = [arg.resolve(context) for arg in self.args] 
    363371        kwargs = dict([(smart_str(k,'ascii'), v.resolve(context)) 
    364372                       for k, v in self.kwargs.items()]) 
     
    369377        # {% url ... as var %} construct in which cause return nothing. 
    370378        url = '' 
    371379        try: 
    372             url = reverse(self.view_name, args=args, kwargs=kwargs) 
     380            url = reverse(view_name, args=args, kwargs=kwargs) 
    373381        except NoReverseMatch: 
    374382            project_name = settings.SETTINGS_MODULE.split('.')[0] 
    375383            try: 
    376                 url = reverse(project_name + '.' + self.view_name, 
     384                url = reverse(project_name + '.' + view_name, 
    377385                              args=args, kwargs=kwargs) 
    378386            except NoReverseMatch: 
    379387                if self.asvar is None: 
     
    10971105        raise TemplateSyntaxError("'%s' takes at least one argument" 
    10981106                                  " (path to a view)" % bits[0]) 
    10991107    viewname = bits[1] 
     1108    if ':' in viewname: 
     1109        viewname = viewname.split(':') 
     1110    else: 
     1111        viewname = [viewname] 
    11001112    args = [] 
    11011113    kwargs = {} 
    11021114    asvar = None 
  • a/docs/ref/contrib/admin/index.txt

    old new  
    12101210 
    12111211.. versionchanged:: 1.1 
    12121212    The method for hooking ``AdminSite`` instances into urls has changed in 
    1213     Django 1.1. 
     1213    Django 1.1 
    12141214 
    12151215In this example, the URLs ``/basic-admin/`` and ``/advanced-admin/`` feature 
    12161216separate versions of the admin site -- using the ``AdminSite`` instances 
     
    12261226        ('^advanced-admin/', include(advanced_site.urls)), 
    12271227    ) 
    12281228 
     1229``AdminSites`` take a single argument to their constructor, their name, which 
     1230can be anything you like.  This argument becomes the prefix to the URL names 
     1231for the pruposes of :ref:`reversing them<admin-reverse-urls>`.  This is only 
     1232necesary if you are using more than one ``AdminSite``. 
     1233 
    12291234Adding views to admin sites 
    12301235--------------------------- 
    12311236 
     
    12351240add them to ``ModelAdmins``.  This by using the ``get_urls()`` method on an 
    12361241AdminSite in the same way as `described above`__ 
    12371242 
     1243.. note:: 
     1244    Any view you render that uses the admin templates, or extends the base 
     1245    admin template should include in it's context a variable named 
     1246    ``admin_site`` that contains the ``AdminSite`` instances name, which for 
     1247    ``AdminSite`` instances exists at ``self.name`` and for ``ModelAdmin`` 
     1248    instances exists at ``self.admin_site.name``. 
     1249 
    12381250__ `get_urls(self)`_ 
     1251 
     1252.. _admin-reverse-urls: 
     1253 
     1254Reversing Admin URLs 
     1255==================== 
     1256 
     1257.. versionadded :: 1.1 
     1258    Before Django 1.1 it wasn't possible to reverse admin URLs.  In addition 
     1259    for this to work you need to be using the new Django 1.1 ``include()`` 
     1260    syntax for setting up admin URLs. 
     1261 
     1262The following are the url names, and parameters for ``AdminSite`` urls, all 
     1263url names are prefixed with the ``AdminSite`` instace's name, followed by an 
     1264underscore, so if an ``AdminSite`` was named ``"user_admin"`` it's urls names 
     1265would be prefixed with ``"user_admin_"``, the default ``AdminSite``'s name is 
     1266``''`` however it's names *do not* have the trailing underscore: 
     1267 
     1268    ======================  =============================== ============= 
     1269    Page                    URL name                        Parameters 
     1270    ======================  =============================== ============= 
     1271    Index                   ``admin_index`` 
     1272    Logout                  ``admin_logout`` 
     1273    Password change         ``admin_password_change`` 
     1274    Password change done    ``admin_password_change_done`` 
     1275    i18n javascript         ``admin_jsi18n`` 
     1276    Application index page  ``admin_app_list``              ``app_label`` 
     1277    ======================  =============================== ============= 
     1278 
     1279The remaining urls are for ``ModelAdmin`` instances, these too are all prefixed 
     1280with the ``AdminSite``'s name(with the same caviets as the ``Adminsite``, and 
     1281``app_label`` and ``model_name`` are the lowercase versions of the 
     1282application's name and the model's name: 
     1283 
     1284    ======================  =====================================================   ============= 
     1285    Page                    URL name                                                Parameters 
     1286    ======================  =====================================================   ============= 
     1287    Changelist              ``admin_{{ app_label }}_{{ model_name }}_changelist`` 
     1288    Add                     ``admin_{{ app_label }}_{{ model_name }}_add`` 
     1289    History                 ``admin_{{ app_label }}_{{ model_name }}_history``      ``object_id`` 
     1290    Delete                  ``admin_{{ app_label }}_{{ model_name }}_delete``       ``object_id`` 
     1291    Change                  ``admin_{{ app_label }}_{{ model_name }}_change``       ``object_id`` 
     1292    ======================  =====================================================   ============= 
  • a/tests/regressiontests/admin_views/tests.py

    old new  
    180180        self.assertRedirects(response, '/test_admin/%s/admin_views/thing/?e=1' % self.urlbit) 
    181181        response = self.client.get('/test_admin/%s/admin_views/thing/' % self.urlbit, {'color__id__exact': 'StringNotInteger!'}) 
    182182        self.assertRedirects(response, '/test_admin/%s/admin_views/thing/?e=1' % self.urlbit) 
     183     
     184    def testLogoutAndPasswordChangeURLs(self): 
     185        response = self.client.get('/test_admin/%s/admin_views/article/' % self.urlbit) 
     186        self.failIf('<a href="/test_admin/%s/logout/">' % self.urlbit not in response.content) 
     187        self.failIf('<a href="/test_admin/%s/password_change/">' % self.urlbit not in response.content)  
    183188 
    184189class CustomModelAdminTest(AdminViewBasicTest): 
    185190    urlbit = "admin2" 
  • a/tests/urls.py

    old new  
    2121    # test urlconf for middleware tests 
    2222    (r'^middleware/', include('regressiontests.middleware.urls')), 
    2323 
     24    # admin widget tests 
     25    (r'widget_admin/', include('regressiontests.admin_widgets.urls')), 
     26 
    2427    # admin view tests 
    2528    (r'^test_admin/', include('regressiontests.admin_views.urls')), 
    2629    (r'^generic_inline_admin/', include('regressiontests.generic_inline_admin.urls')), 
    2730 
    28     # admin widget tests 
    29     (r'widget_admin/', include('regressiontests.admin_widgets.urls')), 
    3031 
    3132    (r'^utils/', include('regressiontests.utils.urls')), 
    3233