Skip to content

Commit

Permalink
models: Use more sensitive on_delete clauses for foreign keys
Browse files Browse the repository at this point in the history
  • Loading branch information
rsebille committed Feb 22, 2024
1 parent d1ce329 commit 2dad337
Show file tree
Hide file tree
Showing 11 changed files with 38 additions and 34 deletions.
18 changes: 9 additions & 9 deletions itou/approvals/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ class Approval(PENotificationMixin, CommonApprovalMixin):
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
verbose_name="demandeur d'emploi",
on_delete=models.CASCADE,
on_delete=models.PROTECT, # 2-step deletion, first the Approval to create a CancelledApproval then the User
related_name="approvals",
)
created_by = models.ForeignKey(
Expand All @@ -507,7 +507,7 @@ class Approval(PENotificationMixin, CommonApprovalMixin):
verbose_name="diagnostic d'éligibilité",
null=True,
blank=True,
on_delete=models.SET_NULL,
on_delete=models.RESTRICT, # To not mess with the `approval_eligibility_diagnosis` constraint
)

# 2023-08-17: An experiment to add a denormalized field “last_suspension_ended_at” did not exhibit large
Expand Down Expand Up @@ -1083,7 +1083,7 @@ def displayed_choices_for_siae(siae):
settings.AUTH_USER_MODEL,
verbose_name="créé par",
null=True,
on_delete=models.SET_NULL,
on_delete=models.RESTRICT, # For traceability and accountability
related_name="approvals_suspended_set",
)
updated_at = models.DateTimeField(verbose_name="date de modification", auto_now=True)
Expand All @@ -1092,7 +1092,7 @@ def displayed_choices_for_siae(siae):
verbose_name="mis à jour par",
null=True,
blank=True,
on_delete=models.SET_NULL,
on_delete=models.RESTRICT, # For traceability and accountability, the dates can be edited
)

objects = SuspensionQuerySet.as_manager()
Expand Down Expand Up @@ -1336,14 +1336,14 @@ class CommonProlongation(models.Model):
settings.AUTH_USER_MODEL,
verbose_name="déclarée par",
null=True,
on_delete=models.SET_NULL,
on_delete=models.RESTRICT, # For traceability and accountability
related_name="%(class)ss_declared",
)
declared_by_siae = models.ForeignKey(
"companies.Company",
verbose_name="SIAE du déclarant",
null=True,
on_delete=models.SET_NULL,
on_delete=models.RESTRICT, # For traceability and accountability, people's organization can change
)

# It is assumed that an authorized prescriber has validated the prolongation beforehand.
Expand All @@ -1352,7 +1352,7 @@ class CommonProlongation(models.Model):
verbose_name="prescripteur habilité qui a autorisé cette prolongation",
null=True,
blank=True,
on_delete=models.SET_NULL,
on_delete=models.RESTRICT, # For traceability and accountability
related_name="%(class)ss_validated",
)

Expand All @@ -1361,7 +1361,7 @@ class CommonProlongation(models.Model):
verbose_name="organisation du prescripteur habilité",
null=True,
blank=True,
on_delete=models.SET_NULL,
on_delete=models.RESTRICT, # For traceability and accountability, people's organization can change
)

# `created_by` can be different from `declared_by` when created in admin.
Expand Down Expand Up @@ -1511,7 +1511,7 @@ class ProlongationRequest(CommonProlongation):
processed_by = models.ForeignKey(
settings.AUTH_USER_MODEL,
verbose_name="traité par",
on_delete=models.SET_NULL,
on_delete=models.RESTRICT, # For traceability and accountability
related_name="%(class)s_processed",
null=True,
blank=True,
Expand Down
2 changes: 1 addition & 1 deletion itou/common_apps/organizations/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ class MembershipAbstract(models.Model):
settings.AUTH_USER_MODEL,
related_name="updated_membershipmodel_set",
null=True,
on_delete=models.CASCADE,
on_delete=models.SET_NULL,
verbose_name="mis à jour par",
)
Expand Down
8 changes: 4 additions & 4 deletions itou/companies/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ class CompanyMembership(MembershipAbstract):
settings.AUTH_USER_MODEL,
related_name="updated_companymembership_set",
null=True,
on_delete=models.CASCADE,
on_delete=models.SET_NULL,
verbose_name="mis à jour par",
)
notifications = models.JSONField(verbose_name="notifications", default=dict, blank=True)
Expand Down Expand Up @@ -563,7 +563,7 @@ class JobDescription(models.Model):
# Max number or workable hours per week in France (Code du Travail)
MAX_WORKED_HOURS_PER_WEEK = 48

