Author: Alex
Date: 2010-11-01 15:54:39 -0500 (Mon, 01 Nov 2010)
New Revision: 14413

Modified:
   django/trunk/django/contrib/auth/management/__init__.py
Log:
Restructure the create_permission signal handler to perform fewer SQL queries, 
this speeds up the test suite dramatically.

Modified: django/trunk/django/contrib/auth/management/__init__.py
===================================================================
--- django/trunk/django/contrib/auth/management/__init__.py     2010-11-01 
17:22:13 UTC (rev 14412)
+++ django/trunk/django/contrib/auth/management/__init__.py     2010-11-01 
20:54:39 UTC (rev 14413)
@@ -2,9 +2,10 @@
 Creates permissions for all installed apps that need permissions.
 """
 
+from django.contrib.auth import models as auth_app
 from django.db.models import get_models, signals
-from django.contrib.auth import models as auth_app
 
+
 def _get_permission_codename(action, opts):
     return u'%s_%s' % (action, opts.object_name.lower())
 
@@ -19,20 +20,44 @@
     from django.contrib.contenttypes.models import ContentType
 
     app_models = get_models(app)
+
+    # This will hold the permissions we're looking for as
+    # (content_type, (codename, name))
+    searched_perms = set()
+    # The codenames and ctypes that should exist.
+    ctypes = set()
+    codenames = set()
     for klass in app_models:
         ctype = ContentType.objects.get_for_model(klass)
-        for codename, name in _get_all_permissions(klass._meta):
-            p, created = auth_app.Permission.objects.get_or_create(
-                codename=codename,
-                content_type__pk=ctype.id,
-                defaults={
-                    'name': name,
-                    'content_type': ctype
-                }
-            )
-            if created and verbosity >= 2:
-                print "Adding permission '%s'" % p
+        ctypes.add(ctype)
+        for perm in _get_all_permissions(klass._meta):
+            codenames.add(perm[0])
+            searched_perms.add((ctype, perm))
 
+    # Find all the Permissions that a) have a content_type for a model we're
+    # looking for, and b) have a codename we're looking for. It doesn't need to
+    # have both, we have a list of exactly what we want, and it's faster to
+    # write the query with fewer conditions.
+    all_perms = set(auth_app.Permission.objects.filter(
+        content_type__in=ctypes,
+        codename__in=codenames
+    ).values_list(
+        "content_type", "codename"
+    ))
+
+    for ctype, (codename, name) in searched_perms:
+        # If the permissions exists, move on.
+        if (ctype.pk, codename) in all_perms:
+            continue
+        p = auth_app.Permission.objects.create(
+            codename=codename,
+            name=name,
+            content_type=ctype
+        )
+        if verbosity >= 2:
+            print "Adding permission '%s'" % p
+
+
 def create_superuser(app, created_models, verbosity, **kwargs):
     from django.core.management import call_command
 

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en.

Reply via email to