ajout cache et optimisation historique
authorOlivier Larchevêque <olivier.larcheveque@auf.org>
Wed, 23 Oct 2013 19:44:09 +0000 (15:44 -0400)
committerOlivier Larchevêque <olivier.larcheveque@auf.org>
Wed, 23 Oct 2013 19:44:09 +0000 (15:44 -0400)
project/dashboard.py
project/decorators.py
project/permissions.py
project/recrutement/admin.py
project/rh/admin.py
project/rh/historique.py
project/settings.py

index 1868e05..ba41b0a 100644 (file)
@@ -72,7 +72,7 @@ class CustomIndexDashboard(Dashboard):
 
 
         if in_drh_or_admin(request.user):
-            revisions = get_active_revisions()[:10]
+            revisions = get_active_revisions(limit=10)
             children = []
             for rev in revisions:
                 date = rev['short_date_created']
index 0424878..06bc649 100644 (file)
@@ -2,6 +2,7 @@
 """
 Décorateurs AUF
 """
+from django.core.cache import cache
 from django.http import HttpResponseRedirect
 from django.conf import settings
 from django.contrib import messages
@@ -30,13 +31,20 @@ def in_drh_or_admin(user):
     """
     Teste si un user Django fait parti du groupe DRH, DRH2 ou s'il est admin
     """
+    key = "in_drh_or_admin_%s" % user.id
+    granted = cache.get(key, None)
+    if granted is not None:
+        return granted
+
     user_groups = [g.name for g in user.groups.all()]
     if user.is_superuser or \
             groups.DRH_NIVEAU_1 in user_groups or \
             groups.DRH_NIVEAU_2 in user_groups:
-        return True
+        granted = True
     else:
-        return False
+        granted = False
+    cache.set(key, granted)
+    return granted
 
 
 def drh_or_admin_required(fn):
@@ -49,7 +57,7 @@ def drh_or_admin_required(fn):
             return fn(request, *args, **kwargs)
 
         msg = u"Votre compte ne permet pas d'accéder à " \
-                u"cette partie de l'application."
+              u"cette partie de l'application."
         return redirect_interdiction(request, msg)
 
     return inner
@@ -69,7 +77,7 @@ def region_protected(model):
                groups.DIRECTEUR_DE_BUREAU in user_groups:
                 zones = groups.get_zones_from_user(request.user)
                 qkey = '%s__in' % model.prefix_implantation
-                q = Q(**{ qkey: zones })
+                q = Q(**{qkey: zones})
                 qs = model.objects.filter(q)
                 if int(id) in [o.id for o in qs]:
                     return func(request, id)
@@ -88,7 +96,8 @@ def in_one_of_group(groups):
             for g in user_groups:
                 if g in groups:
                     return fn(request, *args, **kwargs)
-            msg = u"Votre compte ne permet pas d'accéder à cette partie de l'application."
+            msg = u"Votre compte ne permet pas d'accéder "\
+                  u"à cette partie de l'application."
             return redirect_interdiction(request, msg)
         return wrapped
     return wrapper
index d722826..198d696 100644 (file)
@@ -1,19 +1,40 @@
 # -*- encoding: utf-8 -*
 
+from django.core.cache import cache
+
 from project import groups
-from project.groups import get_employe_from_user, get_zones_from_user
+from project.groups import get_zones_from_user
 from project.decorators import in_drh_or_admin
 
-from auf.django.references import models as ref
 from rh import models as rh
 
+
+def get_user_groupnames(user):
+    key = "get_user_groupnames_%s" % user.id
+    group_names = cache.get(key, None)
+    if group_names is not None:
+        return group_names.split(',')
+    group_names = [g.name for g in user.groups.all()]
+    cache.set(key, ",".join(group_names))
+    return group_names
+
+
 def user_gere_obj_de_sa_region(user):
