Commit 38808b17 by Őry Máté

acl: add management commands and syncdb hook

parent 23600016
"""
Creates Levels for all installed apps that have levels.
"""
from django.db.models import get_models, signals
from django.db import DEFAULT_DB_ALIAS
from django.core.exceptions import ImproperlyConfigured
from ..models import Level, AclBase
def create_levels(app, created_models, verbosity, db=DEFAULT_DB_ALIAS,
**kwargs):
"""Create and set the weights of the configured Levels.
Based on django.contrib.auth.management.__init__.create_permissions"""
# if not router.allow_migrate(db, auth_app.Permission):
# return
from django.contrib.contenttypes.models import ContentType
app_models = [k for k in get_models(app) if AclBase in k.__bases__]
print "Creating levels for models: %s." % ", ".join([m.__name__ for m in app_models])
# This will hold the levels we're looking for as
# (content_type, (codename, name))
searched_levels = list()
level_weights = list()
# The codenames and ctypes that should exist.
ctypes = set()
for klass in app_models:
# Force looking up the content types in the current database
# before creating foreign keys to them.
ctype = ContentType.objects.db_manager(db).get_for_model(klass)
ctypes.add(ctype)
weight = 0
try:
for codename, name in klass.ACL_LEVELS:
searched_levels.append((ctype, (codename, name)))
level_weights.append((ctype, codename, weight))
weight += 1
except AttributeError:
raise ImproperlyConfigured(
"Class %s doesn't have ACL_LEVELS attribute." % klass)
# Find all the Levels that have a content_type for a model we're
# looking for. We don't need to check for codenames since we already have
# a list of the ones we're going to create.
all_levels = set(Level.objects.using(db).filter(
content_type__in=ctypes,
).values_list(
"content_type", "codename"
))
levels = [
Level(codename=codename, name=name, content_type=ctype)
for ctype, (codename, name) in searched_levels
if (ctype.pk, codename) not in all_levels
]
Level.objects.using(db).bulk_create(levels)
if verbosity >= 2:
print("Adding levels [%s]." % ", ".join(levels))
print("Searched: [%s]." % ", ".join([unicode(l) for l in searched_levels]))
print("All: [%s]." % ", ".join([unicode(l) for l in all_levels]))
# set weights
for ctype, codename, weight in level_weights:
Level.objects.filter(codename=codename,
content_type=ctype).update(weight=weight)
signals.post_syncdb.connect(
create_levels, dispatch_uid="circle.acl.management.create_levels")
from django.core.management.base import BaseCommand
from .. import create_levels
class Command(BaseCommand):
args = ''
help = 'Regenerates Levels'
def handle(self, *args, **options):
create_levels(None, None, 3)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment