diff --git a/CHANGELOG.md b/CHANGELOG.md
index 649214b1be2994e75c638358907249ef4fdbb6be..c7c6da441be5272d90227233da9e727dfc886e69 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,7 @@
 - Custom title to error pages
 - Update FAQ
 - More captions for planning
+- Reworked file upload to allow for file replacement (and not just upload to a new unique name)
 - Fix bugs
 
 ## Version 1.2.3 - 2021-04-25
diff --git a/site_settings/models.py b/site_settings/models.py
index 7ca8da89035f91cf7452252ad8e0f754f33e10e9..fe37ead5aa1c584cfe592ad608cc36d82daed837 100644
--- a/site_settings/models.py
+++ b/site_settings/models.py
@@ -1,9 +1,29 @@
 from datetime import timedelta
+from pathlib import Path
 
 from django.db import models
 from django.core.cache import cache
+from django.core.files.storage import FileSystemStorage
 from django.utils.timezone import now
 
+
+class OverwriteStorage(FileSystemStorage):
+	"""used to enforcing a fixed filename to upload file
+	This allow for a constant link to a changeable file"""
+	filename = "PlanningInterludes"
+	def get_available_name(self, name, **kwargs):
+		"""
+		Returns a filename that's free on the target storage system, and
+		available for new content to be written to.
+		"""
+		# If the filename already exists, remove it as if it was a true file system
+		extension = Path(name).suffix
+		new_name = self.filename + extension
+		if self.exists(new_name):
+			self.delete(new_name)
+		return super(FileSystemStorage, self).get_available_name(new_name, **kwargs)
+
+
 class SingletonModel(models.Model):
 	"""Table de la BDD qui ne possède qu'un seul élément"""
 	class Meta:
@@ -54,6 +74,7 @@ class SiteSettings(SingletonModel):
 	display_planning = models.BooleanField("Afficher le planning", default=False)
 	planning_file = models.FileField(
 		verbose_name="Version PDF du planning", null=True, blank=True,
+		storage=OverwriteStorage(),
 	)
 
 	activities_allocated = models.BooleanField(