Commit 34e545a9 authored by Alex Gaynor's avatar Alex Gaynor
Browse files

Restructure the create_permission signal handler to perform fewer SQL queries,...

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
parent 21d6fb60
Loading
Loading
Loading
Loading
+37 −12
Original line number Diff line number Diff line
@@ -2,8 +2,9 @@
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.db.models import get_models, signals


def _get_permission_codename(action, opts):
    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

    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(
        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,
                content_type__pk=ctype.id,
                defaults={
                    'name': name,
                    'content_type': ctype
                }
            name=name,
            content_type=ctype
        )
            if created and verbosity >= 2:
        if verbosity >= 2:
            print "Adding permission '%s'" % p


def create_superuser(app, created_models, verbosity, **kwargs):
    from django.core.management import call_command