diff --git a/AKModel/admin.py b/AKModel/admin.py
index 3d37232595a7efacfa17ebab69466103214c44d5..962293cb93594d1a0b1bd9bf57da039bacdb693f 100644
--- a/AKModel/admin.py
+++ b/AKModel/admin.py
@@ -19,7 +19,7 @@ from AKModel.models import Event, AKOwner, AKCategory, AKTrack, AKTag, AKRequire
     ConstraintViolation, DefaultSlot
 from AKModel.urls import get_admin_urls_event_wizard, get_admin_urls_event
 from AKModel.views import CVMarkResolvedView, CVSetLevelViolationView, CVSetLevelWarningView, AKResetInterestView, \
-    AKResetInterestCounterView, PlanPublishView, PlanUnpublishView, DefaultSlotEditorView
+    AKResetInterestCounterView, PlanPublishView, PlanUnpublishView, DefaultSlotEditorView, RoomBatchCreationView
 
 
 class EventRelatedFieldListFilter(RelatedFieldListFilter):
@@ -56,6 +56,7 @@ class EventAdmin(admin.ModelAdmin):
             path('plan/publish/', PlanPublishView.as_view(), name="plan-publish"),
             path('plan/unpublish/', PlanUnpublishView.as_view(), name="plan-unpublish"),
             path('<slug:event_slug>/defaultSlots/', DefaultSlotEditorView.as_view(), name="default-slots-editor"),
+            path('<slug:event_slug>/importRooms/', RoomBatchCreationView.as_view(), name="room-import"),
         ])
         urls.extend(super().get_urls())
         return urls
diff --git a/AKModel/forms.py b/AKModel/forms.py
index 0f09a63b1d0bbd312201863743a6c080972a9b91..c1386538de6845cae78e7b7fdfbb3934cdab883c 100644
--- a/AKModel/forms.py
+++ b/AKModel/forms.py
@@ -1,3 +1,6 @@
+import csv
+import io
+
 from bootstrap_datepicker_plus import DateTimePickerInput
 from django import forms
 from django.forms.utils import ErrorList
@@ -61,8 +64,10 @@ class NewEventWizardImportForm(forms.Form):
                  renderer=None):
         super().__init__(data, files, auto_id, prefix, initial, error_class, label_suffix, empty_permitted, field_order,
                          use_required_attribute, renderer)
-        self.fields["import_categories"].queryset = self.fields["import_categories"].queryset.filter(event=self.initial["import_event"])
-        self.fields["import_requirements"].queryset = self.fields["import_requirements"].queryset.filter(event=self.initial["import_event"])
+        self.fields["import_categories"].queryset = self.fields["import_categories"].queryset.filter(
+            event=self.initial["import_event"])
+        self.fields["import_requirements"].queryset = self.fields["import_requirements"].queryset.filter(
+            event=self.initial["import_event"])
 
 
 class NewEventWizardActivateForm(forms.ModelForm):
@@ -112,3 +117,22 @@ class DefaultSlotEditorForm(AdminIntermediateForm):
         widget=forms.TextInput(attrs={'class': 'availabilities-editor-data'}),
         required=True,
     )
+
+
+class RoomBatchCreationForm(AdminIntermediateForm):
+    rooms = forms.CharField(
+        label=_('New rooms'),
+        help_text=_('Enter room details in CSV format. Required colum is "name", optional colums are "location", '
+                    '"capacity", and "url" for online/hybrid rooms. Delimiter: Semicolon'),
+        widget=forms.Textarea,
+        required=True,
+    )
+
+    def clean_rooms(self):
+        rooms_raw_text = self.cleaned_data["rooms"]
+        rooms_raw_dict = csv.DictReader(io.StringIO(rooms_raw_text), delimiter=";")
+
+        if "name" not in rooms_raw_dict.fieldnames:
+            raise forms.ValidationError(_("CSV must contain a name column"))
+
+        return rooms_raw_dict
diff --git a/AKModel/locale/de_DE/LC_MESSAGES/django.po b/AKModel/locale/de_DE/LC_MESSAGES/django.po
index 5a302db39b93066d738d3fb84561945f57ddaf87..ba25e4c43f909e01b61eed2ebd9899692b8f395a 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-11-29 00:13+0100\n"
+"POT-Creation-Date: 2022-11-30 01:57+0100\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:63 AKModel/admin.py:66
+#: AKModel/admin.py:64 AKModel/admin.py:67
 #: 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,59 +21,59 @@ msgstr ""
 msgid "Status"
 msgstr "Status"
 