+    key = "user_gere_obj_de_sa_region_%s" % user.id
+    granted = cache.get(key, None)
+    if granted is not None:
+        return granted
+
     user_groups = [g.name for g in user.groups.all()]
     if groups.CORRESPONDANT_RH in user_groups or \
             groups.ADMINISTRATEURS in user_groups or \
             groups.DIRECTEUR_DE_BUREAU in user_groups:
-        return True
-    return False
+        granted = True
+    else:
+        granted = False
+    cache.set(key, granted)
+    return granted
+
 
 def user_can_add_obj(user):
     if user_gere_obj_de_sa_region(user) or \
@@ -21,22 +42,25 @@ def user_can_add_obj(user):
         return True
     return False
 
+
 def user_can_list_obj(user):
     if user_gere_obj_de_sa_region(user) or \
             in_drh_or_admin(user):
         return True
     return False
 
+
 def user_can_change_obj(user, obj):
     if in_drh_or_admin(user) or (
-            user_gere_obj_de_sa_region(user) and \
+            user_gere_obj_de_sa_region(user) and
             obj_in_region_user(user, obj)):
         return True
     return False
-    
+
+
 def user_can_delete_obj(user, obj):
     return in_drh_or_admin(user)
-    
+
 
 # helpers
 def obj_in_region_user(user, obj):
@@ -48,4 +72,3 @@ def obj_in_region_user(user, obj):
     if isinstance(obj, rh.Poste):
         return obj.implantation.zone_administrative in zones
     return False
-    
index 81f954b..cd20147 100644 (file)
@@ -19,6 +19,7 @@ from django.shortcuts import redirect
 from reversion.admin import VersionAdmin
 
 from project import groups
+from project.permissions import get_user_groupnames
 
 from project.rh import models as rh
 from project.recrutement.forms import OffreEmploiForm
@@ -113,7 +114,7 @@ class OffreEmploiAdminMixin(BaseAdmin):
     def get_form(self, request, obj=None, **kwargs):
         form = super(OffreEmploiAdminMixin, self).get_form(request, obj, **kwargs)
         employe = groups.get_employe_from_user(request.user)
-        user_groupes = [g.name for g in request.user.groups.all()]
+        user_groupes = get_user_groupnames(request.user)
 
         # Region
         region_field = None
@@ -168,7 +169,7 @@ class OffreEmploiAdminMixin(BaseAdmin):
     def queryset(self, request):
         qs = self.model._default_manager.get_query_set() \
                 .select_related('offre_emploi')
-        user_groupes = [g.name for g in request.user.groups.all()]
+        user_groupes = get_user_groupnames(request.user)
         if groups.DRH_NIVEAU_1 in user_groupes or \
             groups.DRH_NIVEAU_2 in user_groupes or \
             groups.HAUTE_DIRECTION in user_groupes:
@@ -194,7 +195,7 @@ class OffreEmploiAdminMixin(BaseAdmin):
 
     ### Permission add, delete, change
     def has_add_permission(self, request):
-        user_groupes = [g.name for g in request.user.groups.all()]
+        user_groupes = get_user_groupnames(request.user)
         if request.user.is_superuser is True or \
             groups.DRH_NIVEAU_1 in user_groupes or \
             groups.DRH_NIVEAU_2 in user_groupes or \
@@ -205,7 +206,7 @@ class OffreEmploiAdminMixin(BaseAdmin):
         return False
 
     def has_delete_permission(self, request, obj=None):
-        user_groupes = [g.name for g in request.user.groups.all()]
+        user_groupes = get_user_groupnames(request.user)
         if request.user.is_superuser is True or \
             groups.DRH_NIVEAU_1 in user_groupes or \
             groups.DRH_NIVEAU_2 in user_groupes or \
@@ -222,7 +223,7 @@ class OffreEmploiAdminMixin(BaseAdmin):
         return False
 
     def has_change_permission(self, request, obj=None):
-        user_groupes = [g.name for g in request.user.groups.all()]
+        user_groupes = get_user_groupnames(request.user)
         if request.user.is_superuser is True or \
             groups.DRH_NIVEAU_1 in user_groupes or \
             groups.DRH_NIVEAU_2 in user_groupes or \