appellation = models.ForeignKey("jobs.Appellation", on_delete=models.CASCADE)
appellation = models.ForeignKey("jobs.Appellation", on_delete=models.RESTRICT)
company = models.ForeignKey(Company, on_delete=models.CASCADE, related_name="job_description_through")
created_at = models.DateTimeField(verbose_name="date de création", default=timezone.now)
updated_at = models.DateTimeField(verbose_name="date de modification", auto_now=True, db_index=True)
Expand All @@ -581,7 +581,7 @@ class JobDescription(models.Model):
)
location = models.ForeignKey(
"cities.City",
on_delete=models.SET_NULL,
on_delete=models.RESTRICT,
null=True,
blank=True,
verbose_name="localisation du poste",
Expand Down Expand Up @@ -808,7 +808,7 @@ class SiaeConvention(models.Model):
related_name="reactivated_siae_convention_set",
null=True,
blank=True,
on_delete=models.SET_NULL,
on_delete=models.RESTRICT, # Only staff can update it, and we shouldn't delete one of those accounts
)
reactivated_at = models.DateTimeField(verbose_name="date de réactivation manuelle", blank=True, null=True)

Expand Down
4 changes: 2 additions & 2 deletions itou/eligibility/models/geiq.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ class GEIQAdministrativeCriteria(AbstractAdministrativeCriteria):
verbose_name="critère parent",
blank=True,
null=True,
on_delete=models.SET_NULL,
on_delete=models.RESTRICT, # Prevent promoting a criteria form child to parent
)
# Some criteria do not belong to an annex or a level
annex = models.CharField(
Expand Down Expand Up @@ -289,7 +289,7 @@ class GEIQSelectedAdministrativeCriteria(models.Model):
)
administrative_criteria = models.ForeignKey(
GEIQAdministrativeCriteria,
on_delete=models.CASCADE,
on_delete=models.RESTRICT,
related_name="administrative_criteria_through",
)
created_at = models.DateTimeField(verbose_name="date de création", default=timezone.now)
Expand Down
2 changes: 1 addition & 1 deletion itou/eligibility/models/iae.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ class SelectedAdministrativeCriteria(models.Model):
eligibility_diagnosis = models.ForeignKey(EligibilityDiagnosis, on_delete=models.CASCADE)
administrative_criteria = models.ForeignKey(
AdministrativeCriteria,
on_delete=models.CASCADE,
on_delete=models.RESTRICT,
related_name="administrative_criteria_through",
)
created_at = models.DateTimeField(verbose_name="date de création", default=timezone.now)
Expand Down
2 changes: 1 addition & 1 deletion itou/employee_record/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ class EmployeeRecord(ASPExchangeInformation):
# - Approval
job_application = models.ForeignKey(
"job_applications.jobapplication",
on_delete=models.SET_NULL,
on_delete=models.RESTRICT,
null=True,
verbose_name="candidature / embauche",
related_name="employee_record",
Expand Down
2 changes: 1 addition & 1 deletion itou/institutions/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class InstitutionMembership(MembershipAbstract):
settings.AUTH_USER_MODEL,
related_name="updated_institutionmembership_set",
null=True,
on_delete=models.CASCADE,
on_delete=models.SET_NULL,
verbose_name="mis à jour par",
)

Expand Down
12 changes: 7 additions & 5 deletions itou/job_applications/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ class JobApplication(xwf_models.WorkflowEnabled, models.Model):
job_seeker = models.ForeignKey(
settings.AUTH_USER_MODEL,
verbose_name="demandeur d'emploi",
on_delete=models.CASCADE,
on_delete=models.RESTRICT, # This object is central to us and the SIAE
related_name="job_applications",
)

Expand Down Expand Up @@ -505,7 +505,7 @@ class JobApplication(xwf_models.WorkflowEnabled, models.Model):
sender = models.ForeignKey(
settings.AUTH_USER_MODEL,
verbose_name="utilisateur émetteur",
on_delete=models.SET_NULL,
on_delete=models.SET_NULL, # FIXME: Do we need traceability and accountability?
null=True,
blank=True,
related_name="job_applications_sent",
Expand All @@ -529,7 +529,7 @@ class JobApplication(xwf_models.WorkflowEnabled, models.Model):
verbose_name="organisation du prescripteur émettrice",
null=True,
blank=True,
on_delete=models.SET_NULL,
on_delete=models.SET_NULL, # FIXME: Do we need traceability and accountability?
)

to_company = models.ForeignKey(
Expand All @@ -549,7 +549,7 @@ class JobApplication(xwf_models.WorkflowEnabled, models.Model):
verbose_name="poste retenu",
blank=True,
null=True,
on_delete=models.SET_NULL,
on_delete=models.SET_NULL, # FIXME: Maybe RESTRICT because its value should'nt changes, also exposed in API
related_name="hired_job_applications",
)

