Nice models

This commit is contained in:
Evarin 2017-04-04 00:28:25 +02:00
parent 2447b0558a
commit 71eada8eed
8 changed files with 499 additions and 9 deletions

4
.gitignore vendored
View file

@ -105,4 +105,6 @@ test.py
# Migrations
monstage/migrations/
*.venv/
*~
*~
\#*
.#*

View file

@ -1 +0,0 @@
evarin@Igloo.6706:1491250550

View file

@ -1,5 +1,205 @@
# coding: utf-8
from __future__ import unicode_literals
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.template.defaultfilters import slugify
from django.contrib.gis.db import models as geomodels
# Create your models here.
from taggit.managers import TaggableManager
from djrichtextfield.models import RichTextField
from .utils import choices_length
from .statics import DEPARTEMENTS_DEFAUT, PAYS_OPTIONS, TYPE_LIEU_OPTIONS, TYPE_STAGE_OPTIONS
import ldap
#
# Profil Normalien (extension du modèle User)
#
class Normalien(models.Model):
user = models.OneToOneField(User, related_name="profil")
# Infos spécifiques
nom = models.CharField(u"Nom complet", max_length=255, blank=True)
promotion = models.CharField(u"Promotion", max_length=40, blank=True)
mail = models.CharField(u"Adresse e-mail permanente",
max_length=200, blank=True)
class Meta:
verbose_name = u"Profil élève"
verbose_name_plural = u"Profils élèves"
def __unicode__(self):
return unicode("%s (%s)", self.nom, self.user.username)
# Hook à la création d'un nouvel utilisateur : récupération de ses infos par LDAP
def create_user_profile(sender, instance, created, **kwargs):
if created:
profil = Normalien.objects.get_or_create(user=instance)
try:
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
l = ldap.initialize("ldaps://ldap.spi.ens.fr:636")
l.set_option(ldap.OPT_REFERRALS, 0)
l.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
l.set_option(ldap.OPT_X_TLS,ldap.OPT_X_TLS_DEMAND)
l.set_option( ldap.OPT_X_TLS_DEMAND, True )
l.set_option( ldap.OPT_DEBUG_LEVEL, 255 )
info = l.search_s('dc=spi,dc=ens,dc=fr',
ldap.SCOPE_SUBTREE,
'(uid=%s)' % (instance.username,),
['cn','mailRoutingAddress', 'homeDirectory'])
if len(info) > 0:
infos = info[0][1]
profil.nom = infos.get('cn', [''])[0]
if 'homeDirectory' in infos:
dirs = infos['homeDirectory'][0].split('/')
if dirs[1] == 'users':
annee = dirs[2]
dep = dirs[4]
dep = dict(DEPARTEMENTS_DEFAUT).get('dep')
profil.promotion = u'%s %s' % (dep, annee)
profil.mail = infos.get('mailRoutingAddress',
['%s@clipper.ens.fr'%instance.username])
profil.save()
except ldap.LDAPError:
pass
post_save.connect(create_user_profile, sender=User)
#
# Lieu de stage
#
class Lieu(models.Model):
# Général
nom = models.CharField(u"Nom de l'institution d'accueil",
max_length=250)
type_lieu = models.CharField(u"Type de structure d'accueil",
default="universite",
choices=TYPE_LIEU_OPTIONS,
max_length=choices_length(TYPE_LIEU_OPTIONS))
# Infos géographiques
ville = models.CharField(u"Ville",
max_length=200)
pays = models.CharField(u"Pays",
choices=PAYS_OPTIONS,
max_length=choices_length(PAYS_OPTIONS))
# Coordonnées
objects = geomodels.GeoManager() # Requis par GeoDjango
coord = geomodels.PointField(u"Coordonnées",
geography=True)
def __unicode__(self):
return u"%s (%s)" % (self.name, self.ville)
class Meta:
verbose_name = "Lieu"
verbose_name_plural = "Lieux"
#
# Matières des stages
#
class StageMatiere(models.Model):
nom = models.CharField(u"Nom", max_length=30)
slug = models.SlugField()
class Meta:
verbose_name = "Matière des stages"
verbose_name_plural = "Matières des stages"
def __unicode__(self):
return self.name
def save(self, *args, **kwargs):
if not self.id:
self.slug = slugify(self.nom)
super(StageMatiere, self).save(*args, **kwargs)
#
# Un stage
#
class Stage(models.Model):
# Misc
auteur = models.ForeignKey(Normalien, related_name="stages")
public = models.BooleanField(u"Visible publiquement", default=False)
# Caractéristiques du stage
sujet = models.CharField(u"Sujet", max_length=500)
date_debut = models.DateField(u"Date de début", null=True)
date_fin = models.DateField(u"Date de fin", null=True)
type_stage = models.CharField(u"Type",
default="stage",
choices=TYPE_STAGE_OPTIONS,
max_length=choices_length(TYPE_STAGE_OPTIONS))
thematiques = TaggableManager(u"Thématiques", blank=True)
matieres = models.ManyToManyField(StageMatiere, related_name="stages")
encadrants = models.CharField(u"Encadrants", max_length=500, blank=True)
# Avis
lieux = models.ManyToManyField(Lieu, related_name="stages",
through="AvisLieu")
avis_stage = models.OneToOneField("AvisStage", related_name="stage")
@property
def avis_lieux(self):
return self.avislieu_set.order_by('order')
@property
def lieu_principal(self):
return self.avis_lieux[0].lieu
def __unicode__(self):
return u"%s (par %s)" % (self.sujet, self.auteur.user_id)
class Meta:
verbose_name = "Stage"
#
# Les avis
#
class AvisStage(models.Model):
stage = models.OneToOneField(Stage, related_name="avis_stage")
chapo = models.TextField(u"En quelques mots")
avis_personnes = RichTextField(u"Les encadrants et l'équipe")
avis_sujet = RichTextField(u"Le sujet de stage")
avis_admin = RichTextField(u"Formalités et administration")
les_plus = models.TextField(u"Les plus du stage")
les_moins = models.TextField(u"Les moins du stage")
def __unicode__(self):
return u"Avis sur {%s} par %" % (stage.sujet, stage.auteur.user_id)
class AvisLieu(models.Model):
stage = models.ForeignKey(Stage)
lieu = models.ForeignKey(Lieu)
order = models.IntegerField("Ordre", default=0)
chapo = models.TextField(u"En quelques mots")
avis_lieustage = RichTextField(u"Le lieu du stage")
avis_pratique = RichTextField(u"S'installer - conseils pratiques")
avis_tourisme = RichTextField(u"Dans les parages")
les_plus = models.TextField(u"Les plus du lieu")
les_moins = models.TextField(u"Les moins du lieu")
class Meta:
verbose_name = "Avis sur un lieu de stage"
verbose_name_plural = "Avis sur un lieu de stage"
def __unicode__(self):
return u"Avis sur {%s} par %" % (lieu.nom, stage.auteur.user_id)

