diff --git a/AKModel/admin.py b/AKModel/admin.py
index ae8da12f3a60f47c64cb21b6611ead2b7b099059..4675d84262aa5c38ca1eda84a2ecc2b5c1a6a54b 100644
--- a/AKModel/admin.py
+++ b/AKModel/admin.py
@@ -3,8 +3,9 @@ from django.apps import apps
 from django.contrib import admin
 from django.contrib.admin import SimpleListFilter, RelatedFieldListFilter
 from django.db.models import Count, F
+from django.http import HttpResponseRedirect
 from django.shortcuts import render, redirect
-from django.urls import reverse_lazy
+from django.urls import reverse_lazy, path
 from django.utils import timezone
 from django.utils.html import format_html
 from django.utils.safestring import mark_safe
@@ -17,6 +18,7 @@ from AKModel.availability.models import Availability
 from AKModel.models import Event, AKOwner, AKCategory, AKTrack, AKTag, AKRequirement, AK, AKSlot, Room, AKOrgaMessage, \
     ConstraintViolation
 from AKModel.urls import get_admin_urls_event_wizard, get_admin_urls_event
+from AKModel.views import CVMarkResolvedView, CVSetLevelViolationView, CVSetLevelWarningView
 
 
 class EventRelatedFieldListFilter(RelatedFieldListFilter):
@@ -317,3 +319,28 @@ class ConstraintViolationAdmin(admin.ModelAdmin):
     list_filter = ['event']
     readonly_fields = ['timestamp']
     form = ConstraintViolationAdminForm
+    actions = ['mark_resolved', 'set_violation', 'set_warning']
+
+    def get_urls(self):
+        urls = [
+            path('mark-resolved/', CVMarkResolvedView.as_view(), name="cv-mark-resolved"),
+            path('set-violation/', CVSetLevelViolationView.as_view(), name="cv-set-violation"),
+            path('set-warning/', CVSetLevelWarningView.as_view(), name="cv-set-warning"),
+        ]
+        urls.extend(super().get_urls())
+        return urls
+
+    def mark_resolved(self, request, queryset):
+        selected = queryset.values_list('pk', flat=True)
+        return HttpResponseRedirect(f"{reverse_lazy('admin:cv-mark-resolved')}?pks={','.join(str(pk) for pk in selected)}")
+    mark_resolved.short_description = _("Mark Constraint Violations as manually resolved")
+
+    def set_violation(self, request, queryset):
+        selected = queryset.values_list('pk', flat=True)
+        return HttpResponseRedirect(f"{reverse_lazy('admin:cv-set-violation')}?pks={','.join(str(pk) for pk in selected)}")
+    set_violation.short_description = _('Set to Constraint Violations to level "violation"')
+
+    def set_warning(self, request, queryset):
+        selected = queryset.values_list('pk', flat=True)
+        return HttpResponseRedirect(f"{reverse_lazy('admin:cv-set-warning')}?pks={','.join(str(pk) for pk in selected)}")
+    set_warning.short_description = _('Set Constraint Violations to level "warning"')
diff --git a/AKModel/forms.py b/AKModel/forms.py
index 28e5c678be075e8ee71831e961de17472d95c8bd..d72c973786776736cf176db9c5b3ee916e842584 100644
--- a/AKModel/forms.py
+++ b/AKModel/forms.py
@@ -74,6 +74,10 @@ class AdminIntermediateForm(forms.Form):
     pass
 
 
