web/lib/django/contrib/admin/sites.py
changeset 29 cc9b7e14412b
parent 0 0d40e90630ef
equal deleted inserted replaced
28:b758351d191f 29:cc9b7e14412b
     1 import re
     1 import re
     2 from django import http, template
     2 from django import http, template
     3 from django.contrib.admin import ModelAdmin
     3 from django.contrib.admin import ModelAdmin
     4 from django.contrib.admin import actions
     4 from django.contrib.admin import actions
     5 from django.contrib.auth import authenticate, login
     5 from django.contrib.auth import authenticate, login
       
     6 from django.views.decorators.csrf import csrf_protect
     6 from django.db.models.base import ModelBase
     7 from django.db.models.base import ModelBase
     7 from django.core.exceptions import ImproperlyConfigured
     8 from django.core.exceptions import ImproperlyConfigured
     8 from django.core.urlresolvers import reverse
     9 from django.core.urlresolvers import reverse
     9 from django.shortcuts import render_to_response
    10 from django.shortcuts import render_to_response
    10 from django.utils.functional import update_wrapper
    11 from django.utils.functional import update_wrapper
    11 from django.utils.safestring import mark_safe
    12 from django.utils.safestring import mark_safe
    12 from django.utils.text import capfirst
    13 from django.utils.text import capfirst
    13 from django.utils.translation import ugettext_lazy, ugettext as _
    14 from django.utils.translation import ugettext_lazy, ugettext as _
    14 from django.views.decorators.cache import never_cache
    15 from django.views.decorators.cache import never_cache
    15 from django.conf import settings
    16 from django.conf import settings
    16 try:
       
    17     set
       
    18 except NameError:
       
    19     from sets import Set as set     # Python 2.3 fallback
       
    20 
    17 
    21 ERROR_MESSAGE = ugettext_lazy("Please enter a correct username and password. Note that both fields are case-sensitive.")
    18 ERROR_MESSAGE = ugettext_lazy("Please enter a correct username and password. Note that both fields are case-sensitive.")
    22 LOGIN_FORM_KEY = 'this_is_the_login_form'
    19 LOGIN_FORM_KEY = 'this_is_the_login_form'
    23 
    20 
    24 class AlreadyRegistered(Exception):
    21 class AlreadyRegistered(Exception):
    34     register() method, and the root() method can then be used as a Django view function
    31     register() method, and the root() method can then be used as a Django view function
    35     that presents a full admin interface for the collection of registered models.
    32     that presents a full admin interface for the collection of registered models.
    36     """
    33     """
    37 
    34 
    38     index_template = None
    35     index_template = None
       
    36     app_index_template = None
    39     login_template = None
    37     login_template = None
    40     app_index_template = None
    38     logout_template = None
       
    39     password_change_template = None
       
    40     password_change_done_template = None
    41 
    41 
    42     def __init__(self, name=None, app_name='admin'):
    42     def __init__(self, name=None, app_name='admin'):
    43         self._registry = {} # model_class class -> admin_class instance
    43         self._registry = {} # model_class class -> admin_class instance
    44         self.root_path = None
    44         self.root_path = None
    45         if name is None:
    45         if name is None:
   136     def has_permission(self, request):
   136     def has_permission(self, request):
   137         """
   137         """
   138         Returns True if the given HttpRequest has permission to view
   138         Returns True if the given HttpRequest has permission to view
   139         *at least one* page in the admin site.
   139         *at least one* page in the admin site.
   140         """
   140         """
   141         return request.user.is_authenticated() and request.user.is_staff
   141         return request.user.is_active and request.user.is_staff
   142 
   142 
   143     def check_dependencies(self):
   143     def check_dependencies(self):
   144         """
   144         """
   145         Check that all things needed to run the admin have been correctly installed.
   145         Check that all things needed to run the admin have been correctly installed.
   146 
   146 
   149         """
   149         """
   150         from django.contrib.admin.models import LogEntry
   150         from django.contrib.admin.models import LogEntry
   151         from django.contrib.contenttypes.models import ContentType
   151         from django.contrib.contenttypes.models import ContentType
   152 
   152 
   153         if not LogEntry._meta.installed:
   153         if not LogEntry._meta.installed:
   154             raise ImproperlyConfigured("Put 'django.contrib.admin' in your INSTALLED_APPS setting in order to use the admin application.")
   154             raise ImproperlyConfigured("Put 'django.contrib.admin' in your "
       
   155                 "INSTALLED_APPS setting in order to use the admin application.")
   155         if not ContentType._meta.installed:
   156         if not ContentType._meta.installed:
   156             raise ImproperlyConfigured("Put 'django.contrib.contenttypes' in your INSTALLED_APPS setting in order to use the admin application.")
   157             raise ImproperlyConfigured("Put 'django.contrib.contenttypes' in "
   157         if 'django.core.context_processors.auth' not in settings.TEMPLATE_CONTEXT_PROCESSORS:
   158                 "your INSTALLED_APPS setting in order to use the admin application.")
   158             raise ImproperlyConfigured("Put 'django.core.context_processors.auth' in your TEMPLATE_CONTEXT_PROCESSORS setting in order to use the admin application.")
   159         if not ('django.contrib.auth.context_processors.auth' in settings.TEMPLATE_CONTEXT_PROCESSORS or
       
   160             'django.core.context_processors.auth' in settings.TEMPLATE_CONTEXT_PROCESSORS):
       
   161             raise ImproperlyConfigured("Put 'django.contrib.auth.context_processors.auth' "
       
   162                 "in your TEMPLATE_CONTEXT_PROCESSORS setting in order to use the admin application.")
   159 
   163 
   160     def admin_view(self, view, cacheable=False):
   164     def admin_view(self, view, cacheable=False):
   161         """
   165         """
   162         Decorator to create an admin view attached to this ``AdminSite``. This
   166         Decorator to create an admin view attached to this ``AdminSite``. This
   163         wraps the view and provides permission checking by calling
   167         wraps the view and provides permission checking by calling
   184             if not self.has_permission(request):
   188             if not self.has_permission(request):
   185                 return self.login(request)
   189                 return self.login(request)
   186             return view(request, *args, **kwargs)
   190             return view(request, *args, **kwargs)
   187         if not cacheable:
   191         if not cacheable:
   188             inner = never_cache(inner)
   192             inner = never_cache(inner)
       
   193         # We add csrf_protect here so this function can be used as a utility
       
   194         # function for any view, without having to repeat 'csrf_protect'.
       
   195         if not getattr(view, 'csrf_exempt', False):
       
   196             inner = csrf_protect(inner)
   189         return update_wrapper(inner, view)
   197         return update_wrapper(inner, view)
   190 
   198 
   191     def get_urls(self):
   199     def get_urls(self):
   192         from django.conf.urls.defaults import patterns, url, include
   200         from django.conf.urls.defaults import patterns, url, include
       
   201 
       
   202         if settings.DEBUG:
       
   203             self.check_dependencies()
   193 
   204 
   194         def wrap(view, cacheable=False):
   205         def wrap(view, cacheable=False):
   195             def wrapper(*args, **kwargs):
   206             def wrapper(*args, **kwargs):
   196                 return self.admin_view(view, cacheable)(*args, **kwargs)
   207                 return self.admin_view(view, cacheable)(*args, **kwargs)
   197             return update_wrapper(wrapper, view)
   208             return update_wrapper(wrapper, view)
   239         from django.contrib.auth.views import password_change
   250         from django.contrib.auth.views import password_change
   240         if self.root_path is not None:
   251         if self.root_path is not None:
   241             url = '%spassword_change/done/' % self.root_path
   252             url = '%spassword_change/done/' % self.root_path
   242         else:
   253         else:
   243             url = reverse('admin:password_change_done', current_app=self.name)
   254             url = reverse('admin:password_change_done', current_app=self.name)
   244         return password_change(request, post_change_redirect=url)
   255         defaults = {
       
   256             'post_change_redirect': url
       
   257         }
       
   258         if self.password_change_template is not None:
       
   259             defaults['template_name'] = self.password_change_template
       
   260         return password_change(request, **defaults)
   245 
   261 
   246     def password_change_done(self, request):
   262     def password_change_done(self, request):
   247         """
   263         """
   248         Displays the "success" page after a password change.
   264         Displays the "success" page after a password change.
   249         """
   265         """
   250         from django.contrib.auth.views import password_change_done
   266         from django.contrib.auth.views import password_change_done
   251         return password_change_done(request)
   267         defaults = {}
       
   268         if self.password_change_done_template is not None:
       
   269             defaults['template_name'] = self.password_change_done_template
       
   270         return password_change_done(request, **defaults)
   252 
   271 
   253     def i18n_javascript(self, request):
   272     def i18n_javascript(self, request):
   254         """
   273         """
   255         Displays the i18n JavaScript that the Django admin requires.
   274         Displays the i18n JavaScript that the Django admin requires.
   256 
   275 
   268         Logs out the user for the given HttpRequest.
   287         Logs out the user for the given HttpRequest.
   269 
   288 
   270         This should *not* assume the user is already logged in.
   289         This should *not* assume the user is already logged in.
   271         """
   290         """
   272         from django.contrib.auth.views import logout
   291         from django.contrib.auth.views import logout
   273         return logout(request)
   292         defaults = {}
       
   293         if self.logout_template is not None:
       
   294             defaults['template_name'] = self.logout_template
       
   295         return logout(request, **defaults)
   274     logout = never_cache(logout)
   296     logout = never_cache(logout)
   275 
   297 
   276     def login(self, request):
   298     def login(self, request):
   277         """
   299         """
   278         Displays the login form for the given HttpRequest.
   300         Displays the login form for the given HttpRequest.
   443         removed in Django 1.3.
   465         removed in Django 1.3.
   444         """
   466         """
   445         import warnings
   467         import warnings
   446         warnings.warn(
   468         warnings.warn(
   447             "AdminSite.root() is deprecated; use include(admin.site.urls) instead.",
   469             "AdminSite.root() is deprecated; use include(admin.site.urls) instead.",
   448             PendingDeprecationWarning
   470             DeprecationWarning
   449         )
   471         )
   450 
   472 
   451         #
   473         #
   452         # Again, remember that the following only exists for
   474         # Again, remember that the following only exists for
   453         # backwards-compatibility. Any new URLs, changes to existing URLs, or
   475         # backwards-compatibility. Any new URLs, changes to existing URLs, or