270
avisstage/statics.py Normal file
View file

@ -0,0 +1,270 @@
# coding: utf-8
DEPARTEMENTS_DEFAUT = (
('phy', 'Physique'),
('maths', 'Maths'),
('bio', 'Biologie'),
('chimie', 'Chimie'),
('geol', u'Géosciences'),
('dec', 'DEC'),
('info', 'Informatique'),
('litt', u'Littéraire'),
('guests', u'Pensionnaires étrangers'),
('pei', u'PEI'),
)
TYPE_STAGE_OPTIONS = (
('stage', u"Stage"),
)
TYPE_LIEU_OPTIONS = (
('universite', u"Université"),
('entreprise', u"Entreprise"),
('centrerecherche', u"Centre de recherche"),
('administration', u"Administration"),
('autre', u"Autre"),
)
PAYS_OPTIONS = (
("AF", u"Afghanistan"),
("AL", u"Albanie"),
("AQ", u"Antarctique"),
("DZ", u"Algérie"),
("AS", u"Samoa Américaines"),
("AD", u"Andorre"),
("AO", u"Angola"),
("AG", u"Antigua-et-Barbuda"),
("AZ", u"Azerbaïdjan"),
("AR", u"Argentine"),
("AU", u"Australie"),
("AT", u"Autriche"),
("BS", u"Bahamas"),
("BH", u"Bahreïn"),
("BD", u"Bangladesh"),
("AM", u"Arménie"),
("BB", u"Barbade"),
("BE", u"Belgique"),
("BM", u"Bermudes"),
("BT", u"Bhoutan"),
("BO", u"Bolivie"),
("BA", u"Bosnie-Herzégovine"),
("BW", u"Botswana"),
("BV", u"Île Bouvet"),
("BR", u"Brésil"),
("BZ", u"Belize"),
("IO", u"Territoire Britannique de l'Océan Indien"),
("SB", u"Îles Salomon"),
("VG", u"Îles Vierges Britanniques"),
("BN", u"Brunéi Darussalam"),
("BG", u"Bulgarie"),
("MM", u"Myanmar"),
("BI", u"Burundi"),
("BY", u"Bélarus"),
("KH", u"Cambodge"),
("CM", u"Cameroun"),
("CA", u"Canada"),
("CV", u"Cap-vert"),
("KY", u"Îles Caïmanes"),
("CF", u"République Centrafricaine"),
("LK", u"Sri Lanka"),
("TD", u"Tchad"),
("CL", u"Chili"),
("CN", u"Chine"),
("TW", u"Taïwan"),
("CX", u"Île Christmas"),
("CC", u"Îles Cocos (Keeling)"),
("CO", u"Colombie"),
("KM", u"Comores"),
("YT", u"Mayotte"),
("CG", u"République du Congo"),
("CD", u"République Démocratique du Congo"),
("CK", u"Îles Cook"),
("CR", u"Costa Rica"),
("HR", u"Croatie"),
("CU", u"Cuba"),
("CY", u"Chypre"),
("CZ", u"République Tchèque"),
("BJ", u"Bénin"),
("DK", u"Danemark"),
("DM", u"Dominique"),
("DO", u"République Dominicaine"),
("EC", u"Équateur"),
("SV", u"El Salvador"),
("GQ", u"Guinée Équatoriale"),
("ET", u"Éthiopie"),
("ER", u"Érythrée"),
("EE", u"Estonie"),
("FO", u"Îles Féroé"),
("FK", u"Îles (malvinas) Falkland"),
("GS", u"Géorgie du Sud et les Îles Sandwich du Sud"),
("FJ", u"Fidji"),
("FI", u"Finlande"),
("AX", u"Îles Åland"),
("FR", u"France"),
("GF", u"Guyane Française"),
("PF", u"Polynésie Française"),
("TF", u"Terres Australes Françaises"),
("DJ", u"Djibouti"),
("GA", u"Gabon"),
("GE", u"Géorgie"),
("GM", u"Gambie"),
("PS", u"Territoire Palestinien Occupé"),
("DE", u"Allemagne"),
("GH", u"Ghana"),
("GI", u"Gibraltar"),
("KI", u"Kiribati"),
("GR", u"Grèce"),
("GL", u"Groenland"),
("GD", u"Grenade"),
("GP", u"Guadeloupe"),
("GU", u"Guam"),
("GT", u"Guatemala"),
("GN", u"Guinée"),
("GY", u"Guyana"),
("HT", u"Haïti"),
("HM", u"Îles Heard et Mcdonald"),
("VA", u"Saint-Siège (état de la Cité du Vatican)"),
("HN", u"Honduras"),
("HK", u"Hong-Kong"),
("HU", u"Hongrie"),
("IS", u"Islande"),
("IN", u"Inde"),
("ID", u"Indonésie"),
("IR", u"République Islamique d'Iran"),
("IQ", u"Iraq"),
("IE", u"Irlande"),
("IL", u"Israël"),
("IT", u"Italie"),
("CI", u"Côte d'Ivoire"),
("JM", u"Jamaïque"),
("JP", u"Japon"),
("KZ", u"Kazakhstan"),
("JO", u"Jordanie"),
("KE", u"Kenya"),
("KP", u"République Populaire Démocratique de Corée"),
("KR", u"République de Corée"),
("KW", u"Koweït"),
("KG", u"Kirghizistan"),
("LA", u"République Démocratique Populaire Lao"),
("LB", u"Liban"),
("LS", u"Lesotho"),
("LV", u"Lettonie"),
("LR", u"Libéria"),
("LY", u"Jamahiriya Arabe Libyenne"),
("LI", u"Liechtenstein"),
("LT", u"Lituanie"),
("LU", u"Luxembourg"),
("MO", u"Macao"),
("MG", u"Madagascar"),
("MW", u"Malawi"),
("MY", u"Malaisie"),
("MV", u"Maldives"),
("ML", u"Mali"),
("MT", u"Malte"),
("MQ", u"Martinique"),
("MR", u"Mauritanie"),
("MU", u"Maurice"),
("MX", u"Mexique"),
("MC", u"Monaco"),
("MN", u"Mongolie"),
("MD", u"République de Moldova"),
("MS", u"Montserrat"),
("MA", u"Maroc"),
("MZ", u"Mozambique"),
("OM", u"Oman"),
("NA", u"Namibie"),
("NR", u"Nauru"),
("NP", u"Népal"),
("NL", u"Pays-Bas"),
("AN", u"Antilles Néerlandaises"),
("AW", u"Aruba"),
("NC", u"Nouvelle-Calédonie"),
("VU", u"Vanuatu"),
("NZ", u"Nouvelle-Zélande"),
("NI", u"Nicaragua"),
("NE", u"Niger"),
("NG", u"Nigéria"),
("NU", u"Niué"),
("NF", u"Île Norfolk"),
("NO", u"Norvège"),
("MP", u"Îles Mariannes du Nord"),
("UM", u"Îles Mineures Éloignées des États-Unis"),
("FM", u"États Fédérés de Micronésie"),
("MH", u"Îles Marshall"),
("PW", u"Palaos"),
("PK", u"Pakistan"),
("PA", u"Panama"),
("PG", u"Papouasie-Nouvelle-Guinée"),
("PY", u"Paraguay"),
("PE", u"Pérou"),
("PH", u"Philippines"),
("PN", u"Pitcairn"),
("PL", u"Pologne"),
("PT", u"Portugal"),
("GW", u"Guinée-Bissau"),
("TL", u"Timor-Leste"),
("PR", u"Porto Rico"),
("QA", u"Qatar"),
("RE", u"Réunion"),
("RO", u"Roumanie"),
("RU", u"Fédération de Russie"),
("RW", u"Rwanda"),
("SH", u"Sainte-Hélène"),
("KN", u"Saint-Kitts-et-Nevis"),
("AI", u"Anguilla"),
("LC", u"Sainte-Lucie"),
("PM", u"Saint-Pierre-et-Miquelon"),
("VC", u"Saint-Vincent-et-les Grenadines"),
("SM", u"Saint-Marin"),
("ST", u"Sao Tomé-et-Principe"),
("SA", u"Arabie Saoudite"),
("SN", u"Sénégal"),
("SC", u"Seychelles"),
("SL", u"Sierra Leone"),
("SG", u"Singapour"),
("SK", u"Slovaquie"),
("VN", u"Viet Nam"),
("SI", u"Slovénie"),
("SO", u"Somalie"),
("ZA", u"Afrique du Sud"),
("ZW", u"Zimbabwe"),
("ES", u"Espagne"),
("EH", u"Sahara Occidental"),
("SD", u"Soudan"),
("SR", u"Suriname"),
("SJ", u"Svalbard etÎle Jan Mayen"),
("SZ", u"Swaziland"),
("SE", u"Suède"),
("CH", u"Suisse"),
("SY", u"République Arabe Syrienne"),
("TJ", u"Tadjikistan"),
("TH", u"Thaïlande"),
("TG", u"Togo"),
("TK", u"Tokelau"),
("TO", u"Tonga"),
("TT", u"Trinité-et-Tobago"),
("AE", u"Émirats Arabes Unis"),
("TN", u"Tunisie"),
("TR", u"Turquie"),
("TM", u"Turkménistan"),
("TC", u"Îles Turks et Caïques"),
("TV", u"Tuvalu"),
("UG", u"Ouganda"),
("UA", u"Ukraine"),
("MK", u"L'ex-République Yougoslave de Macédoine"),
("EG", u"Égypte"),
("GB", u"Royaume-Uni"),
("IM", u"Île de Man"),
("TZ", u"République-Unie de Tanzanie"),
("US", u"États-Unis"),
("VI", u"Îles Vierges des États-Unis"),
("BF", u"Burkina Faso"),
("UY", u"Uruguay"),
("UZ", u"Ouzbékistan"),
("VE", u"Venezuela"),
("WF", u"Wallis et Futuna"),
("WS", u"Samoa"),
("YE", u"Yémen"),
("CS", u"Serbie-et-Monténégro"),
("ZM", u"Zambie"),
)

