#! python3 # noqa: E265 # noqa E265
"""
Application database models.
"""
# #############################################################################
# ########## Libraries #############
# ##################################
# standard library
from datetime import datetime
from django.core.validators import MaxLengthValidator
# Django
from django.db import models
from django.template.defaultfilters import truncatechars
# #############################################################################
# ########### Models ###############
# ##################################
[docs]class Contract(models.Model):
abbrv = models.CharField(
max_length=20,
db_index=True,
unique=True,
primary_key=True,
verbose_name="Abbréviation",
)
name = models.CharField(max_length=75, verbose_name="Intitulé complet")
comment = models.TextField(blank=True, verbose_name="Commentaire")
created = models.DateTimeField("Ajouté le", auto_now_add=True)
updated = models.DateTimeField("Modifié le", auto_now=True)
def __str__(self):
return self.abbrv
class Meta:
verbose_name = "Type de contrat"
verbose_name_plural = "Types de contrats"
ordering = ["abbrv"]
[docs]class ContractVariations(models.Model):
# VARIABLES
ND = "UNDEFINED"
# FIELDS
label = models.CharField(
max_length=200,
null=False,
unique=True,
verbose_name="Variante du libellé",
)
name = models.ForeignKey(
Contract,
verbose_name="Type de contrat correspondant",
default=ND,
on_delete=models.SET_DEFAULT,
)
def __str__(self):
return self.label
class Meta:
verbose_name = "Variante du type de contrat"
verbose_name_plural = "Variantes des types de contrats"
[docs]class Technology(models.Model):
# LICENSE
OSS = "OSS"
PROPRIETARY = "PROPRIETARY"
ND = "UNDEFINED"
TYPE_LICENSE = (
(OSS, "Libre"),
(PROPRIETARY, "Propriétaire"),
(ND, "Indéfini"),
)
# TYPE
DEV = "LANGUAGE"
SOFTWARE = "SOFTWARE"
TYPE_SOFT = (
(DEV, "Language de programmation"),
(SOFTWARE, "Logiciel"),
(ND, "Indéfini"),
)
# FIELDS
name = models.CharField(
max_length=200, db_index=True, unique=True, verbose_name="Nom"
)
license = models.CharField(
max_length=20,
choices=TYPE_LICENSE,
default=ND,
verbose_name="Licence principale",
)
type_soft = models.CharField(
max_length=50, choices=TYPE_SOFT, default=ND, verbose_name="Catégorie"
)
created = models.DateTimeField("Ajoutée le", auto_now_add=True)
updated = models.DateTimeField("Modifiée le", auto_now=True)
def __str__(self):
return self.name
class Meta:
verbose_name = "Technologie"
verbose_name_plural = "Technologies"
ordering = [
"name",
]
[docs]class TechnologyVariations(models.Model):
# VARIABLES
ND = "UNDEFINED"
# FIELDS
label = models.CharField(
max_length=200,
default=ND,
null=False,
unique=True,
verbose_name="Variante du libellé",
)
name = models.ForeignKey(
Technology,
verbose_name="Technologie correspondante",
default=ND,
on_delete=models.SET_DEFAULT,
)
def __str__(self):
return self.label
class Meta:
verbose_name = "Variante des technologies"
verbose_name_plural = "Variantes des technologies"
[docs]class Place(models.Model):
# SCALE
DPT = "DEPARTEMENT"
TOM = "TOM"
COUNTRY = "COUNTRY"
UNDEFINED = "UNDEFINED"
SCALES = (
(DPT, "Département français"),
(TOM, "Territoire français"),
(COUNTRY, "Pays"),
(UNDEFINED, "Indéfini"),
)
# FIELDS
name = models.CharField(
max_length=100, unique=True, primary_key=True, verbose_name="Nom"
)
code = models.CharField(
max_length=5,
unique=True,
verbose_name="Code",
help_text="Code du département ou <a href='https://fr.wikipedia.org/wiki/ISO_3166-1#Table_de_codage'>code ISO à 3 lettres pour un pays (voir sur Wikipédia)</a>.",
)
scale = models.CharField(
max_length=50,
choices=SCALES,
default=DPT,
db_index=True,
blank=True,
verbose_name="Echelle",
)
created = models.DateTimeField("Ajouté le", auto_now_add=True)
updated = models.DateTimeField("Modifié le", auto_now=True)
def __str__(self):
return self.name
class Meta:
verbose_name = "Lieu"
verbose_name_plural = "Lieux"
ordering = [
"code",
]
[docs]class PlaceVariations(models.Model):
# VARIABLES
ND = "UNDEFINED"
# FIELDS
label = models.CharField(
max_length=200,
default=ND,
null=False,
unique=True,
verbose_name="Variante du libellé",
)
name = models.ForeignKey(
Place,
verbose_name="Lieu correspondant",
default=ND,
on_delete=models.SET_DEFAULT,
)
def __str__(self):
return self.label
class Meta:
verbose_name = "Variante de lieu"
verbose_name_plural = "Variantes des lieux"
[docs]class JobPosition(models.Model):
# FIELDS
name = models.CharField(
max_length=100, unique=True, primary_key=True, verbose_name="Intitulé"
)
comment = models.CharField(max_length=5, blank=True, verbose_name="Description")
created = models.DateTimeField("Créé le", auto_now_add=True)
updated = models.DateTimeField("Modifié le", auto_now=True)
def __str__(self):
return self.name
class Meta:
verbose_name = "Métier"
verbose_name_plural = "Métiers"
ordering = [
"name",
]
[docs]class JobPositionVariations(models.Model):
# VARIABLES
ND = "UNDEFINED"
# FIELDS
label = models.CharField(
max_length=200,
default=ND,
null=False,
unique=True,
verbose_name="Variante du libellé",
)
name = models.ForeignKey(
JobPosition,
verbose_name="Métier correspondant",
default=ND,
on_delete=models.SET_DEFAULT,
)
def __str__(self):
return self.label
class Meta:
verbose_name = "Variante de métier"
verbose_name_plural = "Variantes des métiers"
[docs]class Source(models.Model):
# FIELDS
name = models.CharField(
max_length=50,
db_index=True,
unique=True,
default="GEOREZO_RSS",
verbose_name="Nom",
)
url = models.URLField(blank=True, verbose_name="Adresse web")
comment = models.TextField(blank=True, verbose_name="Commentaire")
created = models.DateTimeField("Ajoutée le", auto_now_add=True)
updated = models.DateTimeField("Modifiée le", auto_now=True)
def __str__(self):
return self.name
class Meta:
verbose_name = "Source de l'offre"
verbose_name_plural = "Sources"
[docs]class Offer(models.Model):
# timestamps
created = models.DateTimeField("Ajoutée le", auto_now_add=True)
updated = models.DateTimeField("Modifiée le", auto_now=True)
# relations with raw offer
id_rss = models.IntegerField(blank=True, db_index=True, unique=True)
raw_offer = models.OneToOneField(
GeorezoRSS, null=True, on_delete=models.SET_NULL, related_name="clean_offer"
)
source = models.ForeignKey(
Source, verbose_name="Source", null=True, on_delete=models.SET_NULL
)
# attributes
title = models.CharField(
"Titre", max_length=200, validators=[MaxLengthValidator(200)]
)
content = models.TextField("Contenu", null=True)
pub_date = models.DateTimeField(
"Date de publication sur le RSS",
null=True,
)
# analisis results
contract = models.ForeignKey(
Contract,
db_index=True,
verbose_name="Type de contrat",
null=True,
default="ND",
on_delete=models.SET_DEFAULT,
)
jobs_positions = models.ManyToManyField(
JobPosition,
verbose_name="Métiers",
)
place = models.ForeignKey(
Place,
verbose_name="Lieu",
null=True,
default="ND",
on_delete=models.SET_DEFAULT,
)
technologies = models.ManyToManyField(
Technology,
verbose_name="Technologies",
)
def __str__(self):
return self.title
@property
def short_content(self) -> str:
"""Return the first 300 characters of the offer summary (content).
:return: 300 first characters of offer.content
:rtype: str
"""
return truncatechars(self.content, 300)
@property
def yearweek(self) -> str:
"""Return the week from the publication date (monday as first day).
See: https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior
:return: year and week (format: 'YYYYWW')
:rtype: str
"""
if isinstance(self.pub_date, datetime):
return self.pub_date.strftime("%Y%V")
else:
return None
# Model metadata
class Meta:
verbose_name = "Offre d'emploi"
verbose_name_plural = "Offres d'emploi"
get_latest_by = "pub_date"
ordering = [
"id_rss",
]
# add helper text on properties
short_content.fget.short_description = "Contenu (aperçu)"
yearweek.fget.short_description = "Année / Semaine"