@@ -499,7 +500,7 @@ class CandidatAdminMixin(BaseAdmin, ExportAdmin):
 
     ### Permissions add, delete, change
     def has_add_permission(self, request):
-        user_groupes = [g.name for g in request.user.groups.all()]
+        user_groupes = get_user_groupnames(request.user)
         if request.user.is_superuser is True or \
             groups.CORRESPONDANT_RH in user_groupes or \
             groups.DRH_NIVEAU_1 in user_groupes or \
@@ -511,7 +512,7 @@ class CandidatAdminMixin(BaseAdmin, ExportAdmin):
         return False
 
     def has_delete_permission(self, request, obj=None):
-        user_groupes = [g.name for g in request.user.groups.all()]
+        user_groupes = get_user_groupnames(request.user)
         if request.user.is_superuser is True or \
             groups.CORRESPONDANT_RH in user_groupes or \
             groups.DRH_NIVEAU_1 in user_groupes or \
@@ -523,7 +524,7 @@ class CandidatAdminMixin(BaseAdmin, ExportAdmin):
         return False
 
     def has_change_permission(self, request, obj=None):
-        user_groupes = [g.name for g in request.user.groups.all()]
+        user_groupes = get_user_groupnames(request.user)
         if request.user.is_superuser is True or \
             groups.CORRESPONDANT_RH in user_groupes or \
             groups.DRH_NIVEAU_1 in user_groupes or \
@@ -564,7 +565,7 @@ class CandidatAdminMixin(BaseAdmin, ExportAdmin):
                 .select_related('offre_emploi') \
                 .annotate(moyenne=Avg('evaluations__note'))
 
-        user_groupes = [g.name for g in request.user.groups.all()]
+        user_groupes = get_user_groupnames(request.user)
         if groups.DRH_NIVEAU_1 in user_groupes or \
             groups.DRH_NIVEAU_2 in user_groupes or \
             groups.HAUTE_DIRECTION in user_groupes:
@@ -679,7 +680,7 @@ class EvaluateurAdmin(BaseAdmin, VersionAdmin):
 
     ### Permissions add, delete, change
     def has_add_permission(self, request):
-        user_groupes = [g.name for g in request.user.groups.all()]
+        user_groupes = get_user_groupnames(request.user)
         if request.user.is_superuser is True or \
                 groups.DRH_NIVEAU_1 in user_groupes or \
                 groups.DRH_NIVEAU_2 in user_groupes or \
@@ -688,7 +689,7 @@ class EvaluateurAdmin(BaseAdmin, VersionAdmin):
         return False
 
     def has_delete_permission(self, request, obj=None):
-        user_groupes = [g.name for g in request.user.groups.all()]
+        user_groupes = get_user_groupnames(request.user)
         if request.user.is_superuser is True or \
                 groups.DRH_NIVEAU_1 in user_groupes or \
                 groups.DRH_NIVEAU_2 in user_groupes or \
@@ -697,7 +698,7 @@ class EvaluateurAdmin(BaseAdmin, VersionAdmin):
         return False
 
     def has_change_permission(self, request, obj=None):
-        user_groupes = [g.name for g in request.user.groups.all()]
+        user_groupes = get_user_groupnames(request.user)
         if request.user.is_superuser is True or \
                 groups.DRH_NIVEAU_1 in user_groupes or \
                 groups.DRH_NIVEAU_2 in user_groupes or \
@@ -802,7 +803,7 @@ class CandidatEvaluationAdmin(BaseAdmin):
         mais interdire l'accès à modifier l'objet si l'évaluateur n'est pas
         le request.user
         """
-        user_groupes = [g.name for g in request.user.groups.all()]
+        user_groupes = get_user_groupnames(request.user)
 
         if request.user.is_superuser or \
             groups.CORRESPONDANT_RH in user_groupes or \
@@ -824,8 +825,7 @@ class CandidatEvaluationAdmin(BaseAdmin):
         """
         qs = self.model._default_manager.get_query_set() \
                 .select_related('offre_emploi')