-#: AKModel/admin.py:68
+#: AKModel/admin.py:69
 msgid "Toggle plan visibility"
 msgstr "Plansichtbarkeit ändern"
 
-#: AKModel/admin.py:72 AKModel/admin.py:83 AKModel/views.py:483
+#: AKModel/admin.py:73 AKModel/admin.py:84 AKModel/views.py:485
 msgid "Publish plan"
 msgstr "Plan veröffentlichen"
 
-#: AKModel/admin.py:75 AKModel/admin.py:88 AKModel/views.py:493
+#: AKModel/admin.py:76 AKModel/admin.py:89 AKModel/views.py:495
 msgid "Unpublish plan"
 msgstr "Plan verbergen"
 
-#: AKModel/admin.py:160
+#: AKModel/admin.py:161
 msgid "Wish"
 msgstr "AK-Wunsch"
 
-#: AKModel/admin.py:166
+#: AKModel/admin.py:167
 msgid "Is wish"
 msgstr "Ist ein Wunsch"
 
-#: AKModel/admin.py:167
+#: AKModel/admin.py:168
 msgid "Is not a wish"
 msgstr "Ist kein Wunsch"
 
-#: AKModel/admin.py:211
+#: AKModel/admin.py:212
 msgid "Export to wiki syntax"
 msgstr "In Wiki-Syntax exportieren"
 
-#: AKModel/admin.py:220
+#: AKModel/admin.py:221
 msgid "Cannot export AKs from more than one event at the same time."
 msgstr "Kann nicht AKs von mehreren Events zur selben Zeit exportieren."
 
-#: AKModel/admin.py:235 AKModel/views.py:463
+#: AKModel/admin.py:236 AKModel/views.py:465
 msgid "Reset interest in AKs"
 msgstr "Interesse an AKs zurücksetzen"
 
-#: AKModel/admin.py:240 AKModel/views.py:473
+#: AKModel/admin.py:241 AKModel/views.py:475
 msgid "Reset AKs' interest counters"
 msgstr "Interessenszähler der AKs zurücksetzen"
 
-#: AKModel/admin.py:324 AKModel/admin.py:331
+#: AKModel/admin.py:325 AKModel/admin.py:332
 msgid "AK Details"
 msgstr "AK-Details"
 
-#: AKModel/admin.py:383 AKModel/views.py:433
+#: AKModel/admin.py:384 AKModel/views.py:435
 msgid "Mark Constraint Violations as manually resolved"
 msgstr "Markiere Constraintverletzungen als manuell behoben"
 
-#: AKModel/admin.py:388 AKModel/views.py:443
+#: AKModel/admin.py:389 AKModel/views.py:445
 msgid "Set Constraint Violations to level \"violation\""
 msgstr "Constraintverletzungen auf Level \"Violation\" setzen"
 
-#: AKModel/admin.py:393 AKModel/views.py:453
+#: AKModel/admin.py:394 AKModel/views.py:455
 msgid "Set Constraint Violations to level \"warning\""
 msgstr "Constraintverletzungen auf Level \"Warning\" setzen"
 
@@ -81,7 +81,7 @@ msgstr "Constraintverletzungen auf Level \"Warning\" setzen"
 msgid "Availability"
 msgstr "Verfügbarkeit"
 
-#: AKModel/availability/forms.py:23 AKModel/forms.py:110
+#: AKModel/availability/forms.py:23 AKModel/forms.py:115
 msgid ""
 "Click and drag to mark the availability during the event, double-click to "
 "delete."
@@ -154,52 +154,52 @@ msgstr "AK-Kategorie, deren Verfügbarkeit hier abgebildet wird"
 msgid "Availabilities"
 msgstr "Verfügbarkeiten"
 
