diff --git a/biscuit/core/anonymizers.py b/biscuit/core/anonymizers.py
new file mode 100644
index 0000000000000000000000000000000000000000..03d4f3bf3a8597a3a61a9683878eae1a9f1637ea
--- /dev/null
+++ b/biscuit/core/anonymizers.py
@@ -0,0 +1,23 @@
+from hattori.base import BaseAnonymizer, faker
+
+from .models import Person
+
+
+class PersonAnonymizer(BaseAnonymizer):
+    model = Person
+
+    attributes = [
+        ('first_name', faker.first_name),
+        ('last_name', faker.last_name),
+        ('additional_name', ''),
+        ('short_name', lambda **kwargs: faker.pystr(min_chars=3, max_chars=5, **kwargs)),
+        ('street', faker.street_name),
+        ('housenumber', faker.building_number),
+        ('postal_code', faker.postcode),
+        ('place', faker.city),
+        ('phone_number', ''),
+        ('mobile_number', ''),
+        ('email', faker.email),
+        ('date_of_birth', lambda **kwargs: faker.date_of_birth(minimum_age=8, maximum_age=66, **kwargs)),
+        ('photo', '')
+    ]
diff --git a/biscuit/core/forms.py b/biscuit/core/forms.py
index e4aa0d69f6403648bf2bc719f20d1fb6a80493bf..c7e813fdec59f29777da3670fb1aeee377850b3f 100644
--- a/biscuit/core/forms.py
+++ b/biscuit/core/forms.py
@@ -1,6 +1,7 @@
 from django import forms
 from django.contrib.auth import get_user_model
 from django.utils.translation import ugettext_lazy as _
+from django_select2.forms import ModelSelect2MultipleWidget, Select2Widget
 
 from .models import Person, Group, School, SchoolTerm
 
@@ -9,6 +10,9 @@ class PersonAccountForm(forms.ModelForm):
     class Meta:
         model = Person
         fields = ['last_name', 'first_name', 'user']
+        widgets = {
+            'user': Select2Widget
+        }
 
     new_user = forms.CharField(required=False)
 
@@ -44,6 +48,9 @@ class EditPersonForm(forms.ModelForm):
         model = Person
         fields = ['user', 'is_active', 'first_name', 'last_name', 'additional_name', 'short_name', 'street', 'housenumber',
                   'postal_code', 'place', 'phone_number', 'mobile_number', 'email', 'date_of_birth', 'sex', 'photo', 'photo_cropping']