-        user_groupes = request.user.groups.all()
-        user_groupes = [g.name for g in request.user.groups.all()]
+        user_groupes = get_user_groupnames(request.user)
 
         if request.user.is_superuser or \
             groups.CORRESPONDANT_RH in user_groupes or \
index 5b83ffb..8fa54e7 100644 (file)
@@ -25,7 +25,8 @@ from project.permissions import user_gere_obj_de_sa_region, \
         user_can_list_obj, \
         user_can_add_obj, \
         user_can_change_obj, \
-        user_can_delete_obj
+        user_can_delete_obj, \
+        get_user_groupnames
 
 from project.rh.forms import ContratForm, AyantDroitForm, EmployeAdminForm, \
         AjaxSelect, DossierForm, ResponsableInlineForm, \
@@ -779,7 +780,7 @@ class EmployeProxyAdmin(EmployeAdminBase):
         return False
 
     def has_change_permission(self, request, obj=None):
-        user_groups = [g.name for g in request.user.groups.all()]
+        user_groups = get_user_groupnames(request.user)
         if groups.CORRESPONDANT_RH in user_groups or \
            groups.ADMINISTRATEURS in user_groups or \
            groups.DIRECTEUR_DE_BUREAU in user_groups or \
@@ -1175,7 +1176,7 @@ class ServiceProxyAdmin(ServiceAdminBase):
         return False
 
     def has_change_permission(self, request, obj=None):
-        user_groups = [g.name for g in request.user.groups.all()]
+        user_groups = get_user_groupnames(request.user)
         if groups.CORRESPONDANT_RH in user_groups or \
            groups.ADMINISTRATEURS in user_groups or \
            groups.DIRECTEUR_DE_BUREAU in user_groups or \
@@ -1317,7 +1318,7 @@ class ImplantationProxyAdmin(BaseAdmin):
         return False
 
     def has_change_permission(self, request, obj=None):
-        user_groups = [g.name for g in request.user.groups.all()]
+        user_groups = get_user_groupnames(request.user)
         if groups.CORRESPONDANT_RH in user_groups or \
            groups.ADMINISTRATEURS in user_groups or \
            groups.DIRECTEUR_DE_BUREAU in user_groups or \
@@ -1345,7 +1346,7 @@ class RegionProxyAdmin(BaseAdmin):
         return False
 
     def has_change_permission(self, request, obj=None):
-        user_groups = [g.name for g in request.user.groups.all()]
+        user_groups = get_user_groupnames(request.user)
         if groups.CORRESPONDANT_RH in user_groups or \
            groups.ADMINISTRATEURS in user_groups or \
            groups.DIRECTEUR_DE_BUREAU in user_groups or \
index 141a250..f2d21a2 100644 (file)
@@ -3,7 +3,9 @@
 from django.core.urlresolvers import reverse
 from django import forms
 from django.db import models
-from reversion.models import Revision
+from django.db.models import Q
+from reversion.models import Revision, Version
+
 
 class ModificationTraite(models.Model):
     """
@@ -11,70 +13,86 @@ class ModificationTraite(models.Model):
     les DRH.
     """
     revision = models.ForeignKey('reversion.Revision')
-    
+
 
 def format_revisions(qs):
     results = []
-    for rev in qs:
 
-        # Dans une révision, on loop dans les versions associées, pour trouver
-        # un modèle qui dispose d'une admin (à priori, le parent) dans le cas 
-        # des objets composés
+    revisions = [r for r in qs]
+    versions = Version.objects.select_related('revision', 'content_type').filter(
+            Q(revision__in=revisions) &
+            (Q(content_type__model='dossier') | Q(content_type__model='poste'))
+            ).\
+            order_by('-revision__date_created')
+    #for rev in qs:
+
+    # Dans une révision, on loop dans les versions associées, pour trouver
+    # un modèle qui dispose d'une admin (à priori, le parent) dans le cas
+    # des objets composés
+        #for v in rev.version_set.all():
+    for v in versions:
+        if v.revision in [r['id'] for r in results]:
+            continue
         change_url = None
         history_url = None
         type = None
         objet = None
