diff --git a/biscuit/core/migrations/0008_school_person_group.py b/biscuit/core/migrations/0008_school_person_group.py
new file mode 100644
index 0000000000000000000000000000000000000000..4f72da7e55dda07250713583d04a87aeaa1c84d9
--- /dev/null
+++ b/biscuit/core/migrations/0008_school_person_group.py
@@ -0,0 +1,44 @@
+# Generated by Django 2.2.3 on 2019-07-28 20:52
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('core', '0007_school'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='group',
+            name='school',
+            field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='core.School'),
+            preserve_default=False,
+        ),
+        migrations.AddField(
+            model_name='person',
+            name='school',
+            field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='core.School'),
+            preserve_default=False,
+        ),
+        migrations.AlterField(
+            model_name='person',
+            name='import_ref',
+            field=models.CharField(blank=True, editable=False, max_length=64, verbose_name='Reference ID of import source'),
+        ),
+        migrations.AlterField(
+            model_name='person',
+            name='short_name',
+            field=models.CharField(blank=True, max_length=5, verbose_name='Short name'),
+        ),
+        migrations.AlterUniqueTogether(
+            name='group',
+            unique_together={('school', 'short_name'), ('school', 'name')},
+        ),
+        migrations.AlterUniqueTogether(
+            name='person',
+            unique_together={('school', 'short_name'), ('school', 'import_ref')},
+        ),
+    ]
diff --git a/biscuit/core/mixins.py b/biscuit/core/mixins.py
new file mode 100644
index 0000000000000000000000000000000000000000..6506373869e99b587dd76163a45720f388ba18c7
--- /dev/null
+++ b/biscuit/core/mixins.py
@@ -0,0 +1,8 @@
+from django.db import models
+
+
+class SchoolRelated(models.Model):
+    class Meta:
+        abstract = True
+
+    school = models.ForeignKey('core.School', on_delete=models.CASCADE)
diff --git a/biscuit/core/models.py b/biscuit/core/models.py
index 8a9b9622ed5ea7e8a83487f3f0da0adea780a5e7..c1a3d2794d7dde46c293a661f276123abfbf250e 100644
--- a/biscuit/core/models.py
+++ b/biscuit/core/models.py
@@ -3,6 +3,8 @@ from django.utils.translation import gettext_lazy as _
 
 from phonenumber_field.modelfields import PhoneNumberField
 
+from .mixins import SchoolRelated
+
 
 class School(models.Model):
     name = models.CharField(verbose_name=_('Name'), max_length=30)
@@ -10,7 +12,10 @@ class School(models.Model):
         'Official name of the school, e.g. as given by supervisory authority'))
 
 
-class Person(models.Model):
+class Person(SchoolRelated):
+    class Meta:
+        unique_together = [['school', 'short_name'], ['school', 'import_ref']]
+
     SEX_CHOICES = [
         ('f', _('female')),
         ('m', _('male'))
@@ -25,7 +30,7 @@ class Person(models.Model):
         'Additional name(s)'), max_length=30, blank=True)
 
     short_name = models.CharField(verbose_name=_(
-        'Short name'), max_length=5, blank=True, unique=True)
+        'Short name'), max_length=5, blank=True)
 
     street = models.CharField(verbose_name=_(
         'Street'), max_length=30, blank=True)
@@ -50,7 +55,7 @@ class Person(models.Model):
     photo = models.ImageField(verbose_name=_('Photo'), blank=True, null=True)
 
     import_ref = models.CharField(verbose_name=_(
-        'Reference ID of import source'), max_length=64, blank=True, unique=True, editable=False)
+        'Reference ID of import source'), max_length=64, blank=True, editable=False)
 
     guardians = models.ManyToManyField('self', verbose_name=_('Guardians / Parents'),
                                        symmetrical=False, related_name='children')
@@ -59,7 +64,10 @@ class Person(models.Model):
         return '%s, %s' % (self.last_name, self.first_name)
 
 
-class Group(models.Model):
+class Group(SchoolRelated):
+    class Meta:
+        unique_together = [['school', 'name'], ['school', 'short_name']]
+
     name = models.CharField(verbose_name=_(
         'Long name of group'), max_length=30, unique=True)
     short_name = models.CharField(verbose_name=_(