diff --git a/profiles/MultiSelectFieldListFilter.py b/profiles/MultiSelectFieldListFilter.py
new file mode 100644
index 0000000000000000000000000000000000000000..53f2eefdb0d64f73e21483b9e3fe02175e2267d9
--- /dev/null
+++ b/profiles/MultiSelectFieldListFilter.py
@@ -0,0 +1,65 @@
+from django.contrib import admin
+from django.contrib.admin.utils import reverse_field_path
+from django.utils.translation import gettext_lazy as _
+
+class MultiSelectFieldListFilter(admin.FieldListFilter):
+    def __init__(self, field, request, params, model, model_admin, field_path):
+        self.lookup_kwarg = field_path + '__in'
+        self.lookup_kwarg_isnull = field_path + '__isnull'
+
+        super().__init__(field, request, params, model, model_admin, field_path)
+
+        self.lookup_val = self.used_parameters.get(self.lookup_kwarg, [])
+        if len(self.lookup_val) == 1 and self.lookup_val[0] == '':
+            self.lookup_val = []
+        self.lookup_val_isnull = self.used_parameters.get(self.lookup_kwarg_isnull)
+
+        self.empty_value_display = model_admin.get_empty_value_display()
+        parent_model, reverse_path = reverse_field_path(model, field_path)
+        # Obey parent ModelAdmin queryset when deciding which options to show
+        if model == parent_model:
+            queryset = model_admin.get_queryset(request)
+        else:
+            queryset = parent_model._default_manager.all()
+        self.lookup_choices = queryset.distinct().order_by(field.name).values_list(field.name, flat=True)
+
+    def expected_parameters(self):
+        return [self.lookup_kwarg, self.lookup_kwarg_isnull]
+
+    def choices(self, changelist):
+        yield {
+            'selected': not self.lookup_val and self.lookup_val_isnull is None,
+            'query_string': changelist.get_query_string(remove=[self.lookup_kwarg, self.lookup_kwarg_isnull]),
+            'display': _('All'),
+        }
+        include_none = False
+        for val in self.lookup_choices:
+            if val is None:
+                include_none = True
+                continue
+            val = str(val)
+
+            if val in self.lookup_val:
+                values = [v for v in self.lookup_val if v != val]
+            else:
+                values = self.lookup_val + [ val ]
+
+            if values:
+                yield {
+                    'selected': val in self.lookup_val,
+                    'query_string': changelist.get_query_string({self.lookup_kwarg: ','.join(values)}, [self.lookup_kwarg_isnull]),
+                    'display': val,
+                }
+            else:
+                yield {
+                    'selected': val in self.lookup_val,
+                    'query_string': changelist.get_query_string(remove=[self.lookup_kwarg]),
+                    'display': val,
+                }
+
+        if include_none:
+            yield {
+                'selected': bool(self.lookup_val_isnull),
+                'query_string': changelist.get_query_string({self.lookup_kwarg_isnull: 'True'}, [self.lookup_kwarg]),
+                'display': self.empty_value_display,
+            }
\ No newline at end of file
diff --git a/profiles/admin.py b/profiles/admin.py
index 84d55971daa78a4089d22d02a48c9e21317e66aa..9109a6fd5889f333c659c9a89008376f3cf8f758 100644
--- a/profiles/admin.py
+++ b/profiles/admin.py
@@ -2,6 +2,7 @@
 
 from django.contrib import admin
 from .models import Student, Tutor
+from .MultiSelectFieldListFilter import MultiSelectFieldListFilter
 import codecs
 
 import csv
@@ -42,10 +43,11 @@ class TutorAdmin(ProfileAdminMixin, admin.ModelAdmin,ExportCsvMixin):
         model = Tutor
     actions = ["export_as_csv"]
 
+
 @admin.register(Student)
 class StudentAdmin(ProfileAdminMixin, admin.ModelAdmin,ExportCsvMixin):
     """Student admin panel."""
-    list_filter = ('school', 'year')
+    list_filter = (('school',MultiSelectFieldListFilter), 'year')
     class Meta:  # noqa
         model = Student
     actions = ["export_as_csv"]
\ No newline at end of file