+class AdminIntermediateActionForm(AdminIntermediateForm):
+    pks = forms.CharField(widget=forms.HiddenInput)
+
+
 class SlideExportForm(AdminIntermediateForm):
     num_next = forms.IntegerField(
         min_value=0,
diff --git a/AKModel/locale/de_DE/LC_MESSAGES/django.po b/AKModel/locale/de_DE/LC_MESSAGES/django.po
index b9eb5368f3ff32979b37eba5ae3e365962ee0194..25980a446d3fd10bc881331c0e2544c04d33780a 100644
--- a/AKModel/locale/de_DE/LC_MESSAGES/django.po
+++ b/AKModel/locale/de_DE/LC_MESSAGES/django.po
@@ -2,7 +2,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2022-09-27 23:49+0200\n"
+"POT-Creation-Date: 2022-09-28 01:20+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -11,7 +11,7 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: .\AKModel\admin.py:56 .\AKModel\admin.py:58
+#: .\AKModel\admin.py:58 .\AKModel\admin.py:60
 #: .\AKModel\templates\admin\AKModel\event_wizard\activate.html:32
 #: .\AKModel\templates\admin\AKModel\event_wizard\created_prepare_import.html:48
 #: .\AKModel\templates\admin\AKModel\event_wizard\finish.html:21
@@ -21,26 +21,38 @@ msgstr ""
 msgid "Status"
 msgstr "Status"
 
-#: .\AKModel\admin.py:132
+#: .\AKModel\admin.py:134
 msgid "Wish"
 msgstr "AK-Wunsch"
 
-#: .\AKModel\admin.py:138
+#: .\AKModel\admin.py:140
 msgid "Is wish"
 msgstr "Ist ein Wunsch"
 
-#: .\AKModel\admin.py:139
+#: .\AKModel\admin.py:141
 msgid "Is not a wish"
 msgstr "Ist kein Wunsch"
 
-#: .\AKModel\admin.py:185
+#: .\AKModel\admin.py:187
 msgid "Export to wiki syntax"
 msgstr "In Wiki-Syntax exportieren"
 
-#: .\AKModel\admin.py:279
+#: .\AKModel\admin.py:281
 msgid "AK Details"
 msgstr "AK-Details"
 
+#: .\AKModel\admin.py:336 .\AKModel\views.py:412
+msgid "Mark Constraint Violations as manually resolved"
+msgstr "Markiere Constraintverletzungen manuell als behoben"
+
+#: .\AKModel\admin.py:341
+msgid "Set to Constraint Violations to level \"violation\""
+msgstr "Constraintverletzungen auf Level \"Violation\" setzen"
+
+#: .\AKModel\admin.py:346 .\AKModel\views.py:432
+msgid "Set Constraint Violations to level \"warning\""
+msgstr "Constraintverletzungen auf Level \"Warning\" setzen"
+
 #: .\AKModel\availability\forms.py:21 .\AKModel\availability\models.py:248
 msgid "Availability"
 msgstr "Verfügbarkeit"
@@ -135,35 +147,35 @@ msgstr "AK-Kategorien kopieren"
 msgid "Copy ak requirements"
 msgstr "AK-Anforderungen kopieren"
 
-#: .\AKModel\forms.py:82
+#: .\AKModel\forms.py:86
 msgid "# next AKs"
 msgstr "# nächste AKs"
 
-#: .\AKModel\forms.py:83
+#: .\AKModel\forms.py:87
 msgid "How many next AKs should be shown on a slide?"
 msgstr "Wie viele nächste AKs sollen auf einer Folie angezeigt werden?"
 
-#: .\AKModel\forms.py:86
+#: .\AKModel\forms.py:90
 msgid "Presentation only?"
 msgstr "Nur Vorstellung?"
 
-#: .\AKModel\forms.py:88 .\AKModel\forms.py:95
+#: .\AKModel\forms.py:92 .\AKModel\forms.py:99
 msgid "Yes"
 msgstr "Ja"
 
-#: .\AKModel\forms.py:88 .\AKModel\forms.py:95
+#: .\AKModel\forms.py:92 .\AKModel\forms.py:99
 msgid "No"
 msgstr "Nein"
 
-#: .\AKModel\forms.py:90
+#: .\AKModel\forms.py:94
 msgid "Restrict AKs to those that asked for chance to be presented?"
 msgstr "AKs auf solche, die um eine Vorstellung gebeten haben, einschränken?"
 
-#: .\AKModel\forms.py:93
+#: .\AKModel\forms.py:97
 msgid "Space for notes in wishes?"
 msgstr "Platz für Notizen bei den Wünschen?"
 
-#: .\AKModel\forms.py:97
+#: .\AKModel\forms.py:101
 msgid ""
 "Create symbols indicating space to note down owners and timeslots for "
 "wishes, e.g., to be filled out on a touch screen while presenting?"
@@ -208,7 +220,7 @@ msgstr "Zeitzone"
 msgid "Time Zone where this event takes place in"
 msgstr "Zeitzone in der das Event stattfindet"
 
-#: .\AKModel\models.py:27 .\AKModel\views.py:239
+#: .\AKModel\models.py:27 .\AKModel\views.py:241
 msgid "Start"
 msgstr "Start"
 
@@ -557,7 +569,7 @@ msgstr "Anzahl Personen, die online Interesse bekundet haben"
 
 #: .\AKModel\models.py:291 .\AKModel\models.py:498
 #: .\AKModel\templates\admin\AKModel\status.html:49
-#: .\AKModel\templates\admin\AKModel\status.html:56 .\AKModel\views.py:357
+#: .\AKModel\templates\admin\AKModel\status.html:56 .\AKModel\views.py:359
 msgid "AKs"
 msgstr "AKs"
 
@@ -842,7 +854,7 @@ msgid "Successfully imported.<br><br>Do you want to activate your event now?"
 msgstr "Erfolgreich importiert.<br><br>Soll das Event jetzt aktiviert werden?"
 
 #: .\AKModel\templates\admin\AKModel\event_wizard\activate.html:27
-#: .\AKModel\views.py:244
+#: .\AKModel\views.py:246
 msgid "Finish"
 msgstr "Abschluss"
 
@@ -968,7 +980,7 @@ msgstr "AKs als CSV exportieren"
 msgid "Export AKs for Wiki"
 msgstr "AKs im Wiki-Format exportieren"
 
-#: .\AKModel\templates\admin\AKModel\status.html:92 .\AKModel\views.py:327
+#: .\AKModel\templates\admin\AKModel\status.html:92 .\AKModel\views.py:329
 msgid "Export AK Slides"
 msgstr "AK-Folien exportieren"
 
@@ -1021,82 +1033,114 @@ msgstr "Login"
 msgid "Register"
 msgstr "Registrieren"
 
-#: .\AKModel\views.py:145
+#: .\AKModel\views.py:147
 msgid "Event Status"
 msgstr "Eventstatus"
 
-#: .\AKModel\views.py:158
+#: .\AKModel\views.py:160
 msgid "Requirements for Event"
 msgstr "Anforderungen für das Event"
 
-#: .\AKModel\views.py:172
+#: .\AKModel\views.py:174
 msgid "AK CSV Export"
 msgstr "AK-CSV-Export"
 
-#: .\AKModel\views.py:186
+#: .\AKModel\views.py:188
 msgid "AK Wiki Export"
 msgstr "AK-Wiki-Export"
 
-#: .\AKModel\views.py:194 .\AKModel\views.py:343
+#: .\AKModel\views.py:196 .\AKModel\views.py:345
 msgid "Wishes"
 msgstr "Wünsche"
 
-#: .\AKModel\views.py:215
+#: .\AKModel\views.py:217
 msgid "Delete AK Orga Messages"
 msgstr "AK-Organachrichten löschen"
 
-#: .\AKModel\views.py:230
+#: .\AKModel\views.py:232
 msgid "AK Orga Messages successfully deleted"
 msgstr "AK-Organachrichten erfolgreich gelöscht"
 
-#: .\AKModel\views.py:240
+#: .\AKModel\views.py:242
 msgid "Settings"
 msgstr "Einstellungen"
 
-#: .\AKModel\views.py:241
+#: .\AKModel\views.py:243
 msgid "Event created, Prepare Import"
 msgstr "Event angelegt, Import vorbereiten"
 
-#: .\AKModel\views.py:242
+#: .\AKModel\views.py:244
 msgid "Import categories & requirements"
 msgstr "Kategorien & Anforderungen kopieren"
 
-#: .\AKModel\views.py:243
+#: .\AKModel\views.py:245
 #, fuzzy
 #| msgid "Active State"
 msgid "Activate?"
 msgstr "Aktivieren?"
 
-#: .\AKModel\views.py:302
+#: .\AKModel\views.py:304
 #, python-format
 msgid "Copied '%(obj)s'"
 msgstr "'%(obj)s' kopiert"
 
-#: .\AKModel\views.py:305
+#: .\AKModel\views.py:307
 #, python-format
 msgid "Could not copy '%(obj)s' (%(error)s)"
 msgstr "'%(obj)s' konnte nicht kopiert werden (%(error)s)"
 
-#: .\AKModel\views.py:338
+#: .\AKModel\views.py:340
 msgid "Symbols"
 msgstr "Symbole"
 
-#: .\AKModel\views.py:339
+#: .\AKModel\views.py:341
 msgid "Who?"
 msgstr "Wer?"
 
-#: .\AKModel\views.py:340
+#: .\AKModel\views.py:342
 msgid "Duration(s)"
 msgstr "Dauer(n)"
 
-#: .\AKModel\views.py:341
+#: .\AKModel\views.py:343
 msgid "Reso intention?"
 msgstr "Resolutionsabsicht?"
 
-#: .\AKModel\views.py:342
+#: .\AKModel\views.py:344
 msgid "Category (for Wishes)"
 msgstr "Kategorie (für Wünsche)"
 
+#: .\AKModel\views.py:414
+msgid "The following Constraint Violations will be marked as manually resolved"
+msgstr ""
+"Die folgenden Constraintverletzungen werden als manuell behoben markiert"
+
+#: .\AKModel\views.py:415
+msgid "Constraint Violations marked as resolved"
+msgstr "Constraintverletzungen als behoben markiert"
+
+#: .\AKModel\views.py:422
+msgid "Set Constraint Violations to level \"violation\""
+msgstr "Constraintverletzungen auf Level \"violation\" setzen"
+
+#: .\AKModel\views.py:424
+msgid "The following Constraint Violations will be set to level 'violation'"
+msgstr ""
+"Die folgenden Constraintverletzungen werden auf das Level \"Violation\" "
+"gesetzt"
+
+#: .\AKModel\views.py:425
+msgid "Constraint Violations set to level 'violation'"
+msgstr "Constraintverletzungen auf Level \"Violation\" gesetzt"
+
+#: .\AKModel\views.py:434
+msgid "The following Constraint Violations will be set to level 'warning'"
+msgstr ""
+"Die folgenden Constraintverletzungen werden auf das Level \"Warning\" gesetzt"
+
+#: .\AKModel\views.py:435
+msgid "Constraint Violations set to level 'warning'"
+msgstr "Constraintverletzungen auf Level \"Warning\" gesetzt"
+
 #, fuzzy
 #~| msgid "Export AK Slides"
 #~ msgid "Export Slides"
diff --git a/AKModel/views.py b/AKModel/views.py
index 530a26c5f9d0a9ab9ba6245a135e6fc995c0e74a..b6311f3fe84afeed90aef0dd6ec4124aadca85ec 100644
--- a/AKModel/views.py
+++ b/AKModel/views.py
@@ -1,10 +1,11 @@
 import os
 import tempfile
+from abc import ABC, abstractmethod
 from itertools import zip_longest
 
 from django.contrib import admin, messages
 from django.shortcuts import get_object_or_404, redirect
-from django.urls import reverse_lazy
+from django.urls import reverse_lazy, reverse
 from django.utils.translation import gettext_lazy as _
 from django.views.generic import TemplateView, DetailView, ListView, DeleteView, CreateView, FormView, UpdateView
 from django_tex.core import render_template_with_context, run_tex_in_directory
@@ -12,8 +13,10 @@ from django_tex.response import PDFResponse
 from rest_framework import viewsets, permissions, mixins
 
 from AKModel.forms import NewEventWizardStartForm, NewEventWizardSettingsForm, NewEventWizardPrepareImportForm, \
-    NewEventWizardImportForm, NewEventWizardActivateForm, AdminIntermediateForm, SlideExportForm
-from AKModel.models import Event, AK, AKSlot, Room, AKTrack, AKCategory, AKOwner, AKOrgaMessage, AKRequirement
+    NewEventWizardImportForm, NewEventWizardActivateForm, AdminIntermediateForm, SlideExportForm, \
+    AdminIntermediateActionForm
+from AKModel.models import Event, AK, AKSlot, Room, AKTrack, AKCategory, AKOwner, AKOrgaMessage, AKRequirement, \
+    ConstraintViolation
 from AKModel.serializers import AKSerializer, AKSlotSerializer, RoomSerializer, AKTrackSerializer, AKCategorySerializer, \
     AKOwnerSerializer
 
@@ -369,3 +372,67 @@ class ExportSlidesView(EventSlugMixin, IntermediateAdminView):
             pdf = run_tex_in_directory(source, tempdir, template_name=self.template_name)
 
         return PDFResponse(pdf, filename='slides.pdf')
+
+
+class IntermediateAdminActionView(IntermediateAdminView, ABC):
+    form_class = AdminIntermediateActionForm
+
+    def get_queryset(self, pks=None):
+        if pks is None:
+            pks = self.request.GET['pks']
+        return self.model.objects.filter(pk__in=pks.split(","))
+
+    def get_initial(self):
+        initial = super().get_initial()
+        initial['pks'] = self.request.GET['pks']
+        return initial
+
+    def get_preview(self):
+        entities = self.get_queryset()
+        joined_entities = '\n'.join(str(e) for e in entities)
+        return f"{self.confirmation_message}:\n\n {joined_entities}"
+
+    def get_success_url(self):
+        return reverse(f"admin:{self.model._meta.app_label}_{self.model._meta.model_name}_changelist")
+
+    @abstractmethod
+    def perform_action(self, entity):
+        pass
+
+    def form_valid(self, form):
+        entities = self.get_queryset(pks=form.cleaned_data['pks'])
+        for entity in entities:
+            self.perform_action(entity)
+            entity.save()
+        messages.add_message(self.request, messages.SUCCESS, self.success_message)
+        return super().form_valid(form)
+
+
+class CVMarkResolvedView(IntermediateAdminActionView):
+    title = _('Mark Constraint Violations as manually resolved')
+    model = ConstraintViolation
+    confirmation_message = _("The following Constraint Violations will be marked as manually resolved")
+    success_message = _("Constraint Violations marked as resolved")
+
+    def perform_action(self, entity):
+        entity.manually_resolved = True
+
+
+class CVSetLevelViolationView(IntermediateAdminActionView):
+    title = _('Set Constraint Violations to level "violation"')
+    model = ConstraintViolation
+    confirmation_message = _("The following Constraint Violations will be set to level 'violation'")
+    success_message = _("Constraint Violations set to level 'violation'")
+
+    def perform_action(self, entity):
+        entity.level = ConstraintViolation.ViolationLevel.VIOLATION
+
+
+class CVSetLevelWarningView(IntermediateAdminActionView):
+    title = _('Set Constraint Violations to level "warning"')
+    model = ConstraintViolation
+    confirmation_message = _("The following Constraint Violations will be set to level 'warning'")
+    success_message = _("Constraint Violations set to level 'warning'")
+
+    def perform_action(self, entity):
+        entity.level = ConstraintViolation.ViolationLevel.WARNING