Débug de pièces jointes
[auf_rh_dae.git] / project / recrutement / admin.py
CommitLineData
df59fcab 1# -*- encoding: utf-8 -*-
2
6067184b 3from django.core.urlresolvers import reverse
4from django.http import HttpResponseRedirect
df59fcab 5from django.contrib import admin
38df74bb 6from django.shortcuts import get_object_or_404
8e0d552d 7from django.core.files.storage import default_storage
3a542b85 8from django.forms.models import BaseInlineFormSet
38df74bb 9
6067184b 10from reversion.admin import VersionAdmin
38df74bb 11from datamaster_modeles.models import Employe, Implantation, Region
6067184b 12
e2968e84 13from project.rh import models as rh
df59fcab 14from recrutement.models import *
3a542b85
NBV
15from recrutement.workflow import grp_evaluateurs_recrutement, \
16 grp_drh_recrutement, grp_directeurs_bureau_recrutement, \
17 grp_administrateurs_recrutement
a084e988 18from recrutement.forms import *
df59fcab 19
3a542b85
NBV
20from project.lib import get_employe_from_user as get_emp
21
b8b74dee
NBV
22class ProxyEvaluateur(Evaluateur.offres_emploi.through):
23 """
24 Ce proxy sert uniquement dans l'admin à disposer d'un libellé
25 plus ergonomique.
26 """
27 class Meta:
28 proxy = True
29 verbose_name = "évaluateur"
30
31class EvaluateurInline(admin.TabularInline):
32 model = ProxyEvaluateur
33 fields = ('evaluateur',)
34 extra = 1
35
d2b30f5f 36class OffreEmploiAdmin(VersionAdmin):
7f9e891e 37 date_hierarchy = 'date_creation'
c281435b 38 list_display = ('nom', 'date_limite', 'region', 'statut',
e2968e84 39 'est_affiche', '_candidatsList', )
7d0ae1ba
NBV
40 exclude = ('actif', 'poste_nom', 'resume',)
41 list_filter = ('statut',)
c4874d66 42 actions = ['affecter_evaluateurs_offre_emploi', ]
a084e988 43 form = OffreEmploiForm
b8b74dee 44 inlines = [EvaluateurInline, ]
2c3c54ee 45
a029f641
NBV
46 def get_actions(self, request):
47 actions = super(OffreEmploiAdmin, self).get_actions(request)
48 del actions['delete_selected']
540dfae4 49 return actions
a029f641 50
c4874d66
NBV
51 # Affecter un évaluateurs à des offres d'emploi
52 def affecter_evaluateurs_offre_emploi(modeladmin, obj, candidats):
53 selected = obj.POST.getlist(admin.ACTION_CHECKBOX_NAME)
54
55 return HttpResponseRedirect(reverse('affecter_evaluateurs_offre_emploi')+
56 "?ids=%s" % (",".join(selected)))
57 affecter_evaluateurs_offre_emploi.short_description = u'Affecter évaluateur(s)'
58
8941aee7 59 # Afficher la liste des candidats pour l'offre d'emploi
596fe324 60 def _candidatsList(self, obj):
8ea41642 61 return "<a href='%s?offre_emploi__id__exact=%s'>Voir les candidats \
62 </a>" % (reverse('admin:recrutement_candidat_changelist'), obj.id)
2f78949d 63 _candidatsList.allow_tags = True
f6724c20 64 _candidatsList.short_description = "Afficher la liste des candidats"
362a3534 65
3a542b85
NBV
66 def get_form(self, request, obj=None, **kwargs):
67 form = super(OffreEmploiAdmin, self).get_form(request, obj, **kwargs)
68 employe = get_emp(request.user)
69 import pdb;pdb.set_trace()
70 user_groupes = request.user.groups.all()
71 if not grp_drh_recrutement in user_groupes and \
72 not request.user.is_superuser:
73 if form.declared_fields.has_key('region'):
74 region_field = form.declared_fields['region']
75 else:
76 region_field = form.base_fields['region']
77 import pdb;pdb.set_trace()
78 user = request.user
79 region_ids = [g.id for g in user.regions.all()]
80 region_field.queryset = Region.objects.filter(id__in=region_ids)
81 return form
82
2f78949d 83 def queryset(self, request):
382501c1 84 qs = self.model._default_manager.get_query_set()
f6724c20
NBV
85 # Si user est superuser afficher toutes les offres d'emploi
86 user_groupes = request.user.groups.all()
d46075cb 87 if not grp_drh_recrutement in user_groupes and \
3a542b85
NBV
88 not grp_directeurs_bureau_recrutement in user_groupes and \
89 not grp_administrateurs_recrutement in user_groupes and \
d46075cb 90 not request.user.is_superuser:
beef7690 91 """
beef7690
NBV
92 Si le user n'est ni un évaluateur ni un administrateur régional,
93 retourner none
94 Vérifier groupes
95 """
f6724c20 96 if grp_evaluateurs_recrutement in user_groupes:
ca73c3c6
NBV
97 try:
98 user = Evaluateur.objects.get(user=request.user)
99 except Evaluateur.DoesNotExist:
3a542b85 100 return qs.none()
f6724c20
NBV
101 else:
102 return qs.none()
103
beef7690 104 if type(user) is Evaluateur:
f6724c20 105 candidats = [g for g in user.candidats.all()]
beef7690 106 offre_emploi_ids = [c.offre_emploi.id for c in candidats]
f6724c20 107 return qs.select_related('offre_emploi').\
beef7690 108 filter(id__in=offre_emploi_ids)
3bcef02d 109 return qs.none()
382501c1 110 return qs.select_related('offre_emploi')
f6724c20 111
3a542b85
NBV
112 def has_add_permission(self, request):
113 user_groupes = request.user.groups.all()
114 if grp_drh_recrutement in user_groupes or \
115 grp_directeurs_bureau_recrutement in user_groupes or \
116 grp_administrateurs_recrutement in user_groupes or \
117 request.user.is_superuser:
118 return True
119 return False
120
f6724c20
NBV
121 def has_change_permission(self, request, obj=None):
122 user_groupes = request.user.groups.all()
123 if grp_drh_recrutement in user_groupes or \
3a542b85 124 grp_directeurs_bureau_recrutement in user_groupes or \
d46075cb
NBV
125 grp_administrateurs_recrutement in user_groupes or \
126 request.user.is_superuser:
f6724c20
NBV
127 return True
128 return False
129
130class ProxyOffreEmploiAdmin(OffreEmploiAdmin):
4fd0c4a2
NBV
131 list_display = ('nom', 'resume', 'date_limite', 'region', 'statut',
132 'est_affiche')
7d0ae1ba
NBV
133 readonly_fields = ('description', 'bureau', 'duree_affectation',
134 'renumeration', 'debut_affectation', 'lieu_affectation',
135 'nom', 'resume', 'date_limite', 'region')
f6724c20 136 fieldsets = (
720c3ad5 137 ('Nom', {
f6724c20
NBV
138 'fields': ('nom', )
139 }),
720c3ad5 140 ('Description générale', {
14e06ff6 141 'fields': ('resume','description', 'date_limite', )
f6724c20 142 }),
720c3ad5 143 ('Coordonnées', {
f6724c20
NBV
144 'fields': ('lieu_affectation', 'bureau', 'region', )
145 }),
720c3ad5 146 ('Autre', {
f6724c20
NBV
147 'fields': ('debut_affectation', 'duree_affectation',
148 'renumeration', )
149 }),
150 )
464e5825 151 inlines = []
b8778e64
NBV
152 def get_actions(self, request):
153 actions = super(ProxyOffreEmploiAdmin, self).get_actions(request)
154 del actions['affecter_evaluateurs_offre_emploi']
155 return actions
156
a029f641 157 def response_change(self, request, obj):
464e5825
NBV
158 response = super(ProxyOffreEmploiAdmin, self).response_change(request,
159 obj)
a029f641
NBV
160 user_groupes = request.user.groups.all()
161 if grp_drh_recrutement in user_groupes or \
3a542b85
NBV
162 grp_directeurs_bureau_recrutement in user_groupes or \
163 grp_administrateurs_recrutement in user_groupes or \
a029f641 164 request.user.is_superuser:
464e5825
NBV
165 return HttpResponseRedirect(reverse\
166 ('admin:recrutement_offreemploi_changelist'))
167 return HttpResponseRedirect(reverse\
168 ('admin:recrutement_proxyoffreemploi_changelist'))
a029f641 169
f6724c20
NBV
170 def has_add_permission(self, request):
171 return False
172
173 def has_delete_permission(self, request, obj=None):
174 return False
175
2d083449
NBV
176 def has_change_permission(self, request, obj=None):
177 user_groupes = request.user.groups.all()
beef7690 178 if grp_evaluateurs_recrutement in user_groupes or \
d46075cb 179 grp_drh_recrutement in user_groupes or \
3a542b85
NBV
180 grp_directeurs_bureau_recrutement in user_groupes or \
181 grp_administrateurs_recrutement in user_groupes or \
d46075cb 182 request.user.is_superuser:
2d083449
NBV
183 return True
184 return False
185
572c8d08
NBV
186class CandidatPieceInline(admin.TabularInline):
187 model = CandidatPiece
188 fields = ('candidat', 'nom', 'path',)
189 extra = 1
190 max_num = 3
191
572c8d08
NBV
192class CandidatEvaluationInlineFormSet(BaseInlineFormSet):
193 """
194 Empêche la suppression d'une évaluation pour le CandidatEvaluationInline
195 """
196 def __init__(self, *args, **kwargs):
197 super(CandidatEvaluationInlineFormSet, self).__init__(*args, **kwargs)
198 self.can_delete = False
199
200class CandidatEvaluationInline(admin.TabularInline):
201 model = CandidatEvaluation
202 fields = ('evaluateur', 'note', 'commentaire')
203 max_num = 0
204 extra = 0
205 formset = CandidatEvaluationInlineFormSet
206
207 def get_readonly_fields(self, request, obj=None):
208 """
209 Empêche la modification des évaluations
210 """
211 if obj:
212 return self.readonly_fields+('evaluateur', 'note', 'commentaire')
213 return self.readonly_fields
214
d2b30f5f 215class CandidatAdmin(VersionAdmin):
7d0ae1ba 216 exclude = ('actif', )
7f9e891e 217 date_hierarchy = 'date_creation'
0fd8a26d 218 list_display = ('nom', 'prenom', 'offre_emploi','statut',
dc7faf2b
NBV
219 'voir_offre_emploi', 'calculer_moyenne',
220 'afficher_candidat',)
8ea41642 221 list_filter = ('offre_emploi', )
7d0ae1ba 222
7f9e891e 223 fieldsets = (
4896b661 224 ("Offre d'emploi", {
225 'fields': ('offre_emploi', )
226 }),
7f9e891e 227 ('Informations personnelles', {
4fd0c4a2 228 'fields': ('prenom','nom','genre', 'nationalite',
7f9e891e 229 'situation_famille', 'nombre_dependant',)
230 }),
ec517164 231 ('Coordonnées', {
232 'fields': ('telephone', 'email', 'adresse', 'ville',
233 'etat_province', 'code_postal', 'pays', )
7f9e891e 234 }),
235 ('Informations professionnelles', {
4896b661 236 'fields': ('niveau_diplome','employeur_actuel',
8ea41642 237 'poste_actuel', 'domaine_professionnel',)
7f9e891e 238 }),
65c4cbd9
NBV
239 ('Traitement', {
240 'fields': ('statut', )
7f9e891e 241 }),
242 )
170c9aa2 243 inlines = [
244 CandidatPieceInline,
572c8d08 245 CandidatEvaluationInline,
170c9aa2 246 ]
f9983b5a 247
540dfae4 248 actions = ['envoyer_courriel_candidats']
a029f641
NBV
249
250 def get_actions(self, request):
251 actions = super(CandidatAdmin, self).get_actions(request)
252 del actions['delete_selected']
540dfae4 253 return actions
362a3534 254
4e8340cf 255 # Envoyer un courriel à des candidats
52765380 256 def envoyer_courriel_candidats(modeladmin, obj, candidats):
257 selected = obj.POST.getlist(admin.ACTION_CHECKBOX_NAME)
258
32834000 259 return HttpResponseRedirect(reverse('selectionner_template')+
52765380 260 "?ids=%s" % (",".join(selected)))
261 envoyer_courriel_candidats.short_description = u'Envoyer courriel'
262
05503d56 263 # Évaluer un candidat
596fe324 264 def evaluer_candidat(self, obj):
dc7faf2b 265 return "<a href='%s?candidat__id__exact=%s'>Évaluer le candidat</a>" % \
beef7690
NBV
266 (reverse('admin:recrutement_candidatevaluation_changelist'),
267 obj.id)
596fe324 268 evaluer_candidat.allow_tags = True
beef7690 269 evaluer_candidat.short_description = 'Évaluation'
596fe324 270
7d82fd33 271 # Afficher un candidat
272 def afficher_candidat(self, obj):
382501c1
NBV
273 return "<a href='%s'>Voir le candidat</a>" % \
274 (reverse('admin:recrutement_proxycandidat_change', args=(obj.id,)))
7d82fd33 275 afficher_candidat.allow_tags = True
8e0d552d 276 afficher_candidat.short_description = u'Détails du candidat'
7d82fd33 277
8941aee7 278 # Voir l'offre d'emploi
279 def voir_offre_emploi(self, obj):
720c3ad5
NBV
280 return "<a href='%s'>Voir l'offre d'emploi</a>" % \
281 (reverse('admin:recrutement_proxyoffreemploi_change',
282 args=(obj.offre_emploi.id,)))
8941aee7 283 voir_offre_emploi.allow_tags = True
284 voir_offre_emploi.short_description = "Afficher l'offre d'emploi"
285
8941aee7 286 # Calculer la moyenne des notes
287 def calculer_moyenne(self, obj):
288 evaluations = CandidatEvaluation.objects.filter(candidat=obj)
289 offre_emploi = obj.offre_emploi
290
f6724c20
NBV
291 notes = [evaluation.note for evaluation in evaluations.all() \
292 if evaluation.note is not None]
8941aee7 293
7d0ae1ba 294 if len(notes) > 0:
8941aee7 295 moyenne_votes = float(sum(notes)) / len(notes)
296 else:
297 moyenne_votes = "Non disponible"
298 return moyenne_votes
299 calculer_moyenne.allow_tags = True
300 calculer_moyenne.short_description = "Moyenne des notes"
301
3a542b85 302 def has_add_permission(self, request):
f6724c20
NBV
303 user_groupes = request.user.groups.all()
304 if grp_drh_recrutement in user_groupes or \
3a542b85 305 grp_directeurs_bureau_recrutement in user_groupes or \
d46075cb
NBV
306 grp_administrateurs_recrutement in user_groupes or \
307 request.user.is_superuser:
f6724c20 308 return True
3a542b85 309 return False
4896b661 310
f6724c20 311 def has_delete_permission(self, request, obj=None):
3a542b85
NBV
312 user_groupes = request.user.groups.all()
313 if grp_drh_recrutement in user_groupes or \
314 grp_directeurs_bureau_recrutement in user_groupes or \
315 grp_administrateurs_recrutement in user_groupes or \
316 request.user.is_superuser:
317 return True
318 return False
f6724c20
NBV
319
320 def has_change_permission(self, request, obj=None):
321 user_groupes = request.user.groups.all()
322 if grp_drh_recrutement in user_groupes or \
3a542b85 323 grp_directeurs_bureau_recrutement in user_groupes or \
d46075cb
NBV
324 grp_administrateurs_recrutement in user_groupes or \
325 request.user.is_superuser:
f6724c20
NBV
326 return True
327 return False
4896b661 328
d46075cb 329 def queryset(self, request):
f9983b5a 330 """
8ea41642 331 Spécifie un queryset limité, autrement Django exécute un
332 select_related() sans paramètre, ce qui a pour effet de charger tous
333 les objets FK, sans limite de profondeur. Dès qu'on arrive, dans les
334 modèles de Region, il existe plusieurs boucles, ce qui conduit à la
335 génération d'une requête infinie.
d835c9f3 336
f9983b5a 337 """
f6724c20
NBV
338 qs = self.model._default_manager.get_query_set()
339 # Si user est superuser afficher tous les candidats
d46075cb
NBV
340 user_groupes = request.user.groups.all()
341 if not grp_drh_recrutement in user_groupes and \
3a542b85
NBV
342 not grp_directeurs_bureau_recrutement in user_groupes and \
343 not grp_administrateurs_recrutement in user_groupes and \
d46075cb 344 not request.user.is_superuser:
f6724c20
NBV
345 # Si le user n'est ni un évaluateur ni un administrateur régional,
346 # retourner none
347
348 # Vérifier groupes
349 if grp_evaluateurs_recrutement in user_groupes:
ca73c3c6 350 try:
2c3c54ee 351 user = Evaluateur.objects.get(user=request.user)
ca73c3c6
NBV
352 except Evaluateur.DoesNotExist:
353 return qs.none()
f6724c20
NBV
354 else:
355 return qs.none()
f6724c20
NBV
356 ids = [c.id for c in user.candidats.all()]
357 return qs.select_related('candidats').filter(id__in=ids)
358 return qs.select_related('candidats')
359
360class ProxyCandidatAdmin(CandidatAdmin):
f6724c20 361 readonly_fields = ('statut', 'offre_emploi', 'prenom', 'nom',
4fd0c4a2
NBV
362 'genre', 'nationalite', 'situation_famille',
363 'nombre_dependant', 'telephone', 'email', 'adresse',
364 'ville', 'etat_province', 'code_postal', 'pays',
365 'niveau_diplome', 'employeur_actuel', 'poste_actuel',
8e0d552d 366 'domaine_professionnel', 'pieces_jointes',)
2d083449
NBV
367 fieldsets = (
368 ("Offre d'emploi", {
369 'fields': ('offre_emploi', )
370 }),
371 ('Informations personnelles', {
4fd0c4a2 372 'fields': ('prenom','nom','genre', 'nationalite',
2d083449
NBV
373 'situation_famille', 'nombre_dependant',)
374 }),
375 ('Coordonnées', {
376 'fields': ('telephone', 'email', 'adresse', 'ville',
377 'etat_province', 'code_postal', 'pays', )
378 }),
379 ('Informations professionnelles', {
380 'fields': ('niveau_diplome','employeur_actuel',
381 'poste_actuel', 'domaine_professionnel',)
8e0d552d 382 }),
2d083449 383 )
f6724c20 384 inlines = []
2d083449 385
a029f641
NBV
386 def response_change(self, request, obj):
387 response = super(ProxyCandidatAdmin, self).response_change(request, obj)
388 user_groupes = request.user.groups.all()
389 if grp_drh_recrutement in user_groupes or \
3a542b85
NBV
390 grp_directeurs_bureau_recrutement in user_groupes or \
391 grp_administrateurs_recrutement in user_groupes or \
a029f641 392 request.user.is_superuser:
464e5825
NBV
393 return HttpResponseRedirect(reverse\
394 ('admin:recrutement_candidat_changelist'))
395 return HttpResponseRedirect(reverse\
396 ('admin:recrutement_proxycandidat_changelist'))
a029f641 397
f6724c20
NBV
398 def has_add_permission(self, request):
399 return False
400
401 def has_delete_permission(self, request, obj=None):
402 return False
2adf9e0c 403
2d083449
NBV
404 def has_change_permission(self, request, obj=None):
405 user_groupes = request.user.groups.all()
beef7690 406 if grp_drh_recrutement in user_groupes or \
d46075cb 407 grp_evaluateurs_recrutement in user_groupes or \
3a542b85
NBV
408 grp_directeurs_bureau_recrutement in user_groupes or \
409 grp_administrateurs_recrutement in user_groupes or \
d46075cb 410 request.user.is_superuser:
2d083449
NBV
411 return True
412 return False
413
2e9ee615 414class CandidatPieceAdmin(admin.ModelAdmin):
170c9aa2 415 list_display = ('nom', 'candidat', )
416
417 def queryset(self, request):
418 """
419 Spécifie un queryset limité, autrement Django exécute un
420 select_related() sans paramètre, ce qui a pour effet de charger tous
421 les objets FK, sans limite de profondeur. Dès qu'on arrive, dans les
422 modèles de Region, il existe plusieurs boucles, ce qui conduit à la
423 génération d'une requête infinie.
d835c9f3 424 Affiche la liste de candidats que si le user connecté
27c81d11 425 possède un Evaluateur
170c9aa2 426 """
427 qs = self.model._default_manager.get_query_set()
428 return qs.select_related('candidat')
2e9ee615 429
d2b30f5f 430class EvaluateurAdmin(VersionAdmin):
eb579d40 431 fieldsets = (
540dfae4
NBV
432 ("Utilisateur", {
433 'fields': ('user',)
434 }),
435 ("Offres d'emploi à évaluer", {
436 'fields': ('offres_emploi',)
437 }),
eb579d40 438 )
4418c732 439
a029f641
NBV
440 def get_actions(self, request):
441 actions = super(EvaluateurAdmin, self).get_actions(request)
442 del actions['delete_selected']
540dfae4 443 return actions
a029f641 444
b89fef74 445class AdministrateurRegionalAdmin(VersionAdmin):
27c81d11 446 pass
447
d2b30f5f 448class CandidatEvaluationAdmin(VersionAdmin):
2c3c54ee 449 list_display = ('_candidat', '_offre_emploi', 'evaluateur', '_note',
b903198b 450 '_commentaire', )
beef7690
NBV
451 readonly_fields = ('candidat', 'evaluateur')
452 fieldsets = (
453 ('Évaluation du candidat', {
454 'fields': ('candidat', 'evaluateur', 'note', 'commentaire', )
455 }),
456 )
457
a029f641
NBV
458 def get_actions(self, request):
459 actions = super(CandidatEvaluationAdmin, self).get_actions(request)
460 del actions['delete_selected']
540dfae4 461 return actions
a029f641 462
beef7690
NBV
463 def _note(self, obj):
464 """
465 Si l'évaluateur n'a pas encore donné de note au candidat, indiquer
466 un lien pour Évaluer le candidat.
467 Sinon afficher la note.
468 """
469 if obj.note is None:
b903198b 470 return "<a href='%s'>Candidat non évalué</a>" % \
beef7690 471 (reverse('admin:recrutement_candidatevaluation_change',
7d0ae1ba 472 args=(obj.id,)))
b903198b
NBV
473 return "<a href='%s'>%s</a>" % \
474 (reverse('admin:recrutement_candidatevaluation_change',
475 args=(candidat_evaluation.id,)), obj.note)
beef7690 476 _note.allow_tags = True
7d0ae1ba 477 _note.short_description = "Note"
beef7690
NBV
478 _note.admin_order_field = 'note'
479
480 def _candidat(self, obj):
481 return "<a href='%s'>%s</a>" \
482 % (reverse('admin:recrutement_proxycandidat_change',
483 args=(obj.candidat.id,)), obj.candidat)
484 _candidat.allow_tags = True
485 _candidat.short_description = 'Candidat'
486
487 def _commentaire(self, obj):
488 """
489 Si l'évaluateur n'a pas encore donné de note au candidat, indiquer
490 dans le champ commentaire, Aucun au lieu de (None)
491 Sinon afficher la note.
492 """
493 if obj.commentaire is None:
494 return "Aucun"
495 return obj.commentaire
496 _commentaire.allow_tags = True
497 _commentaire.short_description = "Commentaire"
720c3ad5 498
720c3ad5 499
beef7690
NBV
500 def _offre_emploi(self, obj):
501 return "<a href='%s'>%s</a>" % \
502 (reverse('admin:recrutement_proxyoffreemploi_change',
dc7faf2b 503 args=(obj.candidat.offre_emploi.id,)), obj.candidat.offre_emploi)
beef7690
NBV
504 _offre_emploi.allow_tags = True
505 _offre_emploi.short_description = "Voir offre d'emploi"
beef7690 506
21b02da5
NBV
507 def has_change_permission(self, request, obj=None):
508 """
509 Permettre la visualisation dans la changelist
510 mais interdire l'accès à modifier l'objet si l'évaluateur n'est pas
511 le request.user
512 """
513 return obj is None or request.user == obj.evaluateur.user
514
720c3ad5 515 def queryset(self, request):
beef7690
NBV
516 """
517 Afficher uniquement les évaluations de l'évaluateur, sauf si
518 l'utilisateur est super admin.
519 """
720c3ad5 520 qs = self.model._default_manager.get_query_set()
beef7690 521 user_groupes = request.user.groups.all()
3a542b85
NBV
522 if grp_drh_recrutement in user_groupes or \
523 grp_directeurs_bureau_recrutement in user_groupes or \
524 grp_administrateurs_recrutement in user_groupes or \
d46075cb 525 request.user.is_superuser:
beef7690
NBV
526 return qs.select_related('offre_emploi')
527
ca73c3c6 528 try:
d069cdf1 529 evaluateur = Evaluateur.objects.get(user=request.user)
ca73c3c6
NBV
530 except Evaluateur.DoesNotExist:
531 return qs.none()
532
533 candidats_evaluations = CandidatEvaluation.objects.\
534 filter(evaluateur=evaluateur)
535 candidats_evaluations_ids = [ce.id for ce in \
536 candidats_evaluations.all()]
537 return qs.select_related('offre_emploi').\
538 filter(id__in=candidats_evaluations_ids)
596fe324 539
4e8340cf 540class CourrielTemplateAdmin(VersionAdmin):
a029f641
NBV
541 def get_actions(self, request):
542 actions = super(CourrielTemplateAdmin, self).get_actions(request)
543 del actions['delete_selected']
540dfae4 544 return actions
4e8340cf 545
df59fcab 546admin.site.register(OffreEmploi, OffreEmploiAdmin)
382501c1 547admin.site.register(ProxyOffreEmploi, ProxyOffreEmploiAdmin)
df59fcab 548admin.site.register(Candidat, CandidatAdmin)
382501c1 549admin.site.register(ProxyCandidat, ProxyCandidatAdmin)
720c3ad5 550admin.site.register(CandidatEvaluation, CandidatEvaluationAdmin)
27c81d11 551admin.site.register(Evaluateur, EvaluateurAdmin)
beef7690 552#admin.site.register(AdministrateurRegional, AdministrateurRegionalAdmin)
32834000 553admin.site.register(CourrielTemplate, CourrielTemplateAdmin)