4
avisstage/utils.py Normal file
View file

@ -0,0 +1,4 @@
# coding: utf-8
def choices_length (choices):
return reduce (lambda m, choice: max (m, len (choice[0])), choices, 0)

View file

@ -27,8 +27,9 @@ INSTALLED_APPS = (
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.gis',
'django-taggit',
'djrichtextfield',
'taggit',
'avisstage'
)
@ -53,9 +54,9 @@ WSGI_APPLICATION = 'experiENS.wsgi.application'
# Internationalization
# https://docs.djangoproject.com/en/1.7/topics/i18n/
LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'fr-fr'
TIME_ZONE = 'UTC'
TIME_ZONE = 'Europe/Paris'
USE_I18N = True
@ -68,3 +69,14 @@ USE_TZ = True
# https://docs.djangoproject.com/en/1.7/howto/static-files/
STATIC_URL = '/static/'
DJRICHTEXTFIELD_CONFIG = {
'js': ['//tinymce.cachefly.net/4.1/tinymce.min.js'],
'init_template': 'djrichtextfield/init/tinymce.js',
'settings': {
'menubar': False,
'plugins': 'link image',
'toolbar': 'bold italic | link image | removeformat',
'width': 700
}
}

View file

@ -1,10 +1,12 @@
from django.conf.urls import patterns, include, url
from django.contrib import admin
urlpatterns = patterns('',
urlpatterns = patterns(
'',
# Examples:
# url(r'^$', 'experiENS.views.home', name='home'),
# url(r'^blog/', include('blog.urls')),
url(r'^djrichtextfield/', include('djrichtextfield.urls'))
url(r'^admin/', include(admin.site.urls)),
)

View file

@ -2,3 +2,4 @@ django
django-cas-ng
django-taggit
python-ldap
django-richtextfield