Browse Source

Fixed #9057 -- Added default_permissions model meta option.

Thanks hvendelbo for the suggestion and koenb for the draft patch.
Tim Graham 11 years ago
parent
commit
ddae74b64c

+ 2 - 1
django/contrib/auth/management/__init__.py

@@ -30,9 +30,10 @@ def _get_all_permissions(opts, ctype):
 def _get_builtin_permissions(opts):
     """
     Returns (codename, name) for all autogenerated permissions.
+    By default, this is ('add', 'change', 'delete')
     """
     perms = []
-    for action in ('add', 'change', 'delete'):
+    for action in opts.default_permissions:
         perms.append((get_permission_codename(action, opts),
             'Can %s %s' % (action, opts.verbose_name_raw)))
     return perms

+ 23 - 1
django/contrib/auth/tests/test_management.py

@@ -196,13 +196,15 @@ class CustomUserModelValidationTestCase(TestCase):
         self.assertIn("The USERNAME_FIELD must be unique. Add unique=True to the field parameters.", new_io.getvalue())
 
 
-class PermissionDuplicationTestCase(TestCase):
+class PermissionTestCase(TestCase):
 
     def setUp(self):
         self._original_permissions = models.Permission._meta.permissions[:]
+        self._original_default_permissions = models.Permission._meta.default_permissions
 
     def tearDown(self):
         models.Permission._meta.permissions = self._original_permissions
+        models.Permission._meta.default_permissions = self._original_default_permissions
         ContentType.objects.clear_cache()
 
     def test_duplicated_permissions(self):
@@ -235,3 +237,23 @@ class PermissionDuplicationTestCase(TestCase):
             ('other_one', 'Some other permission'),
         ]
         create_permissions(models, [], verbosity=0)
+
+    def test_default_permissions(self):
+        models.Permission._meta.permissions = [
+            ('my_custom_permission', 'Some permission'),
+        ]
+        create_permissions(models, [], verbosity=0)
+
+        # add/change/delete permission by default + custom permission
+        self.assertEqual(models.Permission.objects.filter(content_type=
+            ContentType.objects.get_by_natural_key('auth', 'permission')
+        ).count(), 4)
+
+        models.Permission.objects.all().delete()
+        models.Permission._meta.default_permissions = []
+        create_permissions(models, [], verbosity=0)
+
+        # custom permission only since default permissions is empty
+        self.assertEqual(models.Permission.objects.filter(content_type=
+            ContentType.objects.get_by_natural_key('auth', 'permission')
+        ).count(), 1)

+ 2 - 1
django/db/models/options.py

@@ -22,7 +22,7 @@ DEFAULT_NAMES = ('verbose_name', 'verbose_name_plural', 'db_table', 'ordering',
                  'unique_together', 'permissions', 'get_latest_by',
                  'order_with_respect_to', 'app_label', 'db_tablespace',
                  'abstract', 'managed', 'proxy', 'swappable', 'auto_created',
-                 'index_together')
+                 'index_together', 'default_permissions')
 
 
 @python_2_unicode_compatible
@@ -36,6 +36,7 @@ class Options(object):
         self.ordering = []
         self.unique_together = []
         self.index_together = []
+        self.default_permissions = ('add', 'change', 'delete')
         self.permissions = []
         self.object_name, self.app_label = None, app_label
         self.get_latest_by = None

+ 13 - 0
docs/ref/models/options.txt

@@ -235,6 +235,19 @@ Django quotes column and table names behind the scenes.
     This is a list or tuple of 2-tuples in the format ``(permission_code,
     human_readable_permission_name)``.
 
+``default_permissions``
+------------------------------
+
+.. attribute:: Options.default_permissions
+
+    .. versionadded:: 1.7
+
+    Defaults to ``('add', 'change', 'delete')``. You may customize this list,
+    for example, by setting this to an empty list if your app doesn't require
+    any of the default permissions. It must be specified on the model before
+    the model is created by :djadmin:`syncdb` in order to prevent any omitted
+    permissions from being created.
+
 ``proxy``
 ---------
 

+ 4 - 0
docs/releases/1.7.txt

@@ -131,6 +131,10 @@ Minor features
   return ``self.cleaned_data``. If it does return a changed dictionary then
   that will still be used.
 
+* The new :attr:`~django.db.models.Options.default_permissions` model
+  ``Meta`` option allows you to customize (or disable) creation of the default
+  add, change, and delete permissions.
+
 Backwards incompatible changes in 1.7
 =====================================