+        widgets = {
+            'user': Select2Widget
+        }
 
     new_user = forms.CharField(
         required=False,
@@ -72,7 +79,11 @@ class EditGroupForm(forms.ModelForm):
     class Meta:
         model = Group
         fields = ['name', 'short_name', 'members', 'owners', 'parent_groups']
-
+        widgets = {
+            'members': ModelSelect2MultipleWidget(search_fields=['first_name__icontains', 'last_name__icontains', 'short_name__icontains']),
+            'owners': ModelSelect2MultipleWidget(search_fields=['first_name__icontains', 'last_name__icontains', 'short_name__icontains']),
+            'parent_groups': ModelSelect2MultipleWidget(search_fields=['name__icontains', 'short_name__icontains']),
+        }
 
 class EditSchoolForm(forms.ModelForm):
     class Meta:
diff --git a/biscuit/core/settings.py b/biscuit/core/settings.py
index 7b3ac8005c0e611c716b1b87ce30a9ad895ecd07..72900c31913f8d8cc15268c5ffe1fd30c4668ca5 100644
--- a/biscuit/core/settings.py
+++ b/biscuit/core/settings.py
@@ -64,6 +64,8 @@ INSTALLED_APPS = [
     'phonenumber_field',
     'debug_toolbar',
     'contact_form',
+    'django_select2',
+    'hattori',
     'biscuit.core',
     'impersonate',
 ]
@@ -313,4 +315,6 @@ CRON_CLASSES = [
     'biscuit.core.cronjobs.Backup'
 ]
 
+ANONYMIZE_ENABLED = _settings.get('maintenance.anonymisable', True)
+
 _settings.populate_obj(sys.modules[__name__])
diff --git a/biscuit/core/templates/core/edit_group.html b/biscuit/core/templates/core/edit_group.html
index f49bcc0057c055af6200244554ef45b9c23d5658..0eb63393e8c7326012cb6fe6209f4c7e33218126 100644
--- a/biscuit/core/templates/core/edit_group.html
+++ b/biscuit/core/templates/core/edit_group.html
@@ -3,6 +3,16 @@
 {% extends "core/base.html" %}
 {% load bootstrap4 i18n %}
 
+{% block bootstrap4_extra_head %}
+  {{ block.super }}
+  {{ edit_group_form.media.css }}
+{% endblock %}
+
+{% block bootstrap4_extra_script %}
+  {{ block.super }}
+  {{ edit_group_form.media.js }}
+{% endblock %}
+
 {% block bootstrap4_title %}{% blocktrans %}Edit group{% endblocktrans %} - {{ block.super }}{% endblock %}
 
 {% block page_title %}{% blocktrans %}Edit group{% endblocktrans %}{% endblock %}
diff --git a/biscuit/core/templates/core/edit_person.html b/biscuit/core/templates/core/edit_person.html
index ae0f6da794f5f3a7e3cd20ca3c9029e0b78f842c..c1b4f8e22115bca0f821c7dcc04b67c8e88b3bf6 100644
--- a/biscuit/core/templates/core/edit_person.html
+++ b/biscuit/core/templates/core/edit_person.html
@@ -11,6 +11,12 @@
 {% block bootstrap4_extra_head %}
   {{ block.super }}
   {{ edit_person_form.media }}
+  {{ edit_person_form.media.css }}
+{% endblock %}
+
+{% block bootstrap4_extra_script %}
+  {{ block.super }}
+  {{ edit_person_form.media.js }}
 {% endblock %}
 
 {% block content %}
diff --git a/biscuit/core/templates/core/persons_accounts.html b/biscuit/core/templates/core/persons_accounts.html
index 14e2b8f42931b62ee8684cfc30bcaa61c907c1b3..eb376f1a2cab700c10886e4f452537d24faa27b1 100644
--- a/biscuit/core/templates/core/persons_accounts.html
+++ b/biscuit/core/templates/core/persons_accounts.html
@@ -4,6 +4,16 @@
 
 {% load bootstrap4 i18n %}
 
+{% block bootstrap4_extra_head %}
+  {{ block.super }}
+  {{ persons_accounts_formset.media.css }}
+{% endblock %}
+
+{% block bootstrap4_extra_script %}
+  {{ block.super }}
+  {{ persons_accounts_formset.media.js }}
+{% endblock %}
+
 {% block bootstrap4_title %}{% blocktrans %}Link persons to accounts{% endblocktrans%} - {{ block.super }}{% endblock %}
 
 {% block page_title %}
diff --git a/biscuit/core/urls.py b/biscuit/core/urls.py
index 896467e504ba350783425b97a28de98417fd05b4..794394a34baecd64f3744140ba2922e592c7d571 100644
--- a/biscuit/core/urls.py
+++ b/biscuit/core/urls.py
@@ -31,7 +31,8 @@ urlpatterns = [
     path('maintenance-mode/', include('maintenance_mode.urls')),
     path('contact/', include('contact_form.urls')),
     path('impersonate/', include('impersonate.urls')),
-    path('__i18n__/', include('django.conf.urls.i18n'))
+    path('__i18n__/', include('django.conf.urls.i18n')),
+    path('select2/', include('django_select2.urls'))
 ]
 
 # Serve javascript-common if in development
diff --git a/pyproject.toml b/pyproject.toml
index 1b7d35d177763d9b844a62021b37d084478fbfe4..1e5126079389aa131d11ffb187f608ade4c915cb 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -46,6 +46,7 @@ django-impersonate = "^1.4"
 python-memcached = "^1.59"
 django-dbbackup = "^3.2"
 django-cron = "^0.5.1"
+django-hattori = "^0.2"
 
 [tool.poetry.extras]
 ldap = ["django-auth-ldap"]