Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Restructure the create_permission signal handler to perform fewer SQL…

… queries, this speeds up the test suite dramatically.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@14413 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 34e545a93847142b112083b9858f76448f356711 1 parent 21d6fb6
Alex Gaynor authored November 01, 2010

Showing 1 changed file with 37 additions and 12 deletions. Show diff stats Hide diff stats

  1. 49  django/contrib/auth/management/__init__.py
49  django/contrib/auth/management/__init__.py
@@ -2,8 +2,9 @@
2 2
 Creates permissions for all installed apps that need permissions.
3 3
 """
4 4
 
5  
-from django.db.models import get_models, signals
6 5
 from django.contrib.auth import models as auth_app
  6
+from django.db.models import get_models, signals
  7
+
7 8
 
8 9
 def _get_permission_codename(action, opts):
9 10
     return u'%s_%s' % (action, opts.object_name.lower())
@@ -19,19 +20,43 @@ def create_permissions(app, created_models, verbosity, **kwargs):
19 20
     from django.contrib.contenttypes.models import ContentType
20 21
 
21 22
     app_models = get_models(app)
  23
+
  24
+    # This will hold the permissions we're looking for as
  25
+    # (content_type, (codename, name))
  26
+    searched_perms = set()
  27
+    # The codenames and ctypes that should exist.
  28
+    ctypes = set()
  29
+    codenames = set()
22 30
     for klass in app_models:
23 31
         ctype = ContentType.objects.get_for_model(klass)
24  
-        for codename, name in _get_all_permissions(klass._meta):
25  
-            p, created = auth_app.Permission.objects.get_or_create(
26  
-                codename=codename,
27  
-                content_type__pk=ctype.id,
28  
-                defaults={
29  
-                    'name': name,
30  
-                    'content_type': ctype
31  
-                }
32  
-            )
33  
-            if created and verbosity >= 2:
34  
-                print "Adding permission '%s'" % p
  32
+        ctypes.add(ctype)
  33
+        for perm in _get_all_permissions(klass._meta):
  34
+            codenames.add(perm[0])
  35
+            searched_perms.add((ctype, perm))
  36
+
  37
+    # Find all the Permissions that a) have a content_type for a model we're
  38
+    # looking for, and b) have a codename we're looking for. It doesn't need to
  39
+    # have both, we have a list of exactly what we want, and it's faster to
  40
+    # write the query with fewer conditions.
  41
+    all_perms = set(auth_app.Permission.objects.filter(
  42
+        content_type__in=ctypes,
  43
+        codename__in=codenames
  44
+    ).values_list(
  45
+        "content_type", "codename"
  46
+    ))
  47
+
  48
+    for ctype, (codename, name) in searched_perms:
  49
+        # If the permissions exists, move on.
  50
+        if (ctype.pk, codename) in all_perms:
  51
+            continue
  52
+        p = auth_app.Permission.objects.create(
  53
+            codename=codename,
  54
+            name=name,
  55
+            content_type=ctype
  56
+        )
  57
+        if verbosity >= 2:
  58
+            print "Adding permission '%s'" % p
  59
+
35 60
 
36 61
 def create_superuser(app, created_models, verbosity, **kwargs):
37 62
     from django.core.management import call_command

0 notes on commit 34e545a

Please sign in to comment.
Something went wrong with that request. Please try again.