diff --git a/aleksis/core/migrations/0005_timestamped_activity_notification.py b/aleksis/core/migrations/0005_timestamped_activity_notification.py
new file mode 100644
index 0000000000000000000000000000000000000000..611c55196dc8c703662380e7c73ca0ae20a42059
--- /dev/null
+++ b/aleksis/core/migrations/0005_timestamped_activity_notification.py
@@ -0,0 +1,35 @@
+# Generated by Django 3.1.3 on 2020-11-16 13:04
+
+from django.db import migrations, models
+import django.utils.timezone
+import model_utils.fields
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('core', '0004_add_permissions_for_group_stats'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='activity',
+            name='created',
+            field=model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created'),
+        ),
+        migrations.AddField(
+            model_name='activity',
+            name='modified',
+            field=model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified'),
+        ),
+        migrations.AddField(
+            model_name='notification',
+            name='created',
+            field=model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created'),
+        ),
+        migrations.AddField(
+            model_name='notification',
+            name='modified',
+            field=model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified'),
+        ),
+    ]
diff --git a/aleksis/core/mixins.py b/aleksis/core/mixins.py
index 653e8e0ee81d84be46f9a4faa9787574e5d9af68..c6608a6255d8e0680d6d608dce2b373e71fbcbb8 100644
--- a/aleksis/core/mixins.py
+++ b/aleksis/core/mixins.py
@@ -19,7 +19,6 @@ from django.views.generic import CreateView, UpdateView
 from django.views.generic.edit import DeleteView, ModelFormMixin
 
 import reversion
-from easyaudit.models import CRUDEvent
 from guardian.admin import GuardedModelAdmin
 from jsonstore.fields import IntegerField, JSONFieldMixin
 from material.base import Layout, LayoutNode
@@ -76,8 +75,7 @@ class ExtensibleModel(models.Model, metaclass=_ExtensibleModelBase):
     This base model ensures all objects in AlekSIS apps fulfill the
     following properties:
 
-     * crud_events property to retrieve easyaudit's CRUD event log
-     * created_at and updated_at properties based n CRUD events
+     * `versions` property to retrieve all versions of the model from reversion
      * Allow injection of fields and code from AlekSIS apps to extend
        model functionality.
 
@@ -131,50 +129,30 @@ class ExtensibleModel(models.Model, metaclass=_ExtensibleModelBase):
         pass
 
     @property
-    def crud_events(self) -> QuerySet:
-        """Get all CRUD events connected to this object from easyaudit."""
-        content_type = ContentType.objects.get_for_model(self)
+    def versions(self) -> List[Tuple[str, Tuple[Any, Any]]]:
+        """Get all versions of this object from django-reversion.
 
-        return CRUDEvent.objects.filter(
-            object_id=self.pk, content_type=content_type
-        ).select_related("user", "user__person")
+        Includes diffs to previous version.
+        """
+        versions = reversion.models.Version.objects.get_for_object(self)
 
-    @property
-    def crud_event_create(self) -> Optional[CRUDEvent]:
-        """Return create event of this object."""
-        return self.crud_events.filter(event_type=CRUDEvent.CREATE).latest("datetime")
+        versions_with_changes = []
+        for i, version in enumerate(versions):
+            diff = {}
+            if i > 0:
+                prev_version = versions[i - 1]
 
-    @property
-    def crud_event_update(self) -> Optional[CRUDEvent]:
-        """Return last event of this object."""
-        return self.crud_events.latest("datetime")
+                for k, val in version.field_dict.items():
+                    prev_val = prev_version.field_dict.get(k, None)
+                    if prev_val != val:
+                        diff[k] = (prev_val, val)
 
-    @property
-    def created_at(self) -> Optional[datetime]:
-        """Determine creation timestamp from CRUD log."""
-        if self.crud_event_create:
-            return self.crud_event_create.datetime
+            versions_with_changes.append((version, diff))
 
-    @property
-    def updated_at(self) -> Optional[datetime]:
-        """Determine last timestamp from CRUD log."""
-        if self.crud_event_update:
-            return self.crud_event_update.datetime
+        return versions_with_changes
 
     extended_data = JSONField(default=dict, editable=False)
 
-    @property
-    def created_by(self) -> Optional[models.Model]:
-        """Determine user who created this object from CRUD log."""
-        if self.crud_event_create:
-            return self.crud_event_create.user
-
-    @property
-    def updated_by(self) -> Optional[models.Model]:
-        """Determine user who last updated this object from CRUD log."""
-        if self.crud_event_update:
-            return self.crud_event_update.user
-
     extended_data = JSONField(default=dict, editable=False)
 
     @classmethod
diff --git a/aleksis/core/models.py b/aleksis/core/models.py
index 4c9c28ea657b98dea8c14188bac0e19cad048ab2..c99820e5123f1a2d114c41533a9ee9a6628827d3 100644
--- a/aleksis/core/models.py
+++ b/aleksis/core/models.py
@@ -21,6 +21,7 @@ from django.utils.translation import gettext_lazy as _
 import jsonstore
 from cache_memoize import cache_memoize
 from dynamic_preferences.models import PerInstancePreferenceModel
+from model_utils.models import TimeStampedModel
 from phonenumber_field.modelfields import PhoneNumberField
 from polymorphic.models import PolymorphicModel
 
@@ -226,9 +227,9 @@ class Person(ExtensibleModel):
     def age_at(self, today):
         if self.date_of_birth:
             years = today.year - self.date_of_birth.year
-            if (self.date_of_birth.month > today.month
-                or (self.date_of_birth.month == today.month
-                    and self.date_of_birth.day > today.day)):
+            if self.date_of_birth.month > today.month or (
+                self.date_of_birth.month == today.month and self.date_of_birth.day > today.day
+            ):
                 years -= 1
             return years
 
@@ -388,14 +389,14 @@ class Group(SchoolTermRelatedExtensibleModel):
         """ Get stats about a given group """
         stats = {}
 
-        stats['members'] = len(self.members.all())
+        stats["members"] = len(self.members.all())
 
         ages = [person.age for person in self.members.filter(date_of_birth__isnull=False)]
 
         if ages:
-            stats['age_avg'] = sum(ages) / len(ages)
-            stats['age_range_min'] = min(ages)
-            stats['age_range_max'] = max(ages)
+            stats["age_avg"] = sum(ages) / len(ages)
+            stats["age_range_min"] = min(ages)
+            stats["age_range_max"] = max(ages)
 
         return stats
 
@@ -440,7 +441,7 @@ class PersonGroupThrough(ExtensibleModel):
             setattr(self, field_name, field_instance)
 
 
