diff options
| author | Christopher Long <indirecthit@gmail.com> | 2007-06-17 22:18:54 +0000 |
|---|---|---|
| committer | Christopher Long <indirecthit@gmail.com> | 2007-06-17 22:18:54 +0000 |
| commit | ae22b6d403dcf25098c77f0dfcf59ae58b186461 (patch) | |
| tree | c37fc631e99a7e4d909d6b6d236f495003731ea7 /django/contrib/admin/views | |
| parent | 0cf7bc439129c66df8d64601e885f83b256b4f25 (diff) | |
per-object-permissions: Merged to trunk [5486] NOTE: Not fully tested, will be working on this over the next few weeks.
git-svn-id: http://code.djangoproject.com/svn/django/branches/per-object-permissions@5488 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django/contrib/admin/views')
| -rw-r--r-- | django/contrib/admin/views/auth.py | 41 | ||||
| -rw-r--r-- | django/contrib/admin/views/decorators.py | 12 | ||||
| -rw-r--r-- | django/contrib/admin/views/doc.py | 9 | ||||
| -rw-r--r-- | django/contrib/admin/views/main.py | 62 | ||||
| -rw-r--r-- | django/contrib/admin/views/row_level_permissions.py | 3 |
5 files changed, 85 insertions, 42 deletions
diff --git a/django/contrib/admin/views/auth.py b/django/contrib/admin/views/auth.py index 52bf3bcde8..206e3eb7d4 100644 --- a/django/contrib/admin/views/auth.py +++ b/django/contrib/admin/views/auth.py @@ -1,10 +1,11 @@ from django.contrib.admin.views.decorators import staff_member_required -from django.contrib.auth.forms import UserCreationForm +from django.contrib.auth.forms import UserCreationForm, AdminPasswordChangeForm from django.contrib.auth.models import User from django.core.exceptions import PermissionDenied from django import oldforms, template -from django.shortcuts import render_to_response +from django.shortcuts import render_to_response, get_object_or_404 from django.http import HttpResponseRedirect +from django.utils.html import escape def user_add_stage(request): if not request.user.has_perm('auth.change_user'): @@ -16,7 +17,7 @@ def user_add_stage(request): if not errors: new_user = manipulator.save(new_data) msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': 'user', 'obj': new_user} - if request.POST.has_key("_addanother"): + if "_addanother" in request.POST: request.user.message_set.create(message=msg) return HttpResponseRedirect(request.path) else: @@ -28,7 +29,7 @@ def user_add_stage(request): return render_to_response('admin/auth/user/add_form.html', { 'title': _('Add user'), 'form': form, - 'is_popup': request.REQUEST.has_key('_popup'), + 'is_popup': '_popup' in request.REQUEST, 'add': True, 'change': False, 'has_add_permission': True, @@ -43,3 +44,35 @@ def user_add_stage(request): 'username_help_text': User._meta.get_field('username').help_text, }, context_instance=template.RequestContext(request)) user_add_stage = staff_member_required(user_add_stage) + +def user_change_password(request, id): + if not request.user.has_perm('auth.change_user'): + raise PermissionDenied + user = get_object_or_404(User, pk=id) + manipulator = AdminPasswordChangeForm(user) + if request.method == 'POST': + new_data = request.POST.copy() + errors = manipulator.get_validation_errors(new_data) + if not errors: + new_user = manipulator.save(new_data) + msg = _('Password changed successfully.') + request.user.message_set.create(message=msg) + return HttpResponseRedirect('..') + else: + errors = new_data = {} + form = oldforms.FormWrapper(manipulator, new_data, errors) + return render_to_response('admin/auth/user/change_password.html', { + 'title': _('Change password: %s') % escape(user.username), + 'form': form, + 'is_popup': '_popup' in request.REQUEST, + 'add': True, + 'change': False, + 'has_delete_permission': False, + 'has_change_permission': True, + 'has_absolute_url': False, + 'first_form_field_id': 'id_password1', + 'opts': User._meta, + 'original': user, + 'show_save': True, + }, context_instance=template.RequestContext(request)) +user_change_password = staff_member_required(user_change_password) diff --git a/django/contrib/admin/views/decorators.py b/django/contrib/admin/views/decorators.py index 9dfe651fe6..5389ca4dff 100644 --- a/django/contrib/admin/views/decorators.py +++ b/django/contrib/admin/views/decorators.py @@ -12,7 +12,7 @@ LOGIN_FORM_KEY = 'this_is_the_login_form' def _display_login_form(request, error_message=''): request.session.set_test_cookie() - if request.POST and request.POST.has_key('post_data'): + if request.POST and 'post_data' in request.POST: # User has failed login BUT has previously saved post data. post_data = request.POST['post_data'] elif request.POST: @@ -48,7 +48,7 @@ def staff_member_required(view_func): def _checklogin(request, *args, **kwargs): if request.user.is_authenticated() and request.user.is_staff: # The user is valid. Continue to the admin page. - if request.POST.has_key('post_data'): + if 'post_data' in request.POST: # User must have re-authenticated through a different window # or tab. request.POST = _decode_post_data(request.POST['post_data']) @@ -57,7 +57,7 @@ def staff_member_required(view_func): assert hasattr(request, 'session'), "The Django admin requires session middleware to be installed. Edit your MIDDLEWARE_CLASSES setting to insert 'django.contrib.sessions.middleware.SessionMiddleware'." # If this isn't already the login page, display it. - if not request.POST.has_key(LOGIN_FORM_KEY): + if LOGIN_FORM_KEY not in request.POST: if request.POST: message = _("Please log in again, because your session has expired. Don't worry: Your submission has been saved.") else: @@ -90,11 +90,9 @@ def staff_member_required(view_func): if user.is_active and user.is_staff: login(request, user) # TODO: set last_login with an event. - user.last_login = datetime.datetime.now() - user.save() - if request.POST.has_key('post_data'): + if 'post_data' in request.POST: post_data = _decode_post_data(request.POST['post_data']) - if post_data and not post_data.has_key(LOGIN_FORM_KEY): + if post_data and LOGIN_FORM_KEY not in post_data: # overwrite request.POST with the saved post_data, and continue request.POST = post_data request.user = user diff --git a/django/contrib/admin/views/doc.py b/django/contrib/admin/views/doc.py index 4b592acebd..6430252690 100644 --- a/django/contrib/admin/views/doc.py +++ b/django/contrib/admin/views/doc.py @@ -168,7 +168,7 @@ def model_detail(request, app_label, model_name): model = m break if model is None: - raise Http404, _("Model %r not found in app %r") % (model_name, app_label) + raise Http404, _("Model %(name)r not found in app %(label)r") % {'name': model_name, 'label': app_label} opts = model._meta @@ -180,7 +180,7 @@ def model_detail(request, app_label, model_name): if isinstance(field, models.ForeignKey): data_type = related_object_name = field.rel.to.__name__ app_label = field.rel.to._meta.app_label - verbose = utils.parse_rst((_("the related `%s.%s` object") % (app_label, data_type)), 'model', _('model:') + data_type) + verbose = utils.parse_rst((_("the related `%(label)s.%(type)s` object") % {'label': app_label, 'type': data_type}), 'model', _('model:') + data_type) else: data_type = get_readable_field_data_type(field) verbose = field.verbose_name @@ -211,7 +211,7 @@ def model_detail(request, app_label, model_name): # Gather related objects for rel in opts.get_all_related_objects(): - verbose = _("related `%s.%s` objects") % (rel.opts.app_label, rel.opts.object_name) + verbose = _("related `%(label)s.%(name)s` objects") % {'label': rel.opts.app_label, 'name': rel.opts.object_name} accessor = rel.get_accessor_name() fields.append({ 'name' : "%s.all" % accessor, @@ -294,10 +294,11 @@ DATA_TYPE_MAPPING = { 'CommaSeparatedIntegerField': _('Comma-separated integers'), 'DateField' : _('Date (without time)'), 'DateTimeField' : _('Date (with time)'), + 'DecimalField' : _('Decimal number'), 'EmailField' : _('E-mail address'), 'FileField' : _('File path'), 'FilePathField' : _('File path'), - 'FloatField' : _('Decimal number'), + 'FloatField' : _('Floating point number'), 'ForeignKey' : _('Integer'), 'ImageField' : _('File path'), 'IntegerField' : _('Integer'), diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py index aa8b35bb96..1e99ea341b 100644 --- a/django/contrib/admin/views/main.py +++ b/django/contrib/admin/views/main.py @@ -46,8 +46,8 @@ def quote(s): """ Ensure that primary key values do not confuse the admin URLs by escaping any '/', '_' and ':' characters. Similar to urllib.quote, except that the - quoting is slightly different so that it doesn't get autoamtically - unquoted by the web browser. + quoting is slightly different so that it doesn't get automatically + unquoted by the Web browser. """ if type(s) != type(''): return s @@ -273,17 +273,17 @@ def add_stage(request, app_label, model_name, show_delete=False, form_url='', po delete=admin_opts.grant_delete_row_level_perm) # Here, we distinguish between different save types by checking for # the presence of keys in request.POST. - if request.POST.has_key("_continue"): + if "_continue" in request.POST: request.user.message_set.create(message=msg + ' ' + _("You may edit it again below.")) - if request.POST.has_key("_popup"): + if "_popup" in request.POST: post_url_continue += "?_popup=1" return HttpResponseRedirect(post_url_continue % pk_value) - if request.POST.has_key("_popup"): + if "_popup" in request.POST: if type(pk_value) is str: # Quote if string, so JavaScript doesn't think it's a variable. pk_value = '"%s"' % pk_value.replace('"', '\\"') return HttpResponse('<script type="text/javascript">opener.dismissAddAnotherPopup(window, %s, "%s");</script>' % \ (pk_value, str(new_object).replace('"', '\\"'))) - elif request.POST.has_key("_addanother"): + elif "_addanother" in request.POST: request.user.message_set.create(message=msg + ' ' + (_("You may add another %s below.") % opts.verbose_name)) return HttpResponseRedirect(request.path) else: @@ -304,7 +304,7 @@ def add_stage(request, app_label, model_name, show_delete=False, form_url='', po c = template.RequestContext(request, { 'title': _('Add %s') % opts.verbose_name, 'form': form, - 'is_popup': request.REQUEST.has_key('_popup'), + 'is_popup': '_popup' in request.REQUEST, 'show_delete': show_delete, }) @@ -329,7 +329,7 @@ def change_stage(request, app_label, model_name, object_id): if not request.user.has_perm(app_label + '.' + opts.get_change_permission(), object=manipulator.original_object): raise PermissionDenied - if request.POST and request.POST.has_key("_saveasnew"): + if request.POST and "_saveasnew" in request.POST: return add_stage(request, app_label, model_name, form_url='../../add/') if request.POST: @@ -367,16 +367,16 @@ def change_stage(request, app_label, model_name, object_id): delete=admin_opts.grant_delete_row_level_perm) msg = _('The %(name)s "%(obj)s" was changed successfully.') % {'name': opts.verbose_name, 'obj': new_object} - if request.POST.has_key("_continue"): + if "_continue" in request.POST: request.user.message_set.create(message=msg + ' ' + _("You may edit it again below.")) - if request.REQUEST.has_key('_popup'): + if '_popup' in request.REQUEST: return HttpResponseRedirect(request.path + "?_popup=1") else: return HttpResponseRedirect(request.path) - elif request.POST.has_key("_saveasnew"): + elif "_saveasnew" in request.POST: request.user.message_set.create(message=_('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % {'name': opts.verbose_name, 'obj': new_object}) return HttpResponseRedirect("../%s/" % pk_value) - elif request.POST.has_key("_addanother"): + elif "_addanother" in request.POST: request.user.message_set.create(message=msg + ' ' + (_("You may add another %s below.") % opts.verbose_name)) return HttpResponseRedirect("../add/") else: @@ -416,7 +416,7 @@ def change_stage(request, app_label, model_name, object_id): 'form': form, 'object_id': object_id, 'original': manipulator.original_object, - 'is_popup': request.REQUEST.has_key('_popup'), + 'is_popup': '_popup' in request.REQUEST, 'object_has_row_level_permissions':opts.row_level_permissions, 'has_row_level_permissions':request.user.has_perm("auth.change_rowlevelpermission") and request.user.has_perm(opts.app_label+"."+opts.get_change_permission(), object=manipulator.original_object), }) @@ -488,9 +488,12 @@ def _get_deleted_objects(deleted_objects, perms_needed, user, obj, opts, current opts_seen.append(related.opts) rel_opts_name = related.get_accessor_name() has_related_objs = False - rel_objs = getattr(obj, rel_opts_name, None) - if rel_objs: - has_related_objs = True + + # related.get_accessor_name() could return None for symmetrical relationships + if rel_opts_name: + rel_objs = getattr(obj, rel_opts_name, None) + if rel_objs: + has_related_objs = True if has_related_objs: for sub_obj in rel_objs.all(): @@ -585,12 +588,12 @@ class ChangeList(object): self.page_num = int(request.GET.get(PAGE_VAR, 0)) except ValueError: self.page_num = 0 - self.show_all = request.GET.has_key(ALL_VAR) - self.is_popup = request.GET.has_key(IS_POPUP_VAR) + self.show_all = ALL_VAR in request.GET + self.is_popup = IS_POPUP_VAR in request.GET self.params = dict(request.GET.items()) - if self.params.has_key(PAGE_VAR): + if PAGE_VAR in self.params: del self.params[PAGE_VAR] - if self.params.has_key(ERROR_FLAG): + if ERROR_FLAG in self.params: del self.params[ERROR_FLAG] self.order_field, self.order_type = self.get_ordering() @@ -621,7 +624,7 @@ class ChangeList(object): if k.startswith(r): del p[k] for k, v in new_params.items(): - if p.has_key(k) and v is None: + if k in p and v is None: del p[k] elif v is not None: p[k] = v @@ -687,18 +690,25 @@ class ChangeList(object): order_field, order_type = ordering[0][1:], 'desc' else: order_field, order_type = ordering[0], 'asc' - if params.has_key(ORDER_VAR): + if ORDER_VAR in params: try: + field_name = lookup_opts.admin.list_display[int(params[ORDER_VAR])] try: - f = lookup_opts.get_field(lookup_opts.admin.list_display[int(params[ORDER_VAR])]) + f = lookup_opts.get_field(field_name) except models.FieldDoesNotExist: - pass + # see if field_name is a name of a non-field + # that allows sorting + try: + attr = getattr(lookup_opts.admin.manager.model, field_name) + order_field = attr.admin_order_field + except IndexError: + pass else: if not isinstance(f.rel, models.ManyToOneRel) or not f.null: order_field = f.name except (IndexError, ValueError): pass # Invalid ordering specified. Just use the default. - if params.has_key(ORDER_TYPE_VAR) and params[ORDER_TYPE_VAR] in ('asc', 'desc'): + if ORDER_TYPE_VAR in params and params[ORDER_TYPE_VAR] in ('asc', 'desc'): order_type = params[ORDER_TYPE_VAR] return order_field, order_type @@ -715,7 +725,7 @@ class ChangeList(object): qs = self.manager.get_query_set() lookup_params = self.params.copy() # a dictionary of the query string for i in (ALL_VAR, ORDER_VAR, ORDER_TYPE_VAR, SEARCH_VAR, IS_POPUP_VAR): - if lookup_params.has_key(i): + if i in lookup_params: del lookup_params[i] # Apply lookup parameters from the query string. diff --git a/django/contrib/admin/views/row_level_permissions.py b/django/contrib/admin/views/row_level_permissions.py index a5ea239b51..e9bda73217 100644 --- a/django/contrib/admin/views/row_level_permissions.py +++ b/django/contrib/admin/views/row_level_permissions.py @@ -1,5 +1,6 @@ from django.contrib.admin import utils -from django import forms, template +from django import oldforms as forms +from django import template from django.shortcuts import render_to_response, get_object_or_404 from django.http import Http404, HttpResponse, HttpResponseRedirect from django.contrib.contenttypes.models import ContentType |
