Ticket #20642: 0001-Fixed-20642-Deprecated-Option.get_-add-change-delete.patch

File 0001-Fixed-20642-Deprecated-Option.get_-add-change-delete.patch, 18.5 KB (added by Simon Charette, 11 years ago)

Patch with doc

  • django/contrib/admin/options.py

    From 1fab275061c992c07abc68b1d0f100e9099f967f Mon Sep 17 00:00:00 2001
    From: Simon Charette <charette.s@gmail.com>
    Date: Sat, 22 Jun 2013 21:48:09 -0400
    Subject: [PATCH] Fixed #20642 -- Deprecated
     `Option.get_(add|change|delete)_permission`.
    
    Those methods were only used by `contrib.admin` internally and exclusively
    related to `contrib.auth`. Since they were undocumented but used
    in the wild the raised deprecation warning point to an also undocumented
    alternative that lives in `contrib.auth`.
    
    Also did some PEP8 and other cleanups in the affected modules.
    ---
     django/contrib/admin/options.py            | 100 ++++++++++++++++-------------
     django/contrib/auth/__init__.py            |  15 ++++-
     django/contrib/auth/management/__init__.py |  12 ++--
     django/db/models/options.py                |  24 +++++++
     docs/releases/1.6.txt                      |   7 ++
     5 files changed, 106 insertions(+), 52 deletions(-)
    
    diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
    index e9f4a43..c89dde5 100644
    a b from functools import partial, reduce, update_wrapper  
    44
    55from django import forms
    66from django.conf import settings
    7 from django.forms.formsets import all_valid, DELETION_FIELD_NAME
    8 from django.forms.models import (modelform_factory, modelformset_factory,
    9     inlineformset_factory, BaseInlineFormSet, modelform_defines_fields)
    10 from django.contrib.contenttypes.models import ContentType
     7from django.contrib import messages
    118from django.contrib.admin import widgets, helpers
    129from django.contrib.admin.util import (unquote, flatten_fieldsets, get_deleted_objects,
    1310    model_format_dict, NestedObjects, lookup_needs_distinct)
    1411from django.contrib.admin import validation
    1512from django.contrib.admin.templatetags.admin_static import static
    1613from django.contrib.admin.templatetags.admin_urls import add_preserved_filters
    17 from django.contrib import messages
    18 from django.views.decorators.csrf import csrf_protect
     14from django.contrib.auth import get_permission_codename
     15from django.contrib.contenttypes.models import ContentType
    1916from django.core.exceptions import PermissionDenied, ValidationError, FieldError
    2017from django.core.paginator import Paginator
    2118from django.core.urlresolvers import reverse
    from django.db.models.constants import LOOKUP_SEP  
    2421from django.db.models.related import RelatedObject
    2522from django.db.models.fields import BLANK_CHOICE_DASH, FieldDoesNotExist
    2623from django.db.models.sql.constants import QUERY_TERMS
     24from django.forms.formsets import all_valid, DELETION_FIELD_NAME
     25from django.forms.models import (modelform_factory, modelformset_factory,
     26    inlineformset_factory, BaseInlineFormSet, modelform_defines_fields)
    2727from django.http import Http404, HttpResponse, HttpResponseRedirect
    2828from django.http.response import HttpResponseBase
    2929from django.shortcuts import get_object_or_404
    from django.utils.text import capfirst, get_text_list  
    3939from django.utils.translation import ugettext as _
    4040from django.utils.translation import ungettext
    4141from django.utils.encoding import force_text
     42from django.views.decorators.csrf import csrf_protect
     43
    4244
    4345IS_POPUP_VAR = '_popup'
    4446
    FORMFIELD_FOR_DBFIELD_DEFAULTS = {  
    5860        'form_class': forms.SplitDateTimeField,
    5961        'widget': widgets.AdminSplitDateTime
    6062    },
    61     models.DateField:       {'widget': widgets.AdminDateWidget},
    62     models.TimeField:       {'widget': widgets.AdminTimeWidget},
    63     models.TextField:       {'widget': widgets.AdminTextareaWidget},
    64     models.URLField:        {'widget': widgets.AdminURLFieldWidget},
    65     models.IntegerField:    {'widget': widgets.AdminIntegerFieldWidget},
     63    models.DateField: {'widget': widgets.AdminDateWidget},
     64    models.TimeField: {'widget': widgets.AdminTimeWidget},
     65    models.TextField: {'widget': widgets.AdminTextareaWidget},
     66    models.URLField: {'widget': widgets.AdminURLFieldWidget},
     67    models.IntegerField: {'widget': widgets.AdminIntegerFieldWidget},
    6668    models.BigIntegerField: {'widget': widgets.AdminBigIntegerFieldWidget},
    67     models.CharField:       {'widget': widgets.AdminTextInputWidget},
    68     models.ImageField:      {'widget': widgets.AdminFileWidget},
    69     models.FileField:       {'widget': widgets.AdminFileWidget},
     69    models.CharField: {'widget': widgets.AdminTextInputWidget},
     70    models.ImageField: {'widget': widgets.AdminFileWidget},
     71    models.FileField: {'widget': widgets.AdminFileWidget},
    7072}
    7173
    7274csrf_protect_m = method_decorator(csrf_protect)
    class BaseModelAdmin(six.with_metaclass(RenameBaseModelAdminMethods)):  
    352354        Can be overridden by the user in subclasses.
    353355        """
    354356        opts = self.opts
    355         return request.user.has_perm(opts.app_label + '.' + opts.get_add_permission())
     357        codename = get_permission_codename('add', opts)
     358        return request.user.has_perm("%s.%s" % (opts.app_label, codename))
    356359
    357360    def has_change_permission(self, request, obj=None):
    358361        """
    class BaseModelAdmin(six.with_metaclass(RenameBaseModelAdminMethods)):  
    366369        request has permission to change *any* object of the given type.
    367370        """
    368371        opts = self.opts
    369         return request.user.has_perm(opts.app_label + '.' + opts.get_change_permission())
     372        codename = get_permission_codename('change', opts)
     373        return request.user.has_perm("%s.%s" % (opts.app_label, codename))
    370374
    371375    def has_delete_permission(self, request, obj=None):
    372376        """
    class BaseModelAdmin(six.with_metaclass(RenameBaseModelAdminMethods)):  
    380384        request has permission to delete *any* object of the given type.
    381385        """
    382386        opts = self.opts
    383         return request.user.has_perm(opts.app_label + '.' + opts.get_delete_permission())
     387        codename = get_permission_codename('delete', opts)
     388        return request.user.has_perm("%s.%s" % (opts.app_label, codename))
     389
    384390
    385391class ModelAdmin(BaseModelAdmin):
    386392    "Encapsulates all admin options and functionality for a given model."
    class ModelAdmin(BaseModelAdmin):  
    608614        """
    609615        from django.contrib.admin.models import LogEntry, ADDITION
    610616        LogEntry.objects.log_action(
    611             user_id         = request.user.pk,
    612             content_type_id = ContentType.objects.get_for_model(object).pk,
    613             object_id       = object.pk,
    614             object_repr     = force_text(object),
    615             action_flag     = ADDITION
     617            user_id=request.user.pk,
     618            content_type_id=ContentType.objects.get_for_model(object).pk,
     619            object_id=object.pk,
     620            object_repr=force_text(object),
     621            action_flag=ADDITION
    616622        )
    617623
    618624    def log_change(self, request, object, message):
    class ModelAdmin(BaseModelAdmin):  
    623629        """
    624630        from django.contrib.admin.models import LogEntry, CHANGE
    625631        LogEntry.objects.log_action(
    626             user_id         = request.user.pk,
    627             content_type_id = ContentType.objects.get_for_model(object).pk,
    628             object_id       = object.pk,
    629             object_repr     = force_text(object),
    630             action_flag     = CHANGE,
    631             change_message  = message
     632            user_id=request.user.pk,
     633            content_type_id=ContentType.objects.get_for_model(object).pk,
     634            object_id=object.pk,
     635            object_repr=force_text(object),
     636            action_flag=CHANGE,
     637            change_message=message
    632638        )
    633639
    634640    def log_deletion(self, request, object, object_repr):
    class ModelAdmin(BaseModelAdmin):  
    640646        """
    641647        from django.contrib.admin.models import LogEntry, DELETION
    642648        LogEntry.objects.log_action(
    643             user_id         = request.user.pk,
    644             content_type_id = ContentType.objects.get_for_model(self.model).pk,
    645             object_id       = object.pk,
    646             object_repr     = object_repr,
    647             action_flag     = DELETION
     649            user_id=request.user.pk,
     650            content_type_id=ContentType.objects.get_for_model(self.model).pk,
     651            object_id=object.pk,
     652            object_repr=object_repr,
     653            action_flag=DELETION
    648654        )
    649655
    650656    def action_checkbox(self, obj):
    class ModelAdmin(BaseModelAdmin):  
    880886            'has_add_permission': self.has_add_permission(request),
    881887            'has_change_permission': self.has_change_permission(request, obj),
    882888            'has_delete_permission': self.has_delete_permission(request, obj),
    883             'has_file_field': True, # FIXME - this should check if form or formsets have a FileField,
     889            'has_file_field': True,  # FIXME - this should check if form or formsets have a FileField,
    884890            'has_absolute_url': hasattr(self.model, 'get_absolute_url'),
    885891            'form_url': form_url,
    886892            'opts': opts,
    class ModelAdmin(BaseModelAdmin):  
    10511057        if action_form.is_valid():
    10521058            action = action_form.cleaned_data['action']
    10531059            select_across = action_form.cleaned_data['select_across']
    1054             func, name, description = self.get_actions(request)[action]
     1060            func = self.get_actions(request)[action][0]
    10551061
    10561062            # Get the list of selected PKs. If nothing's selected, we can't
    10571063            # perform an action on it, so bail. Except we want to perform
    class ModelAdmin(BaseModelAdmin):  
    12821288        actions = self.get_actions(request)
    12831289        if actions:
    12841290            # Add the action checkboxes if there are any actions available.
    1285             list_display = ['action_checkbox'] +  list(list_display)
     1291            list_display = ['action_checkbox'] + list(list_display)
    12861292
    12871293        ChangeList = self.get_changelist(request)
    12881294        try:
    class ModelAdmin(BaseModelAdmin):  
    14311437            raise PermissionDenied
    14321438
    14331439        if obj is None:
    1434             raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % {'name': force_text(opts.verbose_name), 'key': escape(object_id)})
     1440            raise Http404(
     1441                _('%(name)s object with primary key %(key)r does not exist.') %
     1442                    {'name': force_text(opts.verbose_name), 'key': escape(object_id)}
     1443            )
    14351444
    14361445        using = router.db_for_write(self.model)
    14371446
    class ModelAdmin(BaseModelAdmin):  
    14401449        (deleted_objects, perms_needed, protected) = get_deleted_objects(
    14411450            [obj], opts, request.user, self.admin_site, using)
    14421451
    1443         if request.POST: # The user has already confirmed the deletion.
     1452        if request.POST:  # The user has already confirmed the deletion.
    14441453            if perms_needed:
    14451454                raise PermissionDenied
    14461455            obj_display = force_text(obj)
    class ModelAdmin(BaseModelAdmin):  
    14581467                                   (opts.app_label, opts.model_name),
    14591468                                   current_app=self.admin_site.name)
    14601469                preserved_filters = self.get_preserved_filters(request)
    1461                 post_url = add_preserved_filters({'preserved_filters': preserved_filters, 'opts': opts}, post_url)
     1470                post_url = add_preserved_filters(
     1471                    {'preserved_filters': preserved_filters, 'opts': opts}, post_url
     1472                )
    14621473            else:
    14631474                post_url = reverse('admin:index',
    14641475                                   current_app=self.admin_site.name)
    class ModelAdmin(BaseModelAdmin):  
    15241535            "admin/object_history.html"
    15251536        ], context, current_app=self.admin_site.name)
    15261537
     1538
    15271539class InlineModelAdmin(BaseModelAdmin):
    15281540    """
    15291541    Options for inline editing of ``model`` instances.
    class InlineModelAdmin(BaseModelAdmin):  
    16671679            # to have the change permission for the related model in order to
    16681680            # be able to do anything with the intermediate model.
    16691681            return self.has_change_permission(request)
    1670         return request.user.has_perm(
    1671             self.opts.app_label + '.' + self.opts.get_add_permission())
     1682        return super(InlineModelAdmin, self).has_add_permission(request)
    16721683
    16731684    def has_change_permission(self, request, obj=None):
    16741685        opts = self.opts
    class InlineModelAdmin(BaseModelAdmin):  
    16791690                if field.rel and field.rel.to != self.parent_model:
    16801691                    opts = field.rel.to._meta
    16811692                    break
    1682         return request.user.has_perm(
    1683             opts.app_label + '.' + opts.get_change_permission())
     1693        codename = get_permission_codename('change', opts)
     1694        return request.user.has_perm("%s.%s" % (opts.app_label, codename))
    16841695
    16851696    def has_delete_permission(self, request, obj=None):
    16861697        if self.opts.auto_created:
    class InlineModelAdmin(BaseModelAdmin):  
    16891700            # to have the change permission for the related model in order to
    16901701            # be able to do anything with the intermediate model.
    16911702            return self.has_change_permission(request, obj)
    1692         return request.user.has_perm(
    1693             self.opts.app_label + '.' + self.opts.get_delete_permission())
     1703        return super(InlineModelAdmin, self).has_delete_permission(request, obj)
    16941704
    16951705
    16961706class StackedInline(InlineModelAdmin):
  • django/contrib/auth/__init__.py

    diff --git a/django/contrib/auth/__init__.py b/django/contrib/auth/__init__.py
    index 029193d..2f620a3 100644
    a b def logout(request):  
    108108
    109109
    110110def get_user_model():
    111     "Return the User model that is active in this project"
     111    """
     112    Returns the User model that is active in this project.
     113    """
    112114    from django.db.models import get_model
    113115
    114116    try:
    def get_user_model():  
    122124
    123125
    124126def get_user(request):
     127    """
     128    Returns the user model instance associated with the given request session.
     129    If no user is retrieved an instance of `AnonymousUser` is returned.
     130    """
    125131    from .models import AnonymousUser
    126132    try:
    127133        user_id = request.session[SESSION_KEY]
    def get_user(request):  
    132138    except (KeyError, AssertionError):
    133139        user = AnonymousUser()
    134140    return user
     141
     142
     143def get_permission_codename(action, opts):
     144    """
     145    Returns the codename of the permission for the specified action.
     146    """
     147    return '%s_%s' % (action, opts.model_name)
  • django/contrib/auth/management/__init__.py

    diff --git a/django/contrib/auth/management/__init__.py b/django/contrib/auth/management/__init__.py
    index 5c1bfbc..1f33846 100644
    a b from __future__ import unicode_literals  
    66import getpass
    77import unicodedata
    88
    9 from django.contrib.auth import models as auth_app, get_user_model
     9from django.contrib.auth import (models as auth_app, get_permission_codename,
     10    get_user_model)
    1011from django.core import exceptions
    1112from django.core.management.base import CommandError
    1213from django.db import DEFAULT_DB_ALIAS, router
    from django.utils import six  
    1617from django.utils.six.moves import input
    1718
    1819
    19 def _get_permission_codename(action, opts):
    20     return '%s_%s' % (action, opts.model_name)
    21 
    22 
    2320def _get_all_permissions(opts, ctype):
    2421    """
    2522    Returns (codename, name) for all permissions in the given opts.
    def _get_all_permissions(opts, ctype):  
    2926    _check_permission_clashing(custom, builtin, ctype)
    3027    return builtin + custom
    3128
     29
    3230def _get_builtin_permissions(opts):
    3331    """
    3432    Returns (codename, name) for all autogenerated permissions.
    3533    """
    3634    perms = []
    3735    for action in ('add', 'change', 'delete'):
    38         perms.append((_get_permission_codename(action, opts),
     36        perms.append((get_permission_codename(action, opts),
    3937            'Can %s %s' % (action, opts.verbose_name_raw)))
    4038    return perms
    4139
     40
    4241def _check_permission_clashing(custom, builtin, ctype):
    4342    """
    4443    Check that permissions for a model do not clash. Raises CommandError if
    def _check_permission_clashing(custom, builtin, ctype):  
    5857                (codename, ctype.app_label, ctype.model_class().__name__))
    5958        pool.add(codename)
    6059
     60
    6161def create_permissions(app, created_models, verbosity, db=DEFAULT_DB_ALIAS, **kwargs):
    6262    try:
    6363        get_model('auth', 'Permission')
  • django/db/models/options.py

    diff --git a/django/db/models/options.py b/django/db/models/options.py
    index b8a7902..ad25de4 100644
    a b class Options(object):  
    414414        return cache
    415415
    416416    def get_add_permission(self):
     417        """
     418        This method has been deprecated in favor of
     419        `django.contrib.auth.get_permission_codename`. refs #20642
     420        """
     421        warnings.warn(
     422            "`Options.get_add_permission` has been deprecated in favor "
     423            "of `django.contrib.auth.get_permission_codename`.",
     424            PendingDeprecationWarning, stacklevel=2)
    417425        return 'add_%s' % self.model_name
    418426
    419427    def get_change_permission(self):
     428        """
     429        This method has been deprecated in favor of
     430        `django.contrib.auth.get_permission_codename`. refs #20642
     431        """
     432        warnings.warn(
     433            "`Options.get_change_permission` has been deprecated in favor "
     434            "of `django.contrib.auth.get_permission_codename`.",
     435            PendingDeprecationWarning, stacklevel=2)
    420436        return 'change_%s' % self.model_name
    421437
    422438    def get_delete_permission(self):
     439        """
     440        This method has been deprecated in favor of
     441        `django.contrib.auth.get_permission_codename`. refs #20642
     442        """
     443        warnings.warn(
     444            "`Options.get_delete_permission` has been deprecated in favor "
     445            "of `django.contrib.auth.get_permission_codename`.",
     446            PendingDeprecationWarning, stacklevel=2)
    423447        return 'delete_%s' % self.model_name
    424448
    425449    def get_all_related_objects(self, local_only=False, include_hidden=False,
  • docs/releases/1.6.txt

    diff --git a/docs/releases/1.6.txt b/docs/releases/1.6.txt
    index 95bfedc..5a611af 100644
    a b on a widget, you should now define this method on the form field itself.  
    851851``Model._meta.module_name`` was renamed to ``model_name``. Despite being a
    852852private API, it will go through a regular deprecation path.
    853853
     854``get_(add|change|delete)_permission`` model _meta methods
     855~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     856
     857``Model._meta.get_(add|change|delete)_permission`` methods were deprecated.
     858Even if they were not part of the public API they'll also go through
     859a regular deprecation path.
     860
    854861``get_query_set`` and similar methods renamed to ``get_queryset``
    855862~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    856863
Back to Top