42 | | class AdminSite(object): |
| 42 | class instance_decorator(object): |
| 43 | ''' |
| 44 | Applies one or more decorators to the given instance method. |
| 45 | |
| 46 | Normal decorators do not work well within class definitions, |
| 47 | because the decorated function will be passed the `self` |
| 48 | parameter. This descriptor avoids that problem by decorating the |
| 49 | function after it has been bound as an instance method. |
| 50 | ''' |
| 51 | def __init__(self, *decorators): |
| 52 | self._decorators = decorators |
| 53 | |
| 54 | def __get__(self, instance, owner): |
| 55 | f = new.instancemethod(self.f, instance, owner) |
| 56 | for dec in self._decorators: |
| 57 | f = dec(f) |
| 58 | return f |
| 59 | |
| 60 | def __call__(self, f): |
| 61 | self.f = f |
| 62 | return self |
| 63 | |
| 64 | |
| 65 | def _has_permission(request): |
90 | | def has_permission(self, request): |
91 | | """ |
92 | | Returns True if the given HttpRequest has permission to view |
93 | | *at least one* page in the admin site. |
94 | | """ |
95 | | return request.user.is_authenticated() and request.user.is_staff |
| 122 | def get_url_patterns(self): |
| 123 | # FIXME: I don't know how to handle the "show in web" links |
| 124 | return [ |
| 125 | url(r'^logout/$', self.logout), |
| 126 | url(r'^$', self.index), |
| 127 | url(r'^password_change/$', self.password_change), |
| 128 | url(r'^password_change/done/$', self.password_change_done), |
| 129 | url(r'jsi18n/$', self.i18n_javascript) |
| 130 | ] |
97 | | def root(self, request, url): |
98 | | """ |
99 | | Handles main URL routing for the admin app. |
100 | | |
101 | | `url` is the remainder of the URL -- e.g. 'comments/comment/'. |
102 | | """ |
103 | | # Figure out the admin base URL path and stash it for later use |
104 | | self.root_path = re.sub(re.escape(url) + '$', '', request.path) |
105 | | |
106 | | url = url.rstrip('/') # Trim trailing slash, if it exists. |
107 | | |
108 | | # The 'logout' view doesn't require that the person is logged in. |
109 | | if url == 'logout': |
110 | | return self.logout(request) |
111 | | |
112 | | if not self.has_permission(request): |
113 | | response = self.login(request) |
114 | | if response: |
115 | | # make sure that there is a response before returning |
116 | | # this addresses any post data that might persist from |
117 | | # expired sessions and continue through (#5999) |
118 | | return response |
119 | | |
120 | | if url == '': |
121 | | return self.index(request) |
122 | | elif url == 'password_change': |
123 | | return self.password_change(request) |
124 | | elif url == 'password_change/done': |
125 | | return self.password_change_done(request) |
126 | | elif url == 'jsi18n': |
127 | | return self.i18n_javascript(request) |
128 | | # urls starting with 'r/' are for the "show in web" links |
129 | | elif url.startswith('r/'): |
130 | | from django.views.defaults import shortcut |
131 | | return shortcut(request, *url.split('/')[1:]) |
132 | | else: |
133 | | match = USER_CHANGE_PASSWORD_URL_RE.match(url) |
134 | | if match: |
135 | | return self.user_change_password(request, match.group(1)) |
136 | | |
137 | | if '/' in url: |
138 | | return self.model_page(request, *url.split('/', 2)) |
139 | | |
140 | | raise http.Http404('The requested admin page does not exist.') |
141 | | |