-#: AKModel/forms.py:39
+#: AKModel/forms.py:42
 msgid "Copy ak requirements and ak categories of existing event"
 msgstr "AK-Anforderungen und AK-Kategorien eines existierenden Events kopieren"
 
-#: AKModel/forms.py:40
+#: AKModel/forms.py:43
 msgid "You can choose what to copy in the next step"
 msgstr ""
 "Im nächsten Schritt kann ausgewählt werden, was genau kopiert werden soll"
 
-#: AKModel/forms.py:48
+#: AKModel/forms.py:51
 msgid "Copy ak categories"
 msgstr "AK-Kategorien kopieren"
 
-#: AKModel/forms.py:55
+#: AKModel/forms.py:58
 msgid "Copy ak requirements"
 msgstr "AK-Anforderungen kopieren"
 
-#: AKModel/forms.py:87
+#: AKModel/forms.py:92
 msgid "# next AKs"
 msgstr "# nächste AKs"
 
-#: AKModel/forms.py:88
+#: AKModel/forms.py:93
 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:91
+#: AKModel/forms.py:96
 msgid "Presentation only?"
 msgstr "Nur Vorstellung?"
 
-#: AKModel/forms.py:93 AKModel/forms.py:100
+#: AKModel/forms.py:98 AKModel/forms.py:105
 msgid "Yes"
 msgstr "Ja"
 
-#: AKModel/forms.py:93 AKModel/forms.py:100
+#: AKModel/forms.py:98 AKModel/forms.py:105
 msgid "No"
 msgstr "Nein"
 
-#: AKModel/forms.py:95
+#: AKModel/forms.py:100
 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:98
+#: AKModel/forms.py:103
 msgid "Space for notes in wishes?"
 msgstr "Platz für Notizen bei den Wünschen?"
 
-#: AKModel/forms.py:102
+#: AKModel/forms.py:107
 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,10 +208,28 @@ msgstr ""
 "fürWünsche markieren, z.B. um während der Präsentation auf einem Touchscreen "
 "ausgefüllt zu werden?"
 
-#: AKModel/forms.py:108 AKModel/models.py:658
+#: AKModel/forms.py:113 AKModel/models.py:658
 msgid "Default Slots"
 msgstr "Standardslots"
 
+#: AKModel/forms.py:124
+msgid "New rooms"
+msgstr "Neue Räume"
+
+#: AKModel/forms.py:125
+msgid ""
+"Enter room details in CSV format. Required colum is \"name\", optional "
+"colums are \"location\", \"capacity\", and \"url\" for online/hybrid rooms. "
+"Delimiter: Semicolon"
+msgstr ""
+"Raumdetails im CSV-Format eingeben. Benötigte Spalte ist \"name\", optionale "
+"Spalten sind \"location\", \"capacity\", und \"url\" for Online-/Hybridräume"
+"Trennzeichen: Semikolon"
+
+#: AKModel/forms.py:136
+msgid "CSV must contain a name column"
+msgstr "CSV muss eine name-Spalte enthalten"
+
 #: AKModel/models.py:18 AKModel/models.py:175 AKModel/models.py:199
 #: AKModel/models.py:218 AKModel/models.py:232 AKModel/models.py:250
 #: AKModel/models.py:346
@@ -248,7 +266,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:244
+#: AKModel/models.py:27 AKModel/views.py:246
 msgid "Start"
 msgstr "Start"
 
@@ -544,7 +562,7 @@ msgstr "AK präsentieren"
 msgid "Present results of this AK"
 msgstr "Die Ergebnisse dieses AKs vorstellen"
 
-#: AKModel/models.py:273 AKModel/templates/admin/AKModel/status.html:104
+#: AKModel/models.py:273 AKModel/templates/admin/AKModel/status.html:105
 msgid "Requirements"
 msgstr "Anforderungen"
 
@@ -600,8 +618,8 @@ msgid "People who have indicated interest online"
 msgstr "Anzahl Personen, die online Interesse bekundet haben"
 
 #: AKModel/models.py:295 AKModel/models.py:502