-class Activity(ExtensibleModel):
+class Activity(ExtensibleModel, TimeStampedModel):
     """Activity of a user to trace some actions done in AlekSIS in displayable form."""
 
     user = models.ForeignKey(
@@ -460,7 +461,7 @@ class Activity(ExtensibleModel):
         verbose_name_plural = _("Activities")
 
 
-class Notification(ExtensibleModel):
+class Notification(ExtensibleModel, TimeStampedModel):
     """Notification to submit to a user."""
 
     sender = models.CharField(max_length=100, verbose_name=_("Sender"))
diff --git a/aleksis/core/settings.py b/aleksis/core/settings.py
index a04471a0084c16919a0395c2df4ff25cc46aea9f..cd92f28e4a3ef71bcb6220711db196452641d3cc 100644
--- a/aleksis/core/settings.py
+++ b/aleksis/core/settings.py
@@ -64,7 +64,6 @@ INSTALLED_APPS = [
     "dbbackup",
     "settings_context_processor",
     "sass_processor",
-    "easyaudit",
     "django_any_js",
     "django_yarnpkg",
     "django_tables2",
@@ -129,7 +128,6 @@ MIDDLEWARE = [
     "impersonate.middleware.ImpersonateMiddleware",
     "django.contrib.messages.middleware.MessageMiddleware",
     "django.middleware.clickjacking.XFrameOptionsMiddleware",
-    "easyaudit.middleware.easyaudit.EasyAuditMiddleware",
     "maintenance_mode.middleware.MaintenanceModeMiddleware",
     "aleksis.core.util.middlewares.EnsurePersonMiddleware",
     "django_prometheus.middleware.PrometheusAfterMiddleware",
diff --git a/aleksis/core/templates/core/index.html b/aleksis/core/templates/core/index.html
index 683adca900d46a8ba50790829db4d3ecd0ba2716..bcf0bf1b4180756d53f1519b8ee2371ee3e4e658 100644
--- a/aleksis/core/templates/core/index.html
+++ b/aleksis/core/templates/core/index.html
@@ -48,7 +48,7 @@
                 <span class="badge new primary-color">{{ activity.app }}</span>
                 <span class="title">{{ activity.title }}</span>
                 <p>
-                  <i class="material-icons left">access_time</i> {{ activity.created_at }}
+                  <i class="material-icons left">access_time</i> {{ activity.created }}
                 </p>
                 <p>
                   {{ activity.description }}
@@ -71,7 +71,7 @@
                 <span class="badge new primary-color">{{ notification.app }}</span>
                 <span class="title">{{ notification.title }}</span>
                 <p>
-                  <i class="material-icons left">access_time</i> {{ notification.created_at }}
+                  <i class="material-icons left">access_time</i> {{ notification.created }}
                 </p>
                 <p>
                   {{ notification.description }}
diff --git a/aleksis/core/templates/core/partials/crud_events.html b/aleksis/core/templates/core/partials/crud_events.html
index 50e4f73cab492804b163b7ddfe0dda08b9e267b7..b0edf14d154690e33a2fac523f5fa38429fcdb5e 100644
--- a/aleksis/core/templates/core/partials/crud_events.html
+++ b/aleksis/core/templates/core/partials/crud_events.html
@@ -1,62 +1,32 @@
 {% load i18n data_helpers %}
 
-<ul class="collection">
-  {% for event in obj.crud_events %}
-    {% if no_m2m and event.event_type == event.M2M_CHANGE or event.event_type == event.M2M_CHANGE_REV %}
-    {% else %}
-      <li class="collection-item">
-        <strong>
-          {% if event.event_type == event.CREATE %}
-            {% blocktrans with person=event.user.person %}
-              Created by {{ person }}
-            {% endblocktrans %}
-          {% elif event.event_type == event.UPDATE %}
-            {% blocktrans with person=event.user.person %}
-              Updated by {{ person }}
-            {% endblocktrans %}
-          {% elif event.event_type == event.DELETE %}
-            {% blocktrans with person=event.user.person %}
-              Deleted by {{ person }}
-            {% endblocktrans %}
-          {% elif event.event_type == event.M2M_CHANGE %}
-            {% blocktrans with person=event.user.person %}
-              Updated by {{ person }}
-            {% endblocktrans %}
-          {% elif event.event_type == event.M2M_CHANGE_REV %}
-            {% blocktrans with person=event.user.person %}
-              Updated by {{ person }}
-            {% endblocktrans %}
-          {% endif %}
-        </strong>
-
-        <div class="left" style="margin-right: 10px;">
-          {% if event.event_type == event.CREATE %}
-            <i class="material-icons">add_circle</i>
-          {% elif event.event_type == event.UPDATE %}
-            <i class="material-icons">edit</i>
-          {% elif event.event_type == event.DELETE %}
-            <i class="material-icons">delete</i>
-          {% elif event.event_type == event.M2M_CHANGE %}
-            <i class="material-icons">edit</i>
-          {% elif event.event_type == event.M2M_CHANGE_REV %}
-            <i class="material-icons">edit</i>
-          {% endif %}
-        </div>
-        <div class="right">
-          {{ event.datetime }}
-        </div>
-        {% parse_json event.changed_fields as changed_fields %}
-        {% if changed_fields %}
-          <ul>
-            {% for field, change in changed_fields.items %}
-              {% verbose_name event.content_type.app_label event.content_type.model field as verbose_name %}
-              <li>
-                {{ verbose_name }}: <s>{{ change.0 }}</s> → {{ change.1 }}
-              </li>
-            {% endfor %}
-          </ul>
+<div class="collection">
+  {% for version in obj.versions %}
+    <div class="collection-item">
+      <div class="left" style="margin-right: 10px;">
+        {% if forloop.first %}
+          <i class="material-icons">add_circle</i>
+        {% else %}
+          <i class="material-icons">edit</i>
         {% endif %}
-      </li>
-    {% endif %}
+      </div>
+      <strong>
+        {{ version.0.revision.get_comment }}
+        {% trans "Changed by" %} {% firstof version.0.revision.user.person _("Unknown") %}
+      </strong>
+      <div class="right">
+        {{ version.0.revision.date_created }}
+      </div>
+      {% if version.1 %}
+        <ul>
+          {% for field, change in version.1.items %}
+            {% verbose_name version.0.content_type.app_label version.0.content_type.model field as verbose_name %}
+            <li>
+              {{ verbose_name }}: <s>{{ change.0 }}</s> → {{ change.1 }}
+            </li>
+          {% endfor %}
+        </ul>
+      {% endif %}
+    </div>
   {% endfor %}
-</ul>
+</div>
diff --git a/aleksis/core/templates/templated_email/notification.email b/aleksis/core/templates/templated_email/notification.email
index 8e61fd0df28b5bc6342c891921831e147e9cc8d9..0e5d9bdee3c8bd9ec3df5c9d008ae68d1f274c23 100644
--- a/aleksis/core/templates/templated_email/notification.email
+++ b/aleksis/core/templates/templated_email/notification.email
@@ -15,7 +15,7 @@
         {% trans "More information" %} → {{ notification.link }}
     {% endif %}
 
-    {% blocktrans with trans_sender=notification.sender trans_created_at=notification.created_at %}
+    {% blocktrans with trans_sender=notification.sender trans_created_at=notification.created %}
         Sent by {{ trans_sender }} at {{ trans_created_at }}
     {% endblocktrans %}
 
@@ -37,7 +37,7 @@
     </blockquote>
 
     <p>
-        {% blocktrans with trans_sender=notification.sender trans_created_at=notification.created_at %}
+        {% blocktrans with trans_sender=notification.sender trans_created_at=notification.created %}
             Sent by {{ trans_sender }} at {{ trans_created_at }}
         {% endblocktrans %}
     </p>
diff --git a/aleksis/core/util/core_helpers.py b/aleksis/core/util/core_helpers.py
index 060a0ef7aee06c51efe8ef2034e32b576e37fec6..bef457feee2b0dd53f72591523387d912c4038b1 100644
--- a/aleksis/core/util/core_helpers.py
+++ b/aleksis/core/util/core_helpers.py
@@ -1,4 +1,5 @@
 import os
+import sys
 import time
 from datetime import datetime, timedelta
 from importlib import import_module
@@ -7,9 +8,9 @@ from operator import itemgetter
 from typing import Any, Callable, Optional, Sequence, Union
 from uuid import uuid4
 
-try:
+if sys.version_info >= (3, 9):
     from importlib import metadata
-except ImportError:
+else:
     import importlib_metadata as metadata
 
 from django.conf import settings
diff --git a/aleksis/core/views.py b/aleksis/core/views.py
index fc1b0ecb8fdc577d9edb951afe3b25bab1cf9a54..c6df78ecb19284975d339ddedd5439f7515bd7ad 100644
--- a/aleksis/core/views.py
+++ b/aleksis/core/views.py
@@ -17,6 +17,7 @@ from haystack.inputs import AutoQuery
 from haystack.query import SearchQuerySet
 from haystack.views import SearchView
 from health_check.views import MainView
+from reversion import set_user
 from rules.contrib.views import PermissionRequiredMixin, permission_required
 
 from .filters import GroupFilter, PersonFilter
@@ -308,6 +309,7 @@ def edit_person(request: HttpRequest, id_: Optional[int] = None) -> HttpResponse
     if request.method == "POST":
         if edit_person_form.is_valid():
             with reversion.create_revision():
+                set_user(request.user)
                 edit_person_form.save(commit=True)
             messages.success(request, _("The person has been saved."))
 
@@ -344,6 +346,7 @@ def edit_group(request: HttpRequest, id_: Optional[int] = None) -> HttpResponse:
     if request.method == "POST":
         if edit_group_form.is_valid():
             with reversion.create_revision():
+                set_user(request.user)
                 group = edit_group_form.save(commit=True)
 
             messages.success(request, _("The group has been saved."))
@@ -543,6 +546,7 @@ def delete_person(request: HttpRequest, id_: int) -> HttpResponse:
     person = objectgetter_optional(Person)(request, id_)
 
     with reversion.create_revision():
+        set_user(request.user)
         person.save()
 
     person.delete()
@@ -556,6 +560,7 @@ def delete_group(request: HttpRequest, id_: int) -> HttpResponse:
     """View to delete an group."""
     group = objectgetter_optional(Group)(request, id_)
     with reversion.create_revision():
+        set_user(request.user)
         group.save()
 
     group.delete()
diff --git a/poetry.lock b/poetry.lock
index 29d94c7f1e176cc100173d4e118bec0aa34c62a7..2896275e72cc9c004709eb5a089be772087e9fea 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -46,14 +46,14 @@ reference = "gitlab"
 
 [[package]]
 name = "amqp"
-version = "2.6.1"
+version = "5.0.2"
 description = "Low-level AMQP client for Python (fork of amqplib)."
 category = "main"
 optional = true
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+python-versions = ">=3.6"
 
 [package.dependencies]
-vine = ">=1.1.3,<5.0.0a1"
+vine = "5.0.0"
 
 [[package]]
 name = "appdirs"
@@ -122,21 +122,6 @@ PyYAML = ">=3.13"
 six = ">=1.10.0"
 stevedore = ">=1.20.0"
 
-[[package]]
-name = "beautifulsoup4"
-version = "4.9.3"
-description = "Screen-scraping library"
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-soupsieve = {version = ">1.2", markers = "python_version >= \"3.0\""}
-
-[package.extras]
-html5lib = ["html5lib"]
-lxml = ["lxml"]
-
 [[package]]
 name = "billiard"
 version = "3.6.3.0"
@@ -199,19 +184,22 @@ django = ["Django (>=2.2,<4.0)"]
 
 [[package]]
 name = "celery"
-version = "4.4.7"
+version = "5.0.2"
 description = "Distributed Task Queue."
 category = "main"
 optional = true
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+python-versions = ">=3.6,"
 
 [package.dependencies]
 billiard = ">=3.6.3.0,<4.0"
+click = ">=7.0"
+click-didyoumean = ">=0.0.3"
+click-repl = ">=0.1.6"
 Django = {version = ">=1.11", optional = true, markers = "extra == \"django\""}
-kombu = ">=4.6.10,<4.7"
+kombu = ">=5.0.0,<6.0"
 pytz = ">0.0-dev"
 redis = {version = ">=3.2.0", optional = true, markers = "extra == \"redis\""}
-vine = "1.3.0"
+vine = ">=5.0.0,<6.0"
 
 [package.extras]
 arangodb = ["pyArango (>=1.3.2)"]
@@ -221,13 +209,13 @@ brotli = ["brotli (>=1.0.0)", "brotlipy (>=0.7.0)"]
 cassandra = ["cassandra-driver (<3.21.0)"]
 consul = ["python-consul"]
 cosmosdbsql = ["pydocumentdb (==2.3.2)"]
-couchbase = ["couchbase-cffi (<3.0.0)", "couchbase (<3.0.0)"]
+couchbase = ["couchbase (>=3.0.0)"]
 couchdb = ["pycouchdb"]
 django = ["Django (>=1.11)"]
 dynamodb = ["boto3 (>=1.9.178)"]
 elasticsearch = ["elasticsearch"]
-eventlet = ["eventlet (>=0.24.1)"]
-gevent = ["gevent"]
+eventlet = ["eventlet (>=0.26.1)"]
+gevent = ["gevent (>=1.0.0)"]
 librabbitmq = ["librabbitmq (>=1.5.0)"]
 lzma = ["backports.lzma"]
 memcache = ["pylibmc"]
@@ -236,7 +224,6 @@ msgpack = ["msgpack"]
 pymemcache = ["python-memcached"]
 pyro = ["pyro4"]
 redis = ["redis (>=3.2.0)"]
-riak = ["riak (>=2.0)"]
 s3 = ["boto3 (>=1.9.125)"]
 slmq = ["softlayer-messaging (>=1.0.3)"]
 solar = ["ephem"]
@@ -291,10 +278,34 @@ python-versions = "*"
 name = "click"
 version = "7.1.2"
 description = "Composable command line interface toolkit"
-category = "dev"
+category = "main"
 optional = false
 python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
 
+[[package]]
+name = "click-didyoumean"
+version = "0.0.3"
+description = "Enable git-like did-you-mean feature in click."
+category = "main"
+optional = true
+python-versions = "*"
+
+[package.dependencies]
+click = "*"
+
+[[package]]
+name = "click-repl"
+version = "0.1.6"
+description = "REPL plugin for Click"
+category = "main"
+optional = true
+python-versions = "*"
+
+[package.dependencies]
+click = "*"
+prompt-toolkit = "*"
+six = "*"
+
 [[package]]
 name = "colorama"
 version = "0.4.4"
@@ -458,14 +469,14 @@ django-appconf = "*"
 
 [[package]]
 name = "django-celery-results"
-version = "1.2.1"
+version = "2.0.0"
 description = "Celery result backends for Django."
 category = "main"
 optional = true
 python-versions = "*"
 
 [package.dependencies]
-celery = ">=4.4,<5.0"
+celery = ">=4.4,<6.0"
 
 [[package]]
 name = "django-ckeditor"
@@ -524,18 +535,6 @@ django = ">=1.11"
 persisting-theory = ">=0.2.1"
 six = "*"
 
-[[package]]
-name = "django-easy-audit"
-version = "1.3.1a1"
-description = "Yet another Django audit log app, hopefully the simplest one."
-category = "main"
-optional = false
-python-versions = ">=3.5"
-
-[package.dependencies]
-beautifulsoup4 = "*"
-django = ">=2.2,<3.2"
-
 [[package]]
 name = "django-favicon-plus-reloaded"
 version = "1.0.4"
@@ -620,7 +619,7 @@ django = ">=1.11"
 
 [[package]]
 name = "django-impersonate"
-version = "1.5.1"
+version = "1.7"
 description = "Django app to allow superusers to impersonate other users."
 category = "main"
 optional = false
@@ -667,7 +666,7 @@ six = "*"
 
 [[package]]
 name = "django-maintenance-mode"
-version = "0.15.0"
+version = "0.15.1"
 description = "django-maintenance-mode shows a 503 error page when maintenance-mode is on."
 category = "main"
 optional = false
@@ -675,7 +674,7 @@ python-versions = "*"
 
 [[package]]
 name = "django-material"
-version = "1.7.1"
+version = "1.7.3"
 description = "Material design for django forms and admin"
 category = "main"
 optional = false
@@ -686,7 +685,7 @@ six = "*"
 
 [[package]]
 name = "django-menu-generator"
-version = "1.0.4"
+version = "1.1.0"
 description = "A straightforward menu generator for Django"
 category = "main"
 optional = false
@@ -703,6 +702,17 @@ python-versions = "*"
 [package.dependencies]
 django = "*"
 
+[[package]]
+name = "django-model-utils"
+version = "4.0.0"
+description = "Django model mixins and utilities"
+category = "main"
+optional = false
+python-versions = "*"
+
+[package.dependencies]
+Django = ">=2.0.1"
+
 [[package]]
 name = "django-otp"
 version = "1.0.2"
@@ -980,7 +990,7 @@ yaml = ["ruamel.yaml"]
 
 [[package]]
 name = "faker"
-version = "4.14.2"
+version = "4.17.1"
 description = "Faker is a Python package that generates fake data for you."
 category = "main"
 optional = false
@@ -1175,18 +1185,18 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
 
 [[package]]
 name = "importlib-metadata"
-version = "2.0.0"
+version = "3.1.0"
 description = "Read metadata from Python packages"
 category = "main"
 optional = false
-python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
+python-versions = ">=3.6"
 
 [package.dependencies]
 zipp = ">=0.5"
 
 [package.extras]
 docs = ["sphinx", "rst.linker"]
-testing = ["packaging", "pep517", "importlib-resources (>=1.3)"]
+testing = ["packaging", "pep517", "unittest2", "importlib-resources (>=1.3)"]
 
 [[package]]
 name = "iniconfig"
@@ -1225,14 +1235,14 @@ i18n = ["Babel (>=0.8)"]
 
 [[package]]
 name = "kombu"
-version = "4.6.11"
+version = "5.0.2"
 description = "Messaging library for Python."
 category = "main"
 optional = true
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+python-versions = ">=3.6"
 
 [package.dependencies]
-amqp = ">=2.6.0,<2.7"
+amqp = ">=5.0.0,<6.0.0"
 importlib-metadata = {version = ">=0.18", markers = "python_version < \"3.8\""}
 
 [package.extras]
@@ -1370,11 +1380,11 @@ python-versions = "*"
 
 [[package]]
 name = "pillow"
-version = "7.2.0"
+version = "8.0.1"
 description = "Python Imaging Library (Fork)"
 category = "main"
 optional = false
-python-versions = ">=3.5"
+python-versions = ">=3.6"
 
 [[package]]
 name = "pluggy"
@@ -1392,7 +1402,7 @@ dev = ["pre-commit", "tox"]
 
 [[package]]
 name = "prometheus-client"
-version = "0.8.0"
+version = "0.9.0"
 description = "Python client for the Prometheus monitoring system."
 category = "main"
 optional = false
@@ -1401,6 +1411,17 @@ python-versions = "*"
 [package.extras]
 twisted = ["twisted"]
 
+[[package]]
+name = "prompt-toolkit"
+version = "3.0.8"
+description = "Library for building powerful interactive command lines in Python"
+category = "main"
+optional = true
+python-versions = ">=3.6.1"
+
+[package.dependencies]
+wcwidth = "*"
+
 [[package]]
 name = "psutil"
 version = "5.7.3"
@@ -1711,7 +1732,7 @@ socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"]
 
 [[package]]
 name = "restructuredtext-lint"
-version = "1.3.1"
+version = "1.3.2"
 description = "reStructuredText linter"
 category = "dev"
 optional = false
@@ -1808,14 +1829,6 @@ category = "dev"
 optional = false
 python-versions = "*"
 
-[[package]]
-name = "soupsieve"
-version = "2.0.1"
-description = "A modern CSS selector implementation for Beautiful Soup."
-category = "main"
-optional = false
-python-versions = ">=3.5"
-
 [[package]]
 name = "spdx-license-list"
 version = "0.5.1"
@@ -2034,18 +2047,18 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
 
 [[package]]
 name = "tqdm"
-version = "4.51.0"
+version = "4.54.0"
 description = "Fast, Extensible Progress Meter"
 category = "main"
 optional = false
-python-versions = ">=2.6, !=3.0.*, !=3.1.*"
+python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7"
 
 [package.extras]
-dev = ["py-make (>=0.1.0)", "twine", "argopt", "pydoc-markdown"]
+dev = ["py-make (>=0.1.0)", "twine", "argopt", "pydoc-markdown", "wheel"]
 
 [[package]]
 name = "twilio"
-version = "6.47.0"
+version = "6.48.0"
 description = "Twilio API client and TwiML generator"
 category = "main"
 optional = false
@@ -2088,11 +2101,19 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
 
 [[package]]
 name = "vine"
-version = "1.3.0"
+version = "5.0.0"
 description = "Promises, promises, promises."
 category = "main"
 optional = true
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+python-versions = ">=3.6"
+
+[[package]]
+name = "wcwidth"
+version = "0.2.5"
+description = "Measures the displayed width of unicode strings in a terminal"
+category = "main"
+optional = true
+python-versions = "*"
 
 [[package]]
 name = "webencodings"
@@ -2132,7 +2153,7 @@ ldap = ["django-auth-ldap"]
 [metadata]
 lock-version = "1.1"
 python-versions = "^3.7"
-content-hash = "ad08a984daa918b60656e0ae43f82cf7833097a121f783fdf6ad8d2603fdc60b"
+content-hash = "796fb4bd6779730135a6d2c08f09646dd3f91cdb59dfe2210bdfabd5050f0d2f"
 
 [metadata.files]
 alabaster = [
@@ -2143,8 +2164,8 @@ aleksis-builddeps = [
     {file = "AlekSIS-Builddeps-1.tar.gz", hash = "sha256:97a19597f422593cbdc438aabf17f95748126c8951df6ac7db7991fc99c108c4"},
 ]
 amqp = [
-    {file = "amqp-2.6.1-py2.py3-none-any.whl", hash = "sha256:aa7f313fb887c91f15474c1229907a04dac0b8135822d6603437803424c0aa59"},
-    {file = "amqp-2.6.1.tar.gz", hash = "sha256:70cdb10628468ff14e57ec2f751c7aa9e48e7e3651cfd62d431213c0c4e58f21"},
+    {file = "amqp-5.0.2-py3-none-any.whl", hash = "sha256:5b9062d5c0812335c75434bf17ce33d7a20ecfedaa0733faec7379868eb4068a"},
+    {file = "amqp-5.0.2.tar.gz", hash = "sha256:fcd5b3baeeb7fc19b3486ff6d10543099d40ae1f5c9196eae695d1cde1b2f784"},
 ]
 appdirs = [
     {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"},
@@ -2170,11 +2191,6 @@ bandit = [
     {file = "bandit-1.6.2-py2.py3-none-any.whl", hash = "sha256:336620e220cf2d3115877685e264477ff9d9abaeb0afe3dc7264f55fa17a3952"},
     {file = "bandit-1.6.2.tar.gz", hash = "sha256:41e75315853507aa145d62a78a2a6c5e3240fe14ee7c601459d0df9418196065"},
 ]
-beautifulsoup4 = [
-    {file = "beautifulsoup4-4.9.3-py2-none-any.whl", hash = "sha256:4c98143716ef1cb40bf7f39a8e3eec8f8b009509e74904ba3a7b315431577e35"},
-    {file = "beautifulsoup4-4.9.3-py3-none-any.whl", hash = "sha256:fff47e031e34ec82bf17e00da8f592fe7de69aeea38be00523c04623c04fb666"},
-    {file = "beautifulsoup4-4.9.3.tar.gz", hash = "sha256:84729e322ad1d5b4d25f805bfa05b902dd96450f43842c4e99067d5e1369eb25"},
-]
 billiard = [
     {file = "billiard-3.6.3.0-py3-none-any.whl", hash = "sha256:bff575450859a6e0fbc2f9877d9b715b0bbc07c3565bb7ed2280526a0cdf5ede"},
     {file = "billiard-3.6.3.0.tar.gz", hash = "sha256:d91725ce6425f33a97dfa72fb6bfef0e47d4652acd98a032bd1a7fbf06d5fa6a"},
@@ -2196,8 +2212,8 @@ calendarweek = [
     {file = "calendarweek-0.4.7.tar.gz", hash = "sha256:7655d6a4c3b4f6a4e01aa7d23b49cd121db0399050e9c08cd8d1210155be25dd"},
 ]
 celery = [
-    {file = "celery-4.4.7-py2.py3-none-any.whl", hash = "sha256:a92e1d56e650781fb747032a3997d16236d037c8199eacd5217d1a72893bca45"},
-    {file = "celery-4.4.7.tar.gz", hash = "sha256:d220b13a8ed57c78149acf82c006785356071844afe0b27012a4991d44026f9f"},
+    {file = "celery-5.0.2-py3-none-any.whl", hash = "sha256:930c3acd55349d028c4e7104a7d377729cbcca19d9fce470c17172d9e7f9a8b6"},
+    {file = "celery-5.0.2.tar.gz", hash = "sha256:012c814967fe89e3f5d2cf49df2dba3de5f29253a7f4f2270e8fce6b901b4ebf"},
 ]
 celery-haystack = [
     {file = "celery-haystack-0.10.tar.gz", hash = "sha256:b6e2a3c70071bef0838ca1a7d9f14fae6c2ecf385704092e59b82147a1ee552e"},
@@ -2219,6 +2235,13 @@ click = [
     {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"},
     {file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"},
 ]
+click-didyoumean = [
+    {file = "click-didyoumean-0.0.3.tar.gz", hash = "sha256:112229485c9704ff51362fe34b2d4f0b12fc71cc20f6d2b3afabed4b8bfa6aeb"},
+]
+click-repl = [
+    {file = "click-repl-0.1.6.tar.gz", hash = "sha256:b9f29d52abc4d6059f8e276132a111ab8d94980afe6a5432b9d996544afa95d5"},
+    {file = "click_repl-0.1.6-py3-none-any.whl", hash = "sha256:9c4c3d022789cae912aad8a3f5e1d7c2cdd016ee1225b5212ad3e8691563cda5"},
+]
 colorama = [
     {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"},
     {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"},
@@ -2306,8 +2329,8 @@ django-celery-email = [
     {file = "django_celery_email-3.0.0-py2.py3-none-any.whl", hash = "sha256:0f72da39cb2ea83c69440566e87f27cd72f68f247f98ce99fb29889fcf329406"},
 ]
 django-celery-results = [
-    {file = "django_celery_results-1.2.1-py2.py3-none-any.whl", hash = "sha256:a29ab580f0e38c66c39f51cc426bbdbb2a391b8cc0867df9dea748db2c961db2"},
-    {file = "django_celery_results-1.2.1.tar.gz", hash = "sha256:e390f70cc43bbc2cd7c8e4607dc29ab6211a2ab968f93677583f0160921f670c"},
+    {file = "django_celery_results-2.0.0-py2.py3-none-any.whl", hash = "sha256:f82280a9a25c44048b9e64ae4d47ade7d522c8221304b0e25388080021b95468"},
+    {file = "django_celery_results-2.0.0.tar.gz", hash = "sha256:754e01f22f70fddee5f2ca95c18f183fccee42ad98f9803577bffa717d45ac5d"},
 ]
 django-ckeditor = [
     {file = "django-ckeditor-6.0.0.tar.gz", hash = "sha256:29fd1a333cb9741ac2c3fd4e427a5c00115ed33a2389716a09af7656022dcdde"},
@@ -2328,10 +2351,6 @@ django-dynamic-preferences = [
     {file = "django-dynamic-preferences-1.10.1.tar.gz", hash = "sha256:e4b2bb7b2563c5064ba56dd76441c77e06b850ff1466a386a1cd308909a6c7de"},
     {file = "django_dynamic_preferences-1.10.1-py2.py3-none-any.whl", hash = "sha256:9419fa925fd2cbb665269ae72059eb3058bf080913d853419b827e4e7a141902"},
 ]
-django-easy-audit = [
-    {file = "django-easy-audit-1.3.1a1.tar.gz", hash = "sha256:1aaa7f19a5a6d7f31698661b061e662df50d2506e0828a1cfb681a95c3b34fea"},
-    {file = "django_easy_audit-1.3.1a1-py3-none-any.whl", hash = "sha256:64448dce510673939825b6d5dec674f6c2ac069ab4b4b95cff7f3f796da7c786"},
-]
 django-favicon-plus-reloaded = [
     {file = "django-favicon-plus-reloaded-1.0.4.tar.gz", hash = "sha256:90c761c636a338e6e9fb1d086649d82095085f92cff816c9cf074607f28c85a5"},
     {file = "django_favicon_plus_reloaded-1.0.4-py3-none-any.whl", hash = "sha256:26e4316d41328a61ced52c7fc0ead795f0eb194d6a30311c34a9833c6fe30a7c"},
@@ -2361,7 +2380,7 @@ django-health-check = [
     {file = "django_health_check-3.16.1-py2.py3-none-any.whl", hash = "sha256:8b0835f04ebaeb0d12498a5ef47dd22196237c3987ff28bcce9ed28b5a169d5e"},
 ]
 django-impersonate = [
-    {file = "django-impersonate-1.5.1.tar.gz", hash = "sha256:7c786ffaa7a5dd430f9277b53a64676c470b684eee5aa52c3b483298860d09b4"},
+    {file = "django-impersonate-1.7.tar.gz", hash = "sha256:1dadb5239a5cb79d4327ef3000cd989f9d4e76428a5e2a080496a53b41fa785f"},
 ]
 django-ipware = [
     {file = "django-ipware-3.0.2.tar.gz", hash = "sha256:c7df8e1410a8e5d6b1fbae58728402ea59950f043c3582e033e866f0f0cf5e94"},
@@ -2378,19 +2397,23 @@ django-jsonstore = [
     {file = "django-jsonstore-0.4.1.tar.gz", hash = "sha256:d6e42152af3f924e4657c99e80144ba9a6410799256f6134b5a4e9fa4282ec10"},
 ]
 django-maintenance-mode = [
-    {file = "django-maintenance-mode-0.15.0.tar.gz", hash = "sha256:f8c500b077045db5444d4d4eb613fd1085b51f960d6d61b13b1cce461e1d0102"},
-    {file = "django_maintenance_mode-0.15.0-py3-none-any.whl", hash = "sha256:54b5afe3282d450bc4161461c5d518b8097cbb29a5fdd0baf1b8c3a1e5f90c08"},
+    {file = "django-maintenance-mode-0.15.1.tar.gz", hash = "sha256:d07102cab88dd707a82232f0c552c287e62aa53af582a0ca4f2aa31f14f5ed27"},
+    {file = "django_maintenance_mode-0.15.1-py3-none-any.whl", hash = "sha256:8c45b400253076655562c99a2ffb88f8353fc1c84496c1b9de812cc8132aea6f"},
 ]
 django-material = [
-    {file = "django-material-1.7.1.tar.gz", hash = "sha256:77cfcc83da7724066b5b78bbb72cd4fbe752b38ffb20cb6ca36feb9657d9f19f"},
-    {file = "django_material-1.7.1-py2.py3-none-any.whl", hash = "sha256:2b70ef05d4c6805554e91efc81c34f71081a5287f016d0172b7368b0a465d759"},
+    {file = "django-material-1.7.3.tar.gz", hash = "sha256:00599cd87f19f3a66be065865b223801afa9da680744a5eac10c489a10d98eba"},
+    {file = "django_material-1.7.3-py2.py3-none-any.whl", hash = "sha256:6c010aa47618ceae2617f8a476b55aaed0884b1a4a6f5bdf969448a1ba72e352"},
 ]
 django-menu-generator = [
-    {file = "django-menu-generator-1.0.4.tar.gz", hash = "sha256:ce71a5055c16933c8aff64fb36c21e5cf8b6d505733aceed1252f8b99369a378"},
+    {file = "django-menu-generator-1.1.0.tar.gz", hash = "sha256:e8f9b808080c4b281f9c5962f39078c76c2007a5ef8ab1f7a81c81dbbe6a9848"},
 ]
 django-middleware-global-request = [
     {file = "django-middleware-global-request-0.1.2.tar.gz", hash = "sha256:f6490759bc9f7dbde4001709554e29ca715daf847f2222914b4e47117dca9313"},
 ]
+django-model-utils = [
+    {file = "django-model-utils-4.0.0.tar.gz", hash = "sha256:adf09e5be15122a7f4e372cb5a6dd512bbf8d78a23a90770ad0983ee9d909061"},
+    {file = "django_model_utils-4.0.0-py2.py3-none-any.whl", hash = "sha256:9cf882e5b604421b62dbe57ad2b18464dc9c8f963fc3f9831badccae66c1139c"},
+]
 django-otp = [
     {file = "django-otp-1.0.2.tar.gz", hash = "sha256:f523fb9dec420f28a29d3e2ad72ac06f64588956ed4f2b5b430d8e957ebb8287"},
     {file = "django_otp-1.0.2-py3-none-any.whl", hash = "sha256:8ba5ab9bd2738c7321376c349d7cce49cf4404e79f6804e0a3cc462a91728e18"},
@@ -2472,8 +2495,8 @@ dynaconf = [
     {file = "dynaconf-3.1.2.tar.gz", hash = "sha256:9b34ab2f811a81755f5eb4beac77a69e1e0887528c7e37fc4bc83fed52dcf502"},
 ]
 faker = [
-    {file = "Faker-4.14.2-py3-none-any.whl", hash = "sha256:ce1c38823eb0f927567cde5bf2e7c8ca565c7a70316139342050ce2ca74b4026"},
-    {file = "Faker-4.14.2.tar.gz", hash = "sha256:6afc461ab3f779c9c16e299fc731d775e39ea7e8e063b3053ee359ae198a15ca"},
+    {file = "Faker-4.17.1-py3-none-any.whl", hash = "sha256:5398268e1d751ffdb3ed36b8a790ed98659200599b368eec38a02eed15bce997"},
+    {file = "Faker-4.17.1.tar.gz", hash = "sha256:d4183b8f57316de3be27cd6c3b40e9f9343d27c95c96179f027316c58c2c239e"},
 ]
 flake8 = [
     {file = "flake8-3.8.4-py2.py3-none-any.whl", hash = "sha256:749dbbd6bfd0cf1318af27bf97a14e28e5ff548ef8e5b1566ccfb25a11e7c839"},
@@ -2537,8 +2560,8 @@ imagesize = [
     {file = "imagesize-1.2.0.tar.gz", hash = "sha256:b1f6b5a4eab1f73479a50fb79fcf729514a900c341d8503d62a62dbc4127a2b1"},
 ]
 importlib-metadata = [
-    {file = "importlib_metadata-2.0.0-py2.py3-none-any.whl", hash = "sha256:cefa1a2f919b866c5beb7c9f7b0ebb4061f30a8a9bf16d609b000e2dfaceb9c3"},
-    {file = "importlib_metadata-2.0.0.tar.gz", hash = "sha256:77a540690e24b0305878c37ffd421785a6f7e53c8b5720d211b211de8d0e95da"},
+    {file = "importlib_metadata-3.1.0-py2.py3-none-any.whl", hash = "sha256:590690d61efdd716ff82c39ca9a9d4209252adfe288a4b5721181050acbd4175"},
+    {file = "importlib_metadata-3.1.0.tar.gz", hash = "sha256:d9b8a46a0885337627a6430db287176970fff18ad421becec1d64cfc763c2099"},
 ]
 iniconfig = [
     {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"},
@@ -2553,8 +2576,8 @@ jinja2 = [
     {file = "Jinja2-2.11.2.tar.gz", hash = "sha256:89aab215427ef59c34ad58735269eb58b1a5808103067f7bb9d5836c651b3bb0"},
 ]
 kombu = [
-    {file = "kombu-4.6.11-py2.py3-none-any.whl", hash = "sha256:be48cdffb54a2194d93ad6533d73f69408486483d189fe9f5990ee24255b0e0a"},
-    {file = "kombu-4.6.11.tar.gz", hash = "sha256:ca1b45faac8c0b18493d02a8571792f3c40291cf2bcf1f55afed3d8f3aa7ba74"},
+    {file = "kombu-5.0.2-py2.py3-none-any.whl", hash = "sha256:6dc509178ac4269b0e66ab4881f70a2035c33d3a622e20585f965986a5182006"},
+    {file = "kombu-5.0.2.tar.gz", hash = "sha256:f4965fba0a4718d47d470beeb5d6446e3357a62402b16c510b6a2f251e05ac3c"},
 ]
 libsass = [
     {file = "libsass-0.20.1-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:4a246e4b88fd279abef8b669206228c92534d96ddcd0770d7012088c408dff23"},
@@ -2658,40 +2681,46 @@ phonenumbers = [
     {file = "phonenumbers-8.12.13.tar.gz", hash = "sha256:96d02120a3481e22d8a8eb5e4595ceec1930855749f6e4a06ef931881f59f562"},
 ]
 pillow = [
-    {file = "Pillow-7.2.0-cp35-cp35m-macosx_10_10_intel.whl", hash = "sha256:1ca594126d3c4def54babee699c055a913efb01e106c309fa6b04405d474d5ae"},
-    {file = "Pillow-7.2.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:c92302a33138409e8f1ad16731568c55c9053eee71bb05b6b744067e1b62380f"},
-    {file = "Pillow-7.2.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:8dad18b69f710bf3a001d2bf3afab7c432785d94fcf819c16b5207b1cfd17d38"},
-    {file = "Pillow-7.2.0-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:431b15cffbf949e89df2f7b48528be18b78bfa5177cb3036284a5508159492b5"},
-    {file = "Pillow-7.2.0-cp35-cp35m-win32.whl", hash = "sha256:09d7f9e64289cb40c2c8d7ad674b2ed6105f55dc3b09aa8e4918e20a0311e7ad"},
-    {file = "Pillow-7.2.0-cp35-cp35m-win_amd64.whl", hash = "sha256:0295442429645fa16d05bd567ef5cff178482439c9aad0411d3f0ce9b88b3a6f"},
-    {file = "Pillow-7.2.0-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:ec29604081f10f16a7aea809ad42e27764188fc258b02259a03a8ff7ded3808d"},
-    {file = "Pillow-7.2.0-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:612cfda94e9c8346f239bf1a4b082fdd5c8143cf82d685ba2dba76e7adeeb233"},
-    {file = "Pillow-7.2.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0a80dd307a5d8440b0a08bd7b81617e04d870e40a3e46a32d9c246e54705e86f"},
-    {file = "Pillow-7.2.0-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:06aba4169e78c439d528fdeb34762c3b61a70813527a2c57f0540541e9f433a8"},
-    {file = "Pillow-7.2.0-cp36-cp36m-win32.whl", hash = "sha256:f7e30c27477dffc3e85c2463b3e649f751789e0f6c8456099eea7ddd53be4a8a"},
-    {file = "Pillow-7.2.0-cp36-cp36m-win_amd64.whl", hash = "sha256:ffe538682dc19cc542ae7c3e504fdf54ca7f86fb8a135e59dd6bc8627eae6cce"},
-    {file = "Pillow-7.2.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:94cf49723928eb6070a892cb39d6c156f7b5a2db4e8971cb958f7b6b104fb4c4"},
-    {file = "Pillow-7.2.0-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:6edb5446f44d901e8683ffb25ebdfc26988ee813da3bf91e12252b57ac163727"},
-    {file = "Pillow-7.2.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:52125833b070791fcb5710fabc640fc1df07d087fc0c0f02d3661f76c23c5b8b"},
-    {file = "Pillow-7.2.0-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:9ad7f865eebde135d526bb3163d0b23ffff365cf87e767c649550964ad72785d"},
-    {file = "Pillow-7.2.0-cp37-cp37m-win32.whl", hash = "sha256:c79f9c5fb846285f943aafeafda3358992d64f0ef58566e23484132ecd8d7d63"},
-    {file = "Pillow-7.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d350f0f2c2421e65fbc62690f26b59b0bcda1b614beb318c81e38647e0f673a1"},
-    {file = "Pillow-7.2.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:6d7741e65835716ceea0fd13a7d0192961212fd59e741a46bbed7a473c634ed6"},
-    {file = "Pillow-7.2.0-cp38-cp38-manylinux1_i686.whl", hash = "sha256:edf31f1150778abd4322444c393ab9c7bd2af271dd4dafb4208fb613b1f3cdc9"},
-    {file = "Pillow-7.2.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:d08b23fdb388c0715990cbc06866db554e1822c4bdcf6d4166cf30ac82df8c41"},
-    {file = "Pillow-7.2.0-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:5e51ee2b8114def244384eda1c82b10e307ad9778dac5c83fb0943775a653cd8"},
-    {file = "Pillow-7.2.0-cp38-cp38-win32.whl", hash = "sha256:725aa6cfc66ce2857d585f06e9519a1cc0ef6d13f186ff3447ab6dff0a09bc7f"},
-    {file = "Pillow-7.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:a060cf8aa332052df2158e5a119303965be92c3da6f2d93b6878f0ebca80b2f6"},
-    {file = "Pillow-7.2.0-pp36-pypy36_pp73-win32.whl", hash = "sha256:25930fadde8019f374400f7986e8404c8b781ce519da27792cbe46eabec00c4d"},
-    {file = "Pillow-7.2.0.tar.gz", hash = "sha256:97f9e7953a77d5a70f49b9a48da7776dc51e9b738151b22dacf101641594a626"},
+    {file = "Pillow-8.0.1-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:b63d4ff734263ae4ce6593798bcfee6dbfb00523c82753a3a03cbc05555a9cc3"},
+    {file = "Pillow-8.0.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:5f9403af9c790cc18411ea398a6950ee2def2a830ad0cfe6dc9122e6d528b302"},
+    {file = "Pillow-8.0.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:6b4a8fd632b4ebee28282a9fef4c341835a1aa8671e2770b6f89adc8e8c2703c"},
+    {file = "Pillow-8.0.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:cc3ea6b23954da84dbee8025c616040d9aa5eaf34ea6895a0a762ee9d3e12e11"},
+    {file = "Pillow-8.0.1-cp36-cp36m-win32.whl", hash = "sha256:d8a96747df78cda35980905bf26e72960cba6d355ace4780d4bdde3b217cdf1e"},
+    {file = "Pillow-8.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:7ba0ba61252ab23052e642abdb17fd08fdcfdbbf3b74c969a30c58ac1ade7cd3"},
+    {file = "Pillow-8.0.1-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:795e91a60f291e75de2e20e6bdd67770f793c8605b553cb6e4387ce0cb302e09"},
+    {file = "Pillow-8.0.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:0a2e8d03787ec7ad71dc18aec9367c946ef8ef50e1e78c71f743bc3a770f9fae"},
+    {file = "Pillow-8.0.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:006de60d7580d81f4a1a7e9f0173dc90a932e3905cc4d47ea909bc946302311a"},
+    {file = "Pillow-8.0.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:bd7bf289e05470b1bc74889d1466d9ad4a56d201f24397557b6f65c24a6844b8"},
+    {file = "Pillow-8.0.1-cp37-cp37m-win32.whl", hash = "sha256:95edb1ed513e68bddc2aee3de66ceaf743590bf16c023fb9977adc4be15bd3f0"},
+    {file = "Pillow-8.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:e38d58d9138ef972fceb7aeec4be02e3f01d383723965bfcef14d174c8ccd039"},
+    {file = "Pillow-8.0.1-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:d3d07c86d4efa1facdf32aa878bd508c0dc4f87c48125cc16b937baa4e5b5e11"},
+    {file = "Pillow-8.0.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:fbd922f702582cb0d71ef94442bfca57624352622d75e3be7a1e7e9360b07e72"},
+    {file = "Pillow-8.0.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:92c882b70a40c79de9f5294dc99390671e07fc0b0113d472cbea3fde15db1792"},
+    {file = "Pillow-8.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:7c9401e68730d6c4245b8e361d3d13e1035cbc94db86b49dc7da8bec235d0015"},
+    {file = "Pillow-8.0.1-cp38-cp38-win32.whl", hash = "sha256:6c1aca8231625115104a06e4389fcd9ec88f0c9befbabd80dc206c35561be271"},
+    {file = "Pillow-8.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:cc9ec588c6ef3a1325fa032ec14d97b7309db493782ea8c304666fb10c3bd9a7"},
+    {file = "Pillow-8.0.1-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:eb472586374dc66b31e36e14720747595c2b265ae962987261f044e5cce644b5"},
+    {file = "Pillow-8.0.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:0eeeae397e5a79dc088d8297a4c2c6f901f8fb30db47795113a4a605d0f1e5ce"},
+    {file = "Pillow-8.0.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:81f812d8f5e8a09b246515fac141e9d10113229bc33ea073fec11403b016bcf3"},
+    {file = "Pillow-8.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:895d54c0ddc78a478c80f9c438579ac15f3e27bf442c2a9aa74d41d0e4d12544"},
+    {file = "Pillow-8.0.1-cp39-cp39-win32.whl", hash = "sha256:2fb113757a369a6cdb189f8df3226e995acfed0a8919a72416626af1a0a71140"},
+    {file = "Pillow-8.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:59e903ca800c8cfd1ebe482349ec7c35687b95e98cefae213e271c8c7fffa021"},
+    {file = "Pillow-8.0.1-pp36-pypy36_pp73-macosx_10_10_x86_64.whl", hash = "sha256:5abd653a23c35d980b332bc0431d39663b1709d64142e3652890df4c9b6970f6"},
+    {file = "Pillow-8.0.1-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:4b0ef2470c4979e345e4e0cc1bbac65fda11d0d7b789dbac035e4c6ce3f98adb"},
+    {file = "Pillow-8.0.1-pp37-pypy37_pp73-win32.whl", hash = "sha256:8de332053707c80963b589b22f8e0229f1be1f3ca862a932c1bcd48dafb18dd8"},
+    {file = "Pillow-8.0.1.tar.gz", hash = "sha256:11c5c6e9b02c9dac08af04f093eb5a2f84857df70a7d4a6a6ad461aca803fb9e"},
 ]
 pluggy = [
     {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"},
     {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"},
 ]
 prometheus-client = [
-    {file = "prometheus_client-0.8.0-py2.py3-none-any.whl", hash = "sha256:983c7ac4b47478720db338f1491ef67a100b474e3bc7dafcbaefb7d0b8f9b01c"},
-    {file = "prometheus_client-0.8.0.tar.gz", hash = "sha256:c6e6b706833a6bd1fd51711299edee907857be10ece535126a158f911ee80915"},
+    {file = "prometheus_client-0.9.0-py2.py3-none-any.whl", hash = "sha256:b08c34c328e1bf5961f0b4352668e6c8f145b4a087e09b7296ef62cbe4693d35"},
+    {file = "prometheus_client-0.9.0.tar.gz", hash = "sha256:9da7b32f02439d8c04f7777021c304ed51d9ec180604700c1ba72a4d44dceb03"},
+]
+prompt-toolkit = [
+    {file = "prompt_toolkit-3.0.8-py3-none-any.whl", hash = "sha256:7debb9a521e0b1ee7d2fe96ee4bd60ef03c6492784de0547337ca4433e46aa63"},
+    {file = "prompt_toolkit-3.0.8.tar.gz", hash = "sha256:25c95d2ac813909f813c93fde734b6e44406d1477a9faef7c915ff37d39c0a8c"},
 ]
 psutil = [
     {file = "psutil-5.7.3-cp27-none-win32.whl", hash = "sha256:1cd6a0c9fb35ece2ccf2d1dd733c1e165b342604c67454fd56a4c12e0a106787"},
@@ -2922,7 +2951,7 @@ requests = [
     {file = "requests-2.25.0.tar.gz", hash = "sha256:7f1a0b932f4a60a1a65caa4263921bb7d9ee911957e0ae4a23a6dd08185ad5f8"},
 ]
 restructuredtext-lint = [
-    {file = "restructuredtext_lint-1.3.1.tar.gz", hash = "sha256:470e53b64817211a42805c3a104d2216f6f5834b22fe7adb637d1de4d6501fb8"},
+    {file = "restructuredtext_lint-1.3.2.tar.gz", hash = "sha256:d3b10a1fe2ecac537e51ae6d151b223b78de9fafdd50e5eb6b08c243df173c80"},
 ]
 "ruamel.yaml" = [
     {file = "ruamel.yaml-0.16.12-py2.py3-none-any.whl", hash = "sha256:012b9470a0ea06e4e44e99e7920277edf6b46eee0232a04487ea73a7386340a5"},
@@ -2950,8 +2979,6 @@ restructuredtext-lint = [
     {file = "ruamel.yaml.clib-0.2.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:5254af7d8bdf4d5484c089f929cb7f5bafa59b4f01d4f48adda4be41e6d29f99"},
     {file = "ruamel.yaml.clib-0.2.2-cp38-cp38-win32.whl", hash = "sha256:74161d827407f4db9072011adcfb825b5258a5ccb3d2cd518dd6c9edea9e30f1"},
     {file = "ruamel.yaml.clib-0.2.2-cp38-cp38-win_amd64.whl", hash = "sha256:058a1cc3df2a8aecc12f983a48bda99315cebf55a3b3a5463e37bb599b05727b"},
-    {file = "ruamel.yaml.clib-0.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c6ac7e45367b1317e56f1461719c853fd6825226f45b835df7436bb04031fd8a"},
-    {file = "ruamel.yaml.clib-0.2.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:b4b0d31f2052b3f9f9b5327024dc629a253a83d8649d4734ca7f35b60ec3e9e5"},
     {file = "ruamel.yaml.clib-0.2.2.tar.gz", hash = "sha256:2d24bd98af676f4990c4d715bcdc2a60b19c56a3fb3a763164d2d8ca0e806ba7"},
 ]
 rules = [
@@ -2981,10 +3008,6 @@ snowballstemmer = [
     {file = "snowballstemmer-2.0.0-py2.py3-none-any.whl", hash = "sha256:209f257d7533fdb3cb73bdbd24f436239ca3b2fa67d56f6ff88e86be08cc5ef0"},
     {file = "snowballstemmer-2.0.0.tar.gz", hash = "sha256:df3bac3df4c2c01363f3dd2cfa78cce2840a79b9f1c2d2de9ce8d31683992f52"},
 ]
-soupsieve = [
-    {file = "soupsieve-2.0.1-py3-none-any.whl", hash = "sha256:1634eea42ab371d3d346309b93df7870a88610f0725d47528be902a0d95ecc55"},
-    {file = "soupsieve-2.0.1.tar.gz", hash = "sha256:a59dc181727e95d25f781f0eb4fd1825ff45590ec8ff49eadfd7f1a537cc0232"},
-]
 spdx-license-list = [
     {file = "spdx_license_list-0.5.1-py3-none-any.whl", hash = "sha256:32f1401e0077b46ba8b3d9c648b6503ef1d49c41aab51aa13816be2dde3b4a13"},
     {file = "spdx_license_list-0.5.1.tar.gz", hash = "sha256:64cb5de37724c64cdeccafa2ae68667ff8ccdb7b688f51c1c2be82d7ebe3a112"},
@@ -3057,11 +3080,11 @@ toml = [
     {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
 ]
 tqdm = [
-    {file = "tqdm-4.51.0-py2.py3-none-any.whl", hash = "sha256:9ad44aaf0fc3697c06f6e05c7cf025dd66bc7bcb7613c66d85f4464c47ac8fad"},
-    {file = "tqdm-4.51.0.tar.gz", hash = "sha256:ef54779f1c09f346b2b5a8e5c61f96fbcb639929e640e59f8cf810794f406432"},
+    {file = "tqdm-4.54.0-py2.py3-none-any.whl", hash = "sha256:9e7b8ab0ecbdbf0595adadd5f0ebbb9e69010e0bd48bbb0c15e550bf2a5292df"},
+    {file = "tqdm-4.54.0.tar.gz", hash = "sha256:5c0d04e06ccc0da1bd3fa5ae4550effcce42fcad947b4a6cafa77bdc9b09ff22"},
 ]
 twilio = [
-    {file = "twilio-6.47.0.tar.gz", hash = "sha256:effb4d6e9e9a9069065fbe21dea844597376ae6d6333626f14b05ba6b35bbb22"},
+    {file = "twilio-6.48.0.tar.gz", hash = "sha256:745f3dfe6685e001ddd2baa290b37377426388906ea6d3549e06fb2f669da7b3"},
 ]
 typed-ast = [
     {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3"},
@@ -3096,8 +3119,12 @@ urllib3 = [
     {file = "urllib3-1.26.2.tar.gz", hash = "sha256:19188f96923873c92ccb987120ec4acaa12f0461fa9ce5d3d0772bc965a39e08"},
 ]
 vine = [
-    {file = "vine-1.3.0-py2.py3-none-any.whl", hash = "sha256:ea4947cc56d1fd6f2095c8d543ee25dad966f78692528e68b4fada11ba3f98af"},
-    {file = "vine-1.3.0.tar.gz", hash = "sha256:133ee6d7a9016f177ddeaf191c1f58421a1dcc6ee9a42c58b34bed40e1d2cd87"},
+    {file = "vine-5.0.0-py2.py3-none-any.whl", hash = "sha256:4c9dceab6f76ed92105027c49c823800dd33cacce13bdedc5b914e3514b7fb30"},
+    {file = "vine-5.0.0.tar.gz", hash = "sha256:7d3b1624a953da82ef63462013bbd271d3eb75751489f9807598e8f340bd637e"},
+]
+wcwidth = [
+    {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"},
+    {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"},
 ]
 webencodings = [
     {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"},
diff --git a/pyproject.toml b/pyproject.toml
index a90ef7a8b3f9c1e39e1632707c56856b6682f266..9d0c7e7a40c795c77697aefea7b04cbef1b8e284 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -37,11 +37,10 @@ python = "^3.7"
 Django = "^3.0"
 django-any-js = "^1.0"
 django-debug-toolbar = "^2.0"
-django-easy-audit = {version ="^1.2rc1", allow-prereleases = true}
 django-middleware-global-request = "^0.1.2"
 django-menu-generator = "^1.0.4"
 django-tables2 = "^2.1"
-Pillow = "^7.0"
+Pillow = "^8.0"
 django-phonenumber-field = {version = "<5.1", extras = ["phonenumbers"]}
 django-sass-processor = "^0.8"
 libsass = "^0.20.0"
@@ -69,8 +68,8 @@ html2text = "^2020.0.0"
 django-ckeditor = "^6.0.0"
 django-js-reverse = "^0.9.1"
 calendarweek = "^0.4.3"
-Celery = {version="^4.4.0", optional=true, extras=["django", "redis"]}
-django-celery-results = {version="^1.1.2", optional=true}
+Celery = {version="^5.0.0", optional=true, extras=["django", "redis"]}
+django-celery-results = {version="^2.0.0", optional=true}
 django-celery-beat = {version="^2.0.0", optional=true}
 django-celery-email = {version="^3.0.0", optional=true}
 django-jsonstore = "^0.4.1"
@@ -91,7 +90,8 @@ django-health-check = "^3.12.1"
 psutil = "^5.7.0"
 celery-progress = "^0.0.14"
 django-prometheus = "^2.1.0"
-importlib-metadata = {version = "^2.0.0", python = "<3.8"}
+importlib-metadata = {version = "^3.0.0", python = "<3.9"}
+django-model-utils = "^4.0.0"
 
 [tool.poetry.extras]
 ldap = ["django-auth-ldap"]
diff --git a/tox.ini b/tox.ini
index cbe278cd8f7b1f3cd38760cb63a1b009786edcd2..98fce3af53aa48d1eac2e28454c26e7b74c23f72 100644
--- a/tox.ini
+++ b/tox.ini
@@ -49,9 +49,8 @@ exclude = migrations,tests
 ignore = BLK100,E203,E231,W503,D100,D101,D102,D103,D104,D105,D106,D107,RST215,RST214,F821,F841,S106,T100,T101,DJ05
 
 [isort]
+profile = black
 line_length = 100
-multi_line_output = 3
-include_trailing_comma = 1
 default_section = THIRDPARTY
 known_first_party = aleksis
 known_django = django