Version 0.17
[auf_django_references.git] / auf / django / references / models.py
1 # -=- encoding: utf-8 -=-
2
3 from django.conf import settings
4 from django.db import models
5
6 MANAGED = getattr(settings, 'AUF_REFERENCES_MANAGED', False)
7
8
9 ### Gestion des actifs/inactifs
10
11 class ActifsManager(models.Manager):
12 """
13 Manager pour ``ActifsModel``.
14 """
15
16 def get_query_set(self):
17 return super(ActifsManager, self).get_query_set().filter(actif=True)
18
19
20 class ActifsModel(models.Model):
21 """
22 Modèle faisant la gestion des objets actifs/inactifs.
23
24 Le manager par défaut ne liste que les objets actifs. Pour avoir tous
25 les objets, utiliser le manager ``avec_inactifs``.
26 """
27 actif = models.BooleanField(default=True, editable=False)
28
29 # Managers
30 objects = ActifsManager()
31 avec_inactifs = models.Manager()
32
33 class Meta:
34 abstract = True
35
36
37 ### Modèles pour les données de référence
38
39 class Employe(ActifsModel):
40 """
41 Personne en contrat d'employé (CDD ou CDI) à l'AUF
42 """
43 GENRE_CHOICES = (
44 (u'h', u'Homme'),
45 (u'f', u'Femme'),
46 )
47
48 nom = models.CharField(max_length=255)
49 prenom = models.CharField(max_length=255)
50 implantation = models.ForeignKey(
51 'references.Implantation',
52 db_column='implantation',
53 related_name='lieu_travail_theorique_de'
54 )
55 implantation_physique = models.ForeignKey(
56 'references.Implantation',
57 db_column='implantation_physique',
58 related_name='lieu_travail_reel_de'
59 )
60 courriel = models.CharField(max_length=255, null=True, blank=True)
61 genre = models.CharField(max_length=3, choices=GENRE_CHOICES)
62 fonction = models.CharField(max_length=255, null=True, blank=True)
63 telephone_poste = models.CharField(max_length=255, null=True, blank=True)
64 telephone_ip = models.CharField(max_length=255, null=True, blank=True)
65 responsable = models.ForeignKey(
66 'references.Employe',
67 db_column='responsable',
68 related_name='responsable_de',
69 null=True, blank=True
70 )
71 mandat_debut = models.DateField(null=True, blank=True)
72 mandat_fin = models.DateField(null=True, blank=True)
73 date_entree = models.DateField(null=True, blank=True)
74 service = models.ForeignKey('references.Service', db_column='service')
75 poste_type_1 = models.ForeignKey(
76 'references.PosteType',
77 null=True, blank=True,
78 db_column='poste_type_1',
79 related_name='poste_type_1'
80 )
81 poste_type_2 = models.ForeignKey(
82 'references.PosteType',
83 null=True, blank=True,
84 db_column='poste_type_2',
85 related_name='poste_type_2'
86 )
87
88 class Meta:
89 db_table = u'ref_employe'
90 ordering = ['nom']
91 managed = MANAGED
92
93 def __unicode__(self):
94 return u"%s, %s [%d]" % (self.nom, self.prenom, self.id)
95
96
97 class Authentification(ActifsModel):
98 """
99 Authentification
100 """
101 id = models.ForeignKey(
102 'references.Employe', primary_key=True, db_column='id'
103 )
104 courriel = models.CharField(max_length=255, unique=True)
105 motdepasse = models.CharField(max_length=255)
106
107 class Meta:
108 db_table = u'ref_authentification'
109 ordering = ['id']
110 managed = MANAGED
111
112 def __unicode__(self):
113 return u"%s [%d]" % (self.courriel, self.id)
114
115
116 class Service(ActifsModel):
117 """
118 Services (donnée de référence, source: SGRH).
119 """
120 nom = models.CharField(max_length=255)
121
122 class Meta:
123 db_table = u'ref_service'
124 ordering = ['nom']
125 managed = MANAGED
126
127 def __unicode__(self):
128 return "%s (%s)" % (self.nom, self.id)
129
130
131 class PosteType(ActifsModel):
132 """
133 Postes types (donnée de référence, source: SGRH).
134 """
135 nom = models.CharField(max_length=255)
136
137 class Meta:
138 db_table = u'ref_poste_type'
139 managed = MANAGED
140
141 def __unicode__(self):
142 return "%s (%s)" % (self.nom, self.id)
143
144
145 class GroupeArh(ActifsModel):
146 employe = models.ForeignKey('references.Employe', db_column='employe')
147
148 class Meta:
149 db_table = u'ref_groupe_arh'
150 managed = MANAGED
151
152
153 class GroupeDirRegion(ActifsModel):
154 employe = models.ForeignKey('references.Employe', db_column='employe')
155 region = models.ForeignKey('references.Region', db_column='region')
156
157 class Meta:
158 db_table = u'ref_groupe_dir_region'
159 managed = MANAGED
160
161
162 class GroupeAdmRegion(ActifsModel):
163 employe = models.ForeignKey('references.Employe', db_column='employe')
164 region = models.ForeignKey('references.Region', db_column='region')
165
166 class Meta:
167 db_table = u'ref_groupe_adm_region'
168 managed = MANAGED
169
170
171 class GroupeRespImplantation(ActifsModel):
172 employe = models.ForeignKey('references.Employe', db_column='employe')
173 implantation = models.ForeignKey(
174 'references.Implantation', db_column='implantation'
175 )
176 type = models.CharField(max_length=255, blank=True, null=True)
177
178 class Meta:
179 db_table = u'ref_groupe_resp_implantation'
180 managed = MANAGED
181
182
183 class GroupeDirProgramme(ActifsModel):
184 employe = models.ForeignKey('references.Employe', db_column='employe')
185 service = models.ForeignKey('references.Service', db_column='service')
186
187 class Meta:
188 db_table = u'ref_groupe_dir_programme'
189 managed = MANAGED
190
191
192 class GroupeDirDelegProgrammeReg(ActifsModel):
193 employe = models.ForeignKey('references.Employe', db_column='employe')
194 region = models.ForeignKey('references.Region', db_column='region')
195
196 class Meta:
197 db_table = u'ref_groupe_dir_deleg_programme_reg'
198 managed = MANAGED
199
200
201 class GroupeComptable(ActifsModel):
202 employe = models.ForeignKey('references.Employe', db_column='employe')
203
204 class Meta:
205 db_table = u'ref_groupe_comptable'
206 managed = MANAGED
207
208
209 class GroupeComptableRegional(ActifsModel):
210 employe = models.ForeignKey('references.Employe', db_column='employe')
211
212 class Meta:
213 db_table = u'ref_groupe_comptable_regional'
214 managed = MANAGED
215
216
217 class GroupeComptableLocal(ActifsModel):
218 employe = models.ForeignKey('references.Employe', db_column='employe')
219
220 class Meta:
221 db_table = u'ref_groupe_comptable_local'
222 managed = MANAGED
223
224
225 class Discipline(ActifsModel):
226 """
227 ATTENTION: DÉSUET
228 Discipline (donnée de référence, source: SQI).
229 Une discipline est une catégorie de savoirs scientifiques.
230 Le conseil scientifique fixe la liste des disciplines.
231 """
232 code = models.CharField(max_length=255, unique=True)
233 nom = models.CharField(max_length=255)
234 nom_long = models.CharField(max_length=255, blank=True)
235 nom_court = models.CharField(max_length=255, blank=True)
236
237 class Meta:
238 db_table = u'ref_discipline'
239 ordering = ['nom']
240 managed = MANAGED
241
242 def __unicode__(self):
243 return "%s - %s" % (self.code, self.nom)
244
245
246 class Programme(ActifsModel):
247 """
248 ATTENTION: DÉSUET
249 Programme (donnée de référence, source: SQI).
250 Structure interne par laquelle l'AUF exécute ses projets et activités,
251 dispense ses produits et ses services.
252 """
253 code = models.CharField(max_length=255, unique=True)
254 nom = models.CharField(max_length=255)
255 nom_long = models.CharField(max_length=255, blank=True)
256 nom_court = models.CharField(max_length=255, blank=True)
257
258 class Meta:
259 db_table = u'ref_programme'
260 managed = MANAGED
261
262 def __unicode__(self):
263 return "%s - %s" % (self.code, self.nom)
264
265
266 #PROGRAMMATION QUADRIENNALLE
267
268 class Projet(ActifsModel):
269 """
270 Projet (donnée de référence, source: programmation-quadriennalle).
271 """
272 SERVICE_CHOICES = (
273 (u'1',
274 u"Direction de la langue et de la communication scientifique "
275 u"en français"),
276 (u'2', u"Direction du développement et de la valorisation"),
277 (u'3',
278 u"Direction de l'innovation pédagogique et de l'économie "
279 u"de la connaissance"),
280 (u'4', u"Direction du renforcement des capacités scientifiques"),
281 )
282
283 code = models.CharField(max_length=255, unique=True)
284 nom = models.CharField(max_length=255)
285 presentation = models.TextField(null=True, blank=True)
286 partenaires = models.TextField(null=True, blank=True)
287 service = models.CharField(
288 max_length=255, choices=SERVICE_CHOICES, blank=True, null=True
289 )
290 objectif_specifique = models.ForeignKey(
291 'references.ObjectifSpecifique',
292 blank=True, null=True,
293 db_column='objectif_specifique'
294 )
295 implantation = models.ForeignKey('references.Implantation', null=True,
296 blank=True, db_column='implantation')
297 etablissement = models.ForeignKey('references.Etablissement', null=True,
298 blank=True, db_column='etablissement')
299 date_debut = models.DateField(null=True, blank=True)
300 date_fin = models.DateField(null=True, blank=True)
301
302 class Meta:
303 db_table = u'ref_projet'
304 ordering = ['nom']
305 managed = MANAGED
306
307 def __unicode__(self):
308 return "%s - %s" % (self.code, self.nom)
309
310
311 class ProjetComposante(ActifsModel):
312 """
313 Composantes des projets (source: programmation-quadriennalle)
314 """
315 code = models.CharField(max_length=10)
316 nom = models.CharField(max_length=255)
317 nom_court = models.CharField(max_length=255, null=True, blank=True)
318 description = models.TextField(null=True, blank=True)
319 projet = models.ForeignKey('references.Projet', db_column='projet')
320
321 class Meta:
322 db_table = u'ref_projet_composante'
323 ordering = ['nom']
324 managed = MANAGED
325
326 def __unicode__(self):
327 return "%s - %s" % (self.code, self.nom)
328
329
330 class UniteProjet(ActifsModel):
331 """
332 Unités de projet (source: programmation-quadriennalle)
333 """
334 code = models.CharField(max_length=10, unique=True)
335 nom = models.CharField(max_length=255)
336
337 class Meta:
338 db_table = u'ref_unite_projet'
339 ordering = ['nom']
340 managed = MANAGED
341
342 def __unicode__(self):
343 return "%s - %s" % (self.code, self.nom)
344
345
346 class ObjectifSpecifique(ActifsModel):
347 nom = models.CharField(max_length=255)
348 objectif_strategique = models.ForeignKey(
349 'references.ObjectifStrategique', db_column='objectif_strategique'
350 )
351
352 class Meta:
353 db_table = u'ref_objectif_specifique'
354 ordering = ['nom']
355 managed = MANAGED
356
357 def __unicode__(self):
358 return "%s - %s" % (self.id, self.nom)
359
360
361 class ObjectifStrategique(ActifsModel):
362 nom = models.CharField(max_length=255)
363 description = models.TextField(null=True, blank=True)
364
365 class Meta:
366 db_table = u'ref_objectif_strategique'
367 ordering = ['nom']
368 managed = MANAGED
369
370 def __unicode__(self):
371 return "%s - %s" % (self.id, self.nom)
372
373
374 class Thematique(ActifsModel):
375 nom = models.CharField(max_length=255)
376
377 class Meta:
378 db_table = u'ref_thematique'
379 ordering = ['nom']
380 managed = MANAGED
381
382 def __unicode__(self):
383 return "%s - %s" % (self.id, self.nom)
384
385
386 class ProjetUp(ActifsModel):
387 """
388 Projet-unité de projet (source: coda)
389 => codes budgétaires
390 """
391 code = models.CharField(max_length=255, unique=True)
392 nom = models.CharField(max_length=255)
393 nom_court = models.CharField(max_length=255, blank=True)
394
395 class Meta:
396 managed = MANAGED
397
398
399 class Poste(ActifsModel):
400 """
401 ATTENTION: DÉSUET
402 Poste (donnée de référence, source: CODA).
403 Un poste est une catégorie destinée à venir raffiner un projet.
404 """
405 code = models.CharField(max_length=255, unique=True)
406 nom = models.CharField(max_length=255)
407 type = models.CharField(max_length=255, blank=True)
408
409 class Meta:
410 db_table = u'ref_poste'
411 managed = MANAGED
412
413 def __unicode__(self):
414 return "%s - %s (%s)" % (self.code, self.nom, self.type)
415
416
417 class ProjetPoste(ActifsModel):
418 """
419 ATTENTION: DÉSUET
420 Projet-poste (donnée de référence, source: CODA).
421 Un projet-poste consiste en une raffinement d'un projet par un poste
422 (budgétaire). Subdivision utile pour le suivi budgétaire et comptable.
423 """
424 code = models.CharField(max_length=255, unique=True)
425 code_projet = models.ForeignKey(
426 'references.Projet', to_field='code', db_column='code_projet'
427 )
428 code_poste = models.ForeignKey(
429 'references.Poste', to_field='code', db_column='code_poste'
430 )
431 code_bureau = models.ForeignKey(
432 'references.Bureau', to_field='code', db_column='code_bureau'
433 )
434 code_programme = models.ForeignKey(
435 'references.Programme', to_field='code', db_column='code_programme'
436 )
437
438 class Meta:
439 db_table = u'ref_projet_poste'
440 managed = MANAGED
441
442 def __unicode__(self):
443 return "%s" % (self.code)
444
445
446 class Region(ActifsModel):
447 """
448 Région (donnée de référence, source: referentiels_spip).
449 Une région est une subdivision géographique du monde pour la gestion de
450 l'AUF.
451 """
452 code = models.CharField(max_length=255, unique=True)
453 nom = models.CharField(max_length=255, db_index=True)
454 implantation_bureau = models.ForeignKey(
455 'references.Implantation', db_column='implantation_bureau',
456 related_name='gere_region', null=True, blank=True
457 )
458
459 class Meta:
460 db_table = u'ref_region'
461 ordering = ['nom']
462 verbose_name = u"région"
463 verbose_name_plural = u"régions"
464 managed = MANAGED
465
466 def __unicode__(self):
467 return "%s (%s)" % (self.nom, self.code)
468
469
470 class Bureau(ActifsModel):
471 """
472 Bureau (donnée de référence, source: SQI).
473
474 Référence legacy entre la notion de région et celle d'implantation
475 responsable des régions et du central.
476
477 Un bureau est :
478 - soit le bureau régional d'une région (implantations de type 'Bureau')
479 - soit la notion unique de Service central pour les 2 implantations
480 centrales (implantations de type 'Service central' et 'Siege').
481
482 Ne pas confondre avec les seuls 'bureaux régionaux'.
483 """
484 code = models.CharField(max_length=255, unique=True)
485 nom = models.CharField(max_length=255)
486 nom_court = models.CharField(max_length=255, blank=True)
487 nom_long = models.CharField(max_length=255, blank=True)
488 implantation = models.ForeignKey(
489 'references.Implantation', db_column='implantation'
490 )
491 region = models.ForeignKey('references.Region', db_column='region')
492
493 class Meta:
494 db_table = u'ref_bureau'
495 ordering = ['nom']
496 verbose_name = u"bureau"
497 verbose_name_plural = u"bureaux"
498 managed = MANAGED
499
500 def __unicode__(self):
501 return "%s (%s)" % (self.nom, self.code)
502
503
504 class Implantation(ActifsModel):
505 """
506 Implantation (donnée de référence, source: Implantus)
507
508 Une implantation est un endroit où l'AUF est présente et offre des
509 services spécifiques. Deux implantations peuvent être au même endroit
510 physique.
511 """
512 STATUT_CHOICES = (
513 (0, u'Fermée ou jamais ouverte'),
514 (1, u'Ouverte'),
515 (2, u'Ouverture imminente'),
516 (3, u'En projet')
517 )
518
519 nom = models.CharField(max_length=255)
520 nom_court = models.CharField(max_length=255, blank=True)
521 nom_long = models.CharField(max_length=255, blank=True)
522 type = models.CharField(max_length=255)
523 bureau_rattachement = models.ForeignKey(
524 'references.Implantation', db_column='bureau_rattachement'
525 )
526 region = models.ForeignKey('references.Region', db_column='region')
527 fuseau_horaire = models.CharField(max_length=255, blank=True)
528 code_meteo = models.CharField(max_length=255, blank=True)
529 # responsable
530 responsable_implantation = models.IntegerField(null=True, blank=True)
531 # adresse postale
532 adresse_postale_precision_avant = models.CharField(
533 max_length=255, blank=True, null=True
534 )
535 adresse_postale_no = models.CharField(max_length=30, blank=True, null=True)
536 adresse_postale_rue = models.CharField(
537 max_length=255, blank=True, null=True
538 )
539 adresse_postale_bureau = models.CharField(
540 max_length=255, blank=True, null=True
541 )
542 adresse_postale_precision = models.CharField(
543 max_length=255, blank=True, null=True
544 )
545 adresse_postale_boite_postale = models.CharField(
546 max_length=255, blank=True, null=True
547 )
548 adresse_postale_ville = models.CharField(max_length=255)
549 adresse_postale_code_postal = models.CharField(
550 max_length=20, blank=True, null=True
551 )
552 adresse_postale_code_postal_avant_ville = models.NullBooleanField()
553 adresse_postale_region = models.CharField(
554 max_length=255, blank=True, null=True
555 )
556 adresse_postale_pays = models.ForeignKey(
557 'references.Pays', to_field='code',
558 db_column='adresse_postale_pays',
559 related_name='impl_adresse_postale'
560 )
561 # adresse physique
562 adresse_physique_precision_avant = models.CharField(
563 max_length=255, blank=True
564 )
565 adresse_physique_no = models.CharField(max_length=30, blank=True)
566 adresse_physique_rue = models.CharField(max_length=255, blank=True)
567 adresse_physique_bureau = models.CharField(max_length=255, blank=True)
568 adresse_physique_precision = models.CharField(max_length=255, blank=True)
569 adresse_physique_ville = models.CharField(max_length=255)
570 adresse_physique_code_postal = models.CharField(max_length=30, blank=True)
571 adresse_physique_code_postal_avant_ville = models.NullBooleanField()
572 adresse_physique_region = models.CharField(max_length=255, blank=True)
573 adresse_physique_pays = models.ForeignKey(
574 'references.Pays', to_field='code',
575 db_column='adresse_physique_pays',
576 related_name='impl_adresse_physique'
577 )
578 # autres coordonnées
579 telephone = models.CharField(max_length=255, blank=True)
580 telephone_interne = models.CharField(max_length=255, blank=True)
581 fax = models.CharField(max_length=255, blank=True)
582 fax_interne = models.CharField(max_length=255, blank=True)
583 courriel = models.EmailField(blank=True)
584 courriel_interne = models.EmailField(blank=True)
585 url = models.URLField(verify_exists=False, max_length=255, blank=True)
586 # traitement
587 statut = models.IntegerField(choices=STATUT_CHOICES)
588 date_ouverture = models.DateField(null=True, blank=True)
589 date_inauguration = models.DateField(null=True, blank=True)
590 date_extension = models.DateField(null=True, blank=True)
591 date_fermeture = models.DateField(null=True, blank=True)
592 hebergement_etablissement = models.CharField(max_length=255, blank=True)
593 hebergement_convention = models.NullBooleanField()
594 hebergement_convention_date = models.DateField(null=True, blank=True)
595 remarque = models.TextField()
596 commentaire = models.CharField(max_length=255, blank=True)
597 # meta
598 modif_date = models.DateField()
599
600 class Managers:
601
602 class Ouvertes(ActifsManager):
603
604 def get_query_set(self):
605 return super(Implantation.Managers.Ouvertes, self) \
606 .get_query_set() \
607 .filter(statut=1)
608
609 objects = ActifsManager()
610 ouvertes = Managers.Ouvertes()
611
612 class Meta:
613 db_table = u'ref_implantation'
614 ordering = ['nom']
615 managed = MANAGED
616
617 def __unicode__(self):
618 return "%s (%d)" % (self.nom, self.id)
619
620
621 class Pays(ActifsModel):
622 """
623 Pays (donnée de référence, source: SQI).
624
625 Liste AUF basée sur la liste ISO-3166-1.
626 """
627 NORD_SUD_CHOICES = (
628 (u'Nord', u'Nord'),
629 (u'Sud', u'Sud'),
630 )
631 DEVELOPPEMENT_CHOICES = (
632 (u'Elevé', u'Elevé'),
633 (u'Faible', u'Faible'),
634 (u'Intermédiaire', u'Intermédiaire'),
635 (u'inconnu', u'Inconnu'),
636 )
637
638 code = models.CharField(max_length=2, unique=True)
639 code_iso3 = models.CharField(max_length=3, unique=True)
640 nom = models.CharField(max_length=255)
641 region = models.ForeignKey('references.Region', db_column='region')
642 code_bureau = models.ForeignKey('references.Bureau', to_field='code',
643 db_column='code_bureau', blank=True,
644 null=True)
645 nord_sud = models.CharField(
646 max_length=255, blank=True, null=True,
647 )
648 developpement = models.CharField(max_length=255, blank=True, null=True)
649 monnaie = models.CharField(max_length=255, blank=True, null=True)
650
651 class Meta:
652 db_table = u'ref_pays'
653 ordering = ['nom']
654 verbose_name = u"pays"
655 verbose_name_plural = u"pays"
656 managed = MANAGED
657
658 def __unicode__(self):
659 return "%s (%s)" % (self.nom, self.code)
660
661
662 class _Etablissement(ActifsModel):
663 """
664 Superclasse pour les modèles ``Etablissement`` et ``EtablissementBase``
665 """
666 STATUT_CHOICES = (
667 ('T', 'Titulaire'),
668 ('A', 'Associé'),
669 ('C', 'Candidat'),
670 )
671 QUALITE_CHOICES = (
672 ('ESR', "Établissement d'enseignement supérieur et de recherche"),
673 ('CIR', "Centre ou institution de recherche"),
674 ('RES', "Réseau"),
675 )
676
677 # Infos de base
678 nom = models.CharField(max_length=255)
679 sigle = models.CharField(max_length=16, blank=True)
680 pays = models.ForeignKey(
681 'references.Pays', to_field='code', db_column='pays',
682 related_name='+'
683 )
684 region = models.ForeignKey(
685 'references.Region', db_column='region', blank=True, null=True,
686 related_name='+', verbose_name='région'
687 )
688 implantation = models.ForeignKey(
689 'references.Implantation', db_column='implantation',
690 related_name='+', blank=True, null=True
691 )
692 description = models.TextField(blank=True)
693 historique = models.TextField(blank=True)
694
695 # Membership
696 membre = models.BooleanField()
697 membre_adhesion_date = models.DateField(
698 null=True, blank=True, verbose_name="date d'adhésion"
699 )
700 statut = models.CharField(
701 max_length=1, choices=STATUT_CHOICES, blank=True, null=True
702 )
703 qualite = models.CharField(
704 max_length=3, choices=QUALITE_CHOICES, verbose_name="qualité",
705 blank=True, null=True
706 )
707
708 # Responsable
709 responsable_genre = models.CharField(
710 max_length=1, blank=True, verbose_name='genre'
711 )
712 responsable_nom = models.CharField(
713 max_length=255, blank=True, verbose_name='nom'
714 )
715 responsable_prenom = models.CharField(
716 max_length=255, blank=True, verbose_name='prénom'
717 )
718 responsable_fonction = models.CharField(
719 max_length=255, blank=True, verbose_name='fonction'
720 )
721
722 # Adresse
723 adresse = models.CharField(max_length=255, blank=True)
724 code_postal = models.CharField(max_length=20, blank=True,
725 verbose_name='code postal')
726 cedex = models.CharField(max_length=20, blank=True, verbose_name='CEDEX')
727 ville = models.CharField(max_length=255, blank=True)
728 province = models.CharField(max_length=255, blank=True)
729 telephone = models.CharField(max_length=255, blank=True,
730 verbose_name='téléphone')
731 fax = models.CharField(max_length=255, blank=True)
732 url = models.URLField(verify_exists=False, max_length=255, null=True,
733 blank=True, verbose_name='URL')
734
735 # Meta-données
736 date_modification = models.DateField(verbose_name='date de modification',
737 blank=True, null=True)
738 commentaire = models.TextField(blank=True)
739
740 class Meta:
741 abstract = True
742 ordering = ['pays__nom', 'nom']
743 managed = MANAGED
744
745 def __unicode__(self):
746 return "%s - %s" % (self.pays.nom, self.nom)
747
748
749 class Etablissement(_Etablissement):
750 """
751 Établissement (donnée de référence, source: GDE).
752
753 Un établissement peut être une université, un centre de recherche, un
754 réseau d'établissement... Un établissement peut être membre de l'AUF ou
755 non.
756 """
757 class Meta(_Etablissement.Meta):
758 db_table = u'ref_etablissement'
759 managed = MANAGED
760
761
762 class EtablissementBase(_Etablissement):
763 """
764 Modèle de base pour créer des établissements locaux pouvant être
765 liés à des établissements des données de référence.
766 """
767 ref = models.OneToOneField(Etablissement, blank=True, null=True,
768 related_name='%(app_label)s_%(class)s')
769
770 class Meta:
771 abstract = True
772
773 def save(self, *args, **kwargs):
774 if self.ref and not self.pk:
775 # Nouvel établissement faisant référence à un établissement dans
776 # les références. On copie tous les champs.
777 for f in self.ref._meta.fields:
778 if f.attname != 'id':
779 setattr(self, f.attname, getattr(self.ref, f.attname))
780 super(EtablissementBase, self).save(*args, **kwargs)