-#: AKModel/templates/admin/AKModel/status.html:56
-#: AKModel/templates/admin/AKModel/status.html:63 AKModel/views.py:362
+#: AKModel/templates/admin/AKModel/status.html:57
+#: AKModel/templates/admin/AKModel/status.html:64 AKModel/views.py:364
 msgid "AKs"
 msgstr "AKs"
 
@@ -710,7 +728,7 @@ msgstr "AK-Organachrichten"
 msgid "Constraint Violation"
 msgstr "Constraintverletzung"
 
-#: AKModel/models.py:473 AKModel/templates/admin/AKModel/status.html:86
+#: AKModel/models.py:473 AKModel/templates/admin/AKModel/status.html:87
 msgid "Constraint Violations"
 msgstr "Constraintverletzungen"
 
@@ -906,7 +924,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:249
+#: AKModel/views.py:251
 msgid "Finish"
 msgstr "Abschluss"
 
@@ -971,7 +989,7 @@ msgid "No AKs with this requirement"
 msgstr "Kein AK mit dieser Anforderung"
 
 #: AKModel/templates/admin/AKModel/requirements_overview.html:45
-#: AKModel/templates/admin/AKModel/status.html:120
+#: AKModel/templates/admin/AKModel/status.html:121
 msgid "Add Requirement"
 msgstr "Anforderung hinzufügen"
 
@@ -999,64 +1017,68 @@ msgstr "Bisher keine Räume"
 msgid "Add Room"
 msgstr "Raum hinzufügen"
 
-#: AKModel/templates/admin/AKModel/status.html:58
+#: AKModel/templates/admin/AKModel/status.html:55 AKModel/views.py:582
+msgid "Import Rooms from CSV"
+msgstr "Räume aus CSV importieren"
+
+#: AKModel/templates/admin/AKModel/status.html:59
 msgid "No AKs yet"
 msgstr "Bisher keine AKs"
 
-#: AKModel/templates/admin/AKModel/status.html:66
+#: AKModel/templates/admin/AKModel/status.html:67
 msgid "Slots"
 msgstr "Slots"
 
-#: AKModel/templates/admin/AKModel/status.html:69
+#: AKModel/templates/admin/AKModel/status.html:70
 msgid "Unscheduled Slots"
 msgstr "Ungeplante Slots"
 
-#: AKModel/templates/admin/AKModel/status.html:83
+#: AKModel/templates/admin/AKModel/status.html:84
 #: AKModel/templates/admin/ak_index.html:16
 msgid "Scheduling"
 msgstr "Scheduling"
 
-#: AKModel/templates/admin/AKModel/status.html:88
+#: AKModel/templates/admin/AKModel/status.html:89
 msgid "AKs requiring special attention"
 msgstr "AKs, die besondere Aufmerksamkeit benötigen"
 
-#: AKModel/templates/admin/AKModel/status.html:90
+#: AKModel/templates/admin/AKModel/status.html:91
 msgid "Enter Interest"
 msgstr "Interesse erfassen"
 
-#: AKModel/templates/admin/AKModel/status.html:93 AKModel/views.py:505
+#: AKModel/templates/admin/AKModel/status.html:94 AKModel/views.py:507
 msgid "Edit Default Slots"
 msgstr "Standardslots bearbeiten"
 
-#: AKModel/templates/admin/AKModel/status.html:95
+#: AKModel/templates/admin/AKModel/status.html:96
 msgid "Manage ak tracks"
 msgstr "AK-Tracks verwalten"
 
-#: AKModel/templates/admin/AKModel/status.html:97
+#: AKModel/templates/admin/AKModel/status.html:98
 msgid "Export AKs as CSV"
 msgstr "AKs als CSV exportieren"
 
-#: AKModel/templates/admin/AKModel/status.html:99
+#: AKModel/templates/admin/AKModel/status.html:100
 msgid "Export AKs for Wiki"
 msgstr "AKs im Wiki-Format exportieren"
 
-#: AKModel/templates/admin/AKModel/status.html:101 AKModel/views.py:332
+#: AKModel/templates/admin/AKModel/status.html:102 AKModel/views.py:334
 msgid "Export AK Slides"
 msgstr "AK-Folien exportieren"
 