Expand Down Expand Up @@ -1230,7 +1230,9 @@ class JobApplicationTransitionLog(xwf_models.BaseTransitionLog):
MODIFIED_OBJECT_FIELD = "job_application"
EXTRA_LOG_ATTRIBUTES = (("user", "user", None),)
job_application = models.ForeignKey(JobApplication, related_name="logs", on_delete=models.CASCADE)
user = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True, on_delete=models.SET_NULL)
user = models.ForeignKey(
settings.AUTH_USER_MODEL, blank=True, null=True, on_delete=models.SET_NULL
) # FIXME: Do we need traceability and accountability?

class Meta:
verbose_name = "log des transitions de la candidature"
Expand Down
4 changes: 2 additions & 2 deletions itou/prescribers/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ class PrescriberOrganization(AddressMixin, OrganizationAbstract):
related_name="authorization_status_set",
null=True,
blank=True,
on_delete=models.SET_NULL,
on_delete=models.RESTRICT, # Only staff can update it, and we shouldn't delete one of those accounts
)

objects = PrescriberOrganizationManager.from_queryset(PrescriberOrganizationQuerySet)()
Expand Down Expand Up @@ -333,7 +333,7 @@ class PrescriberMembership(MembershipAbstract):
settings.AUTH_USER_MODEL,
related_name="updated_prescribermembership_set",
null=True,
on_delete=models.CASCADE,
on_delete=models.SET_NULL,
verbose_name="mis à jour par",
)

Expand Down
16 changes: 9 additions & 7 deletions itou/siae_evaluations/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ class EvaluationCampaign(models.Model):

institution = models.ForeignKey(
"institutions.Institution",
on_delete=models.CASCADE,
on_delete=models.CASCADE, # FIXME: Seems dangerous to allow campaign deletion on institution deletion
related_name="evaluation_campaigns",
verbose_name="DDETS IAE responsable du contrôle",
validators=[validate_institution],
Expand Down Expand Up @@ -445,7 +445,7 @@ class EvaluatedSiae(models.Model):
siae = models.ForeignKey(
"companies.Company",
verbose_name="SIAE",
on_delete=models.CASCADE,
on_delete=models.CASCADE, # FIXME: RESTRICT because CaP is an auditability tool?
related_name="evaluated_siaes",
)
# In “phase amiable” until documents have been reviewed.
Expand Down Expand Up @@ -635,14 +635,14 @@ class EvaluatedJobApplication(models.Model):
job_application = models.ForeignKey(
"job_applications.JobApplication",
verbose_name="candidature",
on_delete=models.CASCADE,
on_delete=models.CASCADE, # FIXME: RESTRICT because CaP is an auditability tool?
related_name="evaluated_job_applications",
)

evaluated_siae = models.ForeignKey(
EvaluatedSiae,
verbose_name="SIAE évaluée",
on_delete=models.CASCADE,
on_delete=models.CASCADE, # FIXME: RESTRICT because CaP is an auditability tool?
related_name="evaluated_job_applications",
)
labor_inspector_explanation = models.TextField(verbose_name="commentaires de l'inspecteur du travail", blank=True)
Expand Down Expand Up @@ -759,18 +759,20 @@ class EvaluatedAdministrativeCriteria(models.Model):
administrative_criteria = models.ForeignKey(
"eligibility.AdministrativeCriteria",
verbose_name="critère administratif",
on_delete=models.CASCADE,
on_delete=models.CASCADE, # FIXME: RESTRICT because CaP is an auditability tool?
related_name="evaluated_administrative_criteria",
)

evaluated_job_application = models.ForeignKey(
EvaluatedJobApplication,
verbose_name="candidature évaluée",
on_delete=models.CASCADE,
on_delete=models.CASCADE, # FIXME: RESTRICT because CaP is an auditability tool?
related_name="evaluated_administrative_criteria",
)

proof = models.ForeignKey("files.File", on_delete=models.CASCADE, blank=True, null=True)
proof = models.ForeignKey(
"files.File", on_delete=models.CASCADE, blank=True, null=True
) # FIXME: RESTRICT because CaP is an auditability tool?
uploaded_at = models.DateTimeField(verbose_name="téléversé le", blank=True, null=True)
submitted_at = models.DateTimeField(verbose_name="transmis le", blank=True, null=True)
review_state = models.CharField(
Expand Down
2 changes: 1 addition & 1 deletion itou/users/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ class User(AbstractUser, AddressMixin):
created_by = models.ForeignKey(
"self",
verbose_name="créé par",
on_delete=models.SET_NULL,
on_delete=models.SET_NULL, # FIXME: Do we need traceability and accountability?
null=True,
blank=True,
)
Expand Down

0 comments on commit 2dad337

Please sign in to comment.