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
This commit is contained in:
Alex Gaynor 2010-11-01 20:54:39 +00:00
parent 21d6fb6062
commit 34e545a938
1 changed files with 37 additions and 12 deletions

View File

@ -2,8 +2,9 @@
Creates permissions for all installed apps that need permissions. Creates permissions for all installed apps that need permissions.
""" """
from django.db.models import get_models, signals
from django.contrib.auth import models as auth_app from django.contrib.auth import models as auth_app
from django.db.models import get_models, signals
def _get_permission_codename(action, opts): def _get_permission_codename(action, opts):
return u'%s_%s' % (action, opts.object_name.lower()) return u'%s_%s' % (action, opts.object_name.lower())
@ -19,20 +20,44 @@ def create_permissions(app, created_models, verbosity, **kwargs):
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
app_models = get_models(app) 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: for klass in app_models:
ctype = ContentType.objects.get_for_model(klass) ctype = ContentType.objects.get_for_model(klass)
for codename, name in _get_all_permissions(klass._meta): ctypes.add(ctype)
p, created = auth_app.Permission.objects.get_or_create( 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, codename=codename,
content_type__pk=ctype.id, name=name,
defaults={ content_type=ctype
'name': name,
'content_type': ctype
}
) )
if created and verbosity >= 2: if verbosity >= 2:
print "Adding permission '%s'" % p print "Adding permission '%s'" % p
def create_superuser(app, created_models, verbosity, **kwargs): def create_superuser(app, created_models, verbosity, **kwargs):
from django.core.management import call_command from django.core.management import call_command