-#: AKModel/templates/admin/AKModel/status.html:106
+#: AKModel/templates/admin/AKModel/status.html:107
 msgid "No requirements yet"
 msgstr "Bisher keine Anforderungen"
 
-#: AKModel/templates/admin/AKModel/status.html:119
+#: AKModel/templates/admin/AKModel/status.html:120
 msgid "Show AKs for requirements"
 msgstr "Zu Anforderungen gehörige AKs anzeigen"
 
-#: AKModel/templates/admin/AKModel/status.html:123
+#: AKModel/templates/admin/AKModel/status.html:124
 msgid "Messages"
 msgstr "Nachrichten"
 
-#: AKModel/templates/admin/AKModel/status.html:125
+#: AKModel/templates/admin/AKModel/status.html:126
 msgid "Delete all messages"
 msgstr "Alle Nachrichten löschen"
 
@@ -1093,148 +1115,162 @@ msgstr "Login"
 msgid "Register"
 msgstr "Registrieren"
 
-#: AKModel/views.py:150
+#: AKModel/views.py:152
 msgid "Event Status"
 msgstr "Eventstatus"
 
-#: AKModel/views.py:163
+#: AKModel/views.py:165
 msgid "Requirements for Event"
 msgstr "Anforderungen für das Event"
 
-#: AKModel/views.py:177
+#: AKModel/views.py:179
 msgid "AK CSV Export"
 msgstr "AK-CSV-Export"
 
-#: AKModel/views.py:191
+#: AKModel/views.py:193
 msgid "AK Wiki Export"
 msgstr "AK-Wiki-Export"
 
-#: AKModel/views.py:199 AKModel/views.py:348
+#: AKModel/views.py:201 AKModel/views.py:350
 msgid "Wishes"
 msgstr "Wünsche"
 
-#: AKModel/views.py:220
+#: AKModel/views.py:222
 msgid "Delete AK Orga Messages"
 msgstr "AK-Organachrichten löschen"
 
-#: AKModel/views.py:235
+#: AKModel/views.py:237
 msgid "AK Orga Messages successfully deleted"
 msgstr "AK-Organachrichten erfolgreich gelöscht"
 
-#: AKModel/views.py:245
+#: AKModel/views.py:247
 msgid "Settings"
 msgstr "Einstellungen"
 
-#: AKModel/views.py:246
+#: AKModel/views.py:248
 msgid "Event created, Prepare Import"
 msgstr "Event angelegt, Import vorbereiten"
 
-#: AKModel/views.py:247
+#: AKModel/views.py:249
 msgid "Import categories & requirements"
 msgstr "Kategorien & Anforderungen kopieren"
 
-#: AKModel/views.py:248
+#: AKModel/views.py:250
 msgid "Activate?"
 msgstr "Aktivieren?"
 
-#: AKModel/views.py:307
+#: AKModel/views.py:309
 #, python-format
 msgid "Copied '%(obj)s'"
 msgstr "'%(obj)s' kopiert"
 
-#: AKModel/views.py:310
+#: AKModel/views.py:312
 #, python-format
 msgid "Could not copy '%(obj)s' (%(error)s)"
 msgstr "'%(obj)s' konnte nicht kopiert werden (%(error)s)"
 
-#: AKModel/views.py:343
+#: AKModel/views.py:345
 msgid "Symbols"
 msgstr "Symbole"
 
-#: AKModel/views.py:344
+#: AKModel/views.py:346
 msgid "Who?"
 msgstr "Wer?"
 
-#: AKModel/views.py:345
+#: AKModel/views.py:347
 msgid "Duration(s)"
 msgstr "Dauer(n)"
 
-#: AKModel/views.py:346
+#: AKModel/views.py:348
 msgid "Reso intention?"
 msgstr "Resolutionsabsicht?"
 
-#: AKModel/views.py:347
+#: AKModel/views.py:349
 msgid "Category (for Wishes)"
 msgstr "Kategorie (für Wünsche)"
 
-#: AKModel/views.py:435
+#: AKModel/views.py:437
 msgid "The following Constraint Violations will be marked as manually resolved"
 msgstr ""
 "Die folgenden Constraintverletzungen werden als manuell behoben markiert."
 
