diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 8e5936c5590cc6cf11a820389e5e77bf6cba993c..c3dbc3374fe51157dea2cfae674344530de76402 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -19,6 +19,7 @@ Fixed
 ~~~~~
 
 * ``Event.__str__`` returned a proxy type instead a string.
+* Do not show substitutions on regular timetables.
 
 `2.0rc2`_ - 2021-08-01
 ----------
diff --git a/aleksis/apps/chronos/managers.py b/aleksis/apps/chronos/managers.py
index d03589aac4d36e1f640cff5e793a27cfdc0d6b52..b2f364c9cff65588650f983a230339e430b82fc1 100644
--- a/aleksis/apps/chronos/managers.py
+++ b/aleksis/apps/chronos/managers.py
@@ -319,7 +319,7 @@ class LessonDataQuerySet(models.QuerySet, WeekQuerySetMixin):
             | Q(**{self._period_path + "lesson__groups__parent_groups__in": groups})
         )
 
-    def filter_teacher(self, teacher: Union[Person, int]):
+    def filter_teacher(self, teacher: Union[Person, int], is_smart: bool = True):
         """Filter for all lessons given by a certain teacher."""
         qs1 = self.filter(**{self._period_path + "lesson__teachers": teacher})
         qs2 = self.filter(
@@ -330,9 +330,12 @@ class LessonDataQuerySet(models.QuerySet, WeekQuerySetMixin):
             }
         )
 
-        return qs1.union(qs2)
+        if is_smart:
+            return qs1.union(qs2)
+        else:
+            return qs1
 
-    def filter_room(self, room: Union["Room", int]):
+    def filter_room(self, room: Union["Room", int], is_smart: bool = True):
         """Filter for all lessons taking part in a certain room."""
         qs1 = self.filter(**{self._period_path + "room": room})
         qs2 = self.filter(
@@ -343,18 +346,21 @@ class LessonDataQuerySet(models.QuerySet, WeekQuerySetMixin):
             }
         )
 
-        return qs1.union(qs2)
+        if is_smart:
+            return qs1.union(qs2)
+        else:
+            return qs1
 
     def filter_from_type(
-        self, type_: TimetableType, obj: Union[Person, Group, "Room", int]
+        self, type_: TimetableType, obj: Union[Person, Group, "Room", int], is_smart: bool = True
     ) -> Optional[models.QuerySet]:
         """Filter lesson data for a group, teacher or room by provided type."""
         if type_ == TimetableType.GROUP:
             return self.filter_group(obj)
         elif type_ == TimetableType.TEACHER:
-            return self.filter_teacher(obj)
+            return self.filter_teacher(obj, is_smart=is_smart)
         elif type_ == TimetableType.ROOM:
-            return self.filter_room(obj)
+            return self.filter_room(obj, is_smart=is_smart)
         else:
             return None
 
diff --git a/aleksis/apps/chronos/util/build.py b/aleksis/apps/chronos/util/build.py
index d2f7214826fec61b3351758231cadfcf1194bed0..5ae3341f70638a7bbdc81c1841d22155541b608f 100644
--- a/aleksis/apps/chronos/util/build.py
+++ b/aleksis/apps/chronos/util/build.py
@@ -76,7 +76,7 @@ def build_timetable(
     if is_person:
         lesson_periods = lesson_periods.filter_from_person(obj)
     else:
-        lesson_periods = lesson_periods.filter_from_type(type_, obj)
+        lesson_periods = lesson_periods.filter_from_type(type_, obj, is_smart=with_holidays)
 
     # Sort lesson periods in a dict
     lesson_periods_per_period = lesson_periods.group_by_periods(is_week=is_week)