-            
-        for v in rev.version_set.all():
 
-            try:
-                klass = v.content_type.model_class()
-                id = int(v.object_id)
-                objet = klass.objects.get(id=id)
-                change_url = reverse('admin:%s_%s_change' %
-                        (v.content_type.app_label, v.content_type.model),
-                        args=(id, ))
-                history_url = reverse('admin:%s_%s_history' %
-                        (v.content_type.app_label, v.content_type.model),
-                        args=(id, ))
-                type = "%s %s" % (v.content_type.app_label, v.content_type.model)
-                break
-            except:
-                continue
+        try:
+            klass = v.content_type.model_class()
+            id = int(v.object_id)
+            objet = klass.objects.get(id=id)
+            change_url = reverse(
+                'admin:%s_%s_change' % (
+                    v.content_type.app_label, v.content_type.model),
+                args=(id, ))
+            history_url = reverse(
+                'admin:%s_%s_history' % (
+                    v.content_type.app_label, v.content_type.model),
+                args=(id, ))
+            type = "%s %s" % (
+                v.content_type.app_label, v.content_type.model)
+            rev = v.revision
+            results.append({
+                'id': rev.id,
+                'date_created': rev.date_created.strftime("%d-%m-%Y %H:%M:%S"),
+                'short_date_created': rev.date_created.strftime("%d-%m-%Y"),
+                'user': rev.user,
+                'comment': rev.comment,
+                'change_url': change_url,
+                'history_url': history_url,
+                'type': type,
+                'objet': objet,
 
-        results.append({
-            'id': rev.id,
-            'date_created': rev.date_created.strftime("%d-%m-%Y %H:%M:%S"),
-            'short_date_created': rev.date_created.strftime("%d-%m-%Y"),
-            'user': rev.user,
-            'comment': rev.comment,
-            'change_url': change_url,
-            'history_url': history_url,
-            'type': type,
-            'objet': objet,
+                })
+        except Exception, e:
+            continue
 
-            })
     return results
 
-def get_active_revisions():
+
+def get_active_revisions(limit=None):
     ids_revisions_traitees = [m.revision.id for m in
-            ModificationTraite.objects.all()]
-    return format_revisions(
-            Revision.objects.
-                filter(version__content_type__app_label="rh").
-                exclude(user__isnull=True).
-                exclude(id__in=ids_revisions_traitees).
-                order_by('-date_created').
-                distinct('id'))
+                              ModificationTraite.objects.select_related('revision').all()]
+    revisions = Revision.objects.\
+        filter(version__content_type__app_label="rh").\
+        exclude(user__isnull=True).\
+        exclude(id__in=ids_revisions_traitees).\
+        order_by('-date_created').\
+        distinct('id')
+    
+    if limit is not None:
+        revisions = revisions[:limit]
+    return format_revisions(revisions)
 
 
 class TodoForm(forms.Form):
-    items = forms.MultipleChoiceField("Les items traités",
-            widget=forms.CheckboxSelectMultiple)
+    items = forms.MultipleChoiceField(
+        "Les items traités",
+        widget=forms.CheckboxSelectMultiple)
 
     def __init__(self, *args, **kwargs):
         self.revisions = kwargs.pop('revisions')
         super(TodoForm, self).__init__(*args, **kwargs)
-        self.fields['items'].choices = [(r['id'], r['id']) for r in self.revisions]
-
-
+        self.fields['items'].choices = \
+            [(r['id'], r['id']) for r in self.revisions]
index b415987..eb985d6 100644 (file)
@@ -243,6 +243,12 @@ LOGGING = {
     },
 }
 
+CACHES = {
+    'default': {
+        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
+    }
+}
+
 # Pour accéder aux requêtes savegardées, il faut définir les permissions dans
 # l'admin
 def qbe_access(user):