-#: AKModel/views.py:436
+#: AKModel/views.py:438
 msgid "Constraint Violations marked as resolved"
 msgstr "Constraintverletzungen als manuell behoben markiert"
 
-#: AKModel/views.py:445
+#: AKModel/views.py:447
 msgid "The following Constraint Violations will be set to level 'violation'"
 msgstr ""
 "Die folgenden Constraintverletzungen werden auf das Level \"Violation\" "
 "gesetzt."
 
-#: AKModel/views.py:446
+#: AKModel/views.py:448
 msgid "Constraint Violations set to level 'violation'"
 msgstr "Constraintverletzungen auf Level \"Violation\" gesetzt"
 
-#: AKModel/views.py:455
+#: AKModel/views.py:457
 msgid "The following Constraint Violations will be set to level 'warning'"
 msgstr ""
 "Die folgenden Constraintverletzungen werden auf das Level 'warning' gesetzt."
 
-#: AKModel/views.py:456
+#: AKModel/views.py:458
 msgid "Constraint Violations set to level 'warning'"
 msgstr "Constraintverletzungen auf Level \"Warning\" gesetzt"
 
-#: AKModel/views.py:465
+#: AKModel/views.py:467
 msgid "Interest of the following AKs will be set to not filled (-1):"
 msgstr "Interesse an den folgenden AKs wird auf nicht ausgefüllt (-1) gesetzt:"
 
-#: AKModel/views.py:466
+#: AKModel/views.py:468
 msgid "Reset of interest in AKs successful."
 msgstr "Interesse an AKs erfolgreich zurückgesetzt."
 
-#: AKModel/views.py:475
+#: AKModel/views.py:477
 msgid "Interest counter of the following AKs will be set to 0:"
 msgstr "Interessensbekundungszähler der folgenden AKs wird auf 0 gesetzt:"
 
-#: AKModel/views.py:476
+#: AKModel/views.py:478
 msgid "AKs' interest counters set back to 0."
 msgstr "Interessenszähler der AKs zurückgesetzt"
 
-#: AKModel/views.py:485
+#: AKModel/views.py:487
 msgid "Publish the plan(s) of:"
 msgstr "Den Plan/die Pläne veröffentlichen von:"
 
-#: AKModel/views.py:486
+#: AKModel/views.py:488
 msgid "Plan published"
 msgstr "Plan veröffentlicht"
 
-#: AKModel/views.py:495
+#: AKModel/views.py:497
 msgid "Unpublish the plan(s) of:"
 msgstr "Den Plan/die Pläne verbergen von:"
 
-#: AKModel/views.py:496
+#: AKModel/views.py:498
 msgid "Plan unpublished"
 msgstr "Plan verborgen"
 
-#: AKModel/views.py:542
+#: AKModel/views.py:544
 #, python-brace-format
 msgid "Could not update slot {id} since it does not belong to {event}"
 msgstr ""
 "Konnte  Slot {id} nicht bearbeiten, da er nicht zum Event {event} gehört"
 
-#: AKModel/views.py:572
+#: AKModel/views.py:574
 #, python-brace-format
 msgid "Updated {u} slot(s). created {c} new slot(s) and deleted {d} slot(s)"
 msgstr ""
 "{u} Slot(s) aktualisiert, {c} Slot(s) hinzugefügt und {d} Slot(s) gelöscht"
+
+#: AKModel/views.py:611
+#, python-brace-format
+msgid "Could not import room {name}: {e}"
+msgstr "Konnte Raum {name} nicht importieren: {e}"
+
+#: AKModel/views.py:615
+#, python-brace-format
+msgid "Imported {count} room(s)"
+msgstr "{count} Raum/Räume importiert"
+
+#: AKModel/views.py:617
+msgid "No rooms imported"
+msgstr "Keine Räume importiert"
diff --git a/AKModel/templates/admin/AKModel/status.html b/AKModel/templates/admin/AKModel/status.html
index 8530e444719bbb2be948dc55f7376ed0f23bee01..d315c396e51cdd49004117978de766edc21b5dcc 100644
--- a/AKModel/templates/admin/AKModel/status.html
+++ b/AKModel/templates/admin/AKModel/status.html
@@ -52,6 +52,7 @@
                     </p>
                 {% endif %}
                 <a class="btn btn-success" href="{% url 'admin:AKModel_room_add' %}">{% trans "Add Room" %}</a>
