Ticket #10061: admin-urls.10.diff

File admin-urls.10.diff, 17.2 KB (added by Alex Gaynor, 15 years ago)

updated for merge conflicts

  • django/contrib/admin/options.py

    diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
    index 8cc27c5..e00bbd6 100644
    a b class ModelAdmin(BaseModelAdmin):  
    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        )
    class ModelAdmin(BaseModelAdmin):  
    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()),
    class ModelAdmin(BaseModelAdmin):  
    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)
    class ModelAdmin(BaseModelAdmin):  
    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 {})
    class ModelAdmin(BaseModelAdmin):  
    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,
    class ModelAdmin(BaseModelAdmin):  
    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 {})
    class ModelAdmin(BaseModelAdmin):  
    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 {})
  • django/contrib/admin/sites.py

    diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py
    index 872e4a0..e7bbfed 100644
    a b from django import http, template  
    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
    class AdminSite(object):  
    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:
    class AdminSite(object):  
    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),
    class AdminSite(object):  
    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        """
    class AdminSite(object):  
    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,
    class AdminSite(object):  
    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,
    class AdminSite(object):  
    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,
  • 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  
    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>
     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>
    2958        {% endif %}
    3059        {% block nav-global %}{% endblock %}
    3160    </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):  
    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
    class UserAdmin(admin.ModelAdmin):  
    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
  • 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  
    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):
    def moderation_queue(request):  
    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)
  • django/core/urlresolvers.py

    diff --git a/django/core/urlresolvers.py b/django/core/urlresolvers.py
    index 6fc5cfc..7e42c9f 100644
    a b def resolve(path, urlconf=None):  
    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:
  • django/template/defaulttags.py

    diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py
    index c08ecc4..6fb0b7a 100644
    a b class URLNode(Node):  
    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()])
    class URLNode(Node):  
    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:
    def url(parser, token):  
    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
  • docs/ref/contrib/admin/index.txt

    diff --git a/docs/ref/contrib/admin/index.txt b/docs/ref/contrib/admin/index.txt
    index 0dff313..420ef25 100644
    a b It possible to add additional views to the admin site in the same way one can  
    12351235add them to ``ModelAdmins``.  This by using the ``get_urls()`` method on an
    12361236AdminSite in the same way as `described above`__
    12371237
     1238.. note::
     1239    Any view you render that uses the admin templates, or extends the base
     1240    admin template should include in it's context a variable named
     1241    ``admin_site`` that contains the ``AdminSite`` instances name, which for
     1242    ``AdminSite`` instances exists at ``self.name`` and for ``ModelAdmin``
     1243    instances exists at ``self.admin_site.name``.
     1244
    12381245__ `get_urls(self)`_
     1246
     1247
     1248Reversing Admin URLs
     1249====================
     1250
     1251.. versionadded :: 1.1
     1252    Before Django 1.1 it wasn't possible to reverse admin URLs.  In addition
     1253    for this to work you need to be using the new Django 1.1 ``include()``
     1254    syntax for setting up admin URLs.
     1255
     1256The following are the url names, and parameters for ``AdminSite`` urls, all
     1257url names are prefixed with the ``AdminSite`` instace's name, followed by an
     1258underscore, so if an ``AdminSite`` was named ``"user_admin"`` it's urls names
     1259would be prefixed with ``"user_admin_"``, the default ``AdminSite``'s name is
     1260``''`` however it's names *do not* have the trailing underscore:
     1261
     1262    ======================  =============================== =============
     1263    Page                    URL name                        Parameters
     1264    ======================  =============================== =============
     1265    Index                   ``admin_index``
     1266    Logout                  ``admin_logout``
     1267    Password change         ``admin_password_change``
     1268    Password change done    ``admin_password_change_done``
     1269    i18n javascript         ``admin_jsi18n``
     1270    Application index page  ``admin_app_list``              ``app_label``
     1271    ======================  =============================== =============
     1272
     1273The remaining urls are for ``ModelAdmin`` instances, these too are all prefixed
     1274with the ``AdminSite``'s name(with the same caviets as the ``Adminsite``, and
     1275``app_label`` and ``model_name`` are the lowercase versions of the
     1276application's name and the model's name:
     1277
     1278    ======================  =====================================================   =============
     1279    Page                    URL name                                                Parameters
     1280    ======================  =====================================================   =============
     1281    Changelist              ``admin_{{ app_label }}_{{ model_name }}_changelist``
     1282    Add                     ``admin_{{ app_label }}_{{ model_name }}_add``
     1283    History                 ``admin_{{ app_label }}_{{ model_name }}_history``      ``object_id``
     1284    Delete                  ``admin_{{ app_label }}_{{ model_name }}_delete``       ``object_id``
     1285    Change                  ``admin_{{ app_label }}_{{ model_name }}_change``       ``object_id``
     1286    ======================  =====================================================   =============
     1287
  • tests/regressiontests/admin_views/tests.py

    diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py
    index ce63567..6b32d3b 100644
    a b class AdminViewBasicTest(TestCase):  
    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"
  • tests/urls.py

    diff --git a/tests/urls.py b/tests/urls.py
    index 6704829..31faea5 100644
    a b urlpatterns = patterns('',  
    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
Back to Top