+                <a class="btn btn-success" href="{% url 'admin:room-import' event_slug=event.slug %}">{% trans "Import Rooms from CSV" %}</a>
 
                 <h3 class="block-header">{% trans "AKs" %}</h3>
                 {% if event.ak_set.count == 0 %}
diff --git a/AKModel/views.py b/AKModel/views.py
index 76ead0da0e45f5a2b57089558ba13b6a15f6411c..dde2d17fd8b3165b703370fd9e57ee2044448cc0 100644
--- a/AKModel/views.py
+++ b/AKModel/views.py
@@ -1,9 +1,11 @@
+import csv
 import json
 import os
 import tempfile
 from abc import ABC, abstractmethod
 from itertools import zip_longest
 
+import django.db
 from django.contrib import admin, messages
 from django.db.models.functions import Now
 from django.shortcuts import get_object_or_404, redirect
@@ -17,7 +19,7 @@ from rest_framework import viewsets, permissions, mixins
 
 from AKModel.forms import NewEventWizardStartForm, NewEventWizardSettingsForm, NewEventWizardPrepareImportForm, \
     NewEventWizardImportForm, NewEventWizardActivateForm, AdminIntermediateForm, SlideExportForm, \
-    AdminIntermediateActionForm, DefaultSlotEditorForm
+    AdminIntermediateActionForm, DefaultSlotEditorForm, RoomBatchCreationForm
 from AKModel.models import Event, AK, AKSlot, Room, AKTrack, AKCategory, AKOwner, AKOrgaMessage, AKRequirement, \
     ConstraintViolation, DefaultSlot
 from AKModel.serializers import AKSerializer, AKSlotSerializer, RoomSerializer, AKTrackSerializer, AKCategorySerializer, \
@@ -573,3 +575,44 @@ class DefaultSlotEditorView(EventSlugMixin, IntermediateAdminView):
                 .format(u=str(updated_count), c=str(created_count), d=str(deleted_count))
             )
         return super().form_valid(form)
+
+
+class RoomBatchCreationView(EventSlugMixin, IntermediateAdminView):
+    form_class = RoomBatchCreationForm
+    title = _("Import Rooms from CSV")
+
+    def get_success_url(self):
+        return reverse_lazy('admin:event_status', kwargs={'slug': self.event.slug})
+
+    def form_valid(self, form):
+        from django.apps import apps
+        VIRTUAL_ROOMS_SUPPORT = False
+        if apps.is_installed("AKOnline"):
+            VIRTUAL_ROOMS_SUPPORT = True
+            from AKOnline.models import VirtualRoom
+
+        created_count = 0
+
+        rooms_raw_dict: csv.DictReader = form.cleaned_data["rooms"]
+        for raw_room in rooms_raw_dict:
+            name = raw_room["name"]
+            location = raw_room["location"] if "location" in rooms_raw_dict.fieldnames else ""
+            capacity = raw_room["capacity"] if "capacity" in rooms_raw_dict.fieldnames else -1
+            url = raw_room["url"] if "url" in rooms_raw_dict.fieldnames else ""
+
+            try:
+                if VIRTUAL_ROOMS_SUPPORT and url != "":
+                    VirtualRoom.objects.create(name=name, location=location, capacity=capacity, url=url, event=self.event)
+                else:
+                    Room.objects.create(name=name, location=location, capacity=capacity, event=self.event)
+                created_count += 1
+            except django.db.Error as e:
+                messages.add_message(self.request, messages.WARNING,
+                                     _("Could not import room {name}: {e}").format(name=name, e=str(e)))
+
+        if created_count > 0:
+            messages.add_message(self.request, messages.SUCCESS,
+                                 _("Imported {count} room(s)").format(count=created_count))
+        else:
+            messages.add_message(self.request, messages.WARNING, _("No rooms imported"))
+        return super().form_valid(form)