diff --git a/aleksis/core/forms.py b/aleksis/core/forms.py
index 1ca40c66cf414058c14964af03b32f2144c2a8b5..0daff5fd91fe2c45452025dd4d1e99bb7246953e 100644
--- a/aleksis/core/forms.py
+++ b/aleksis/core/forms.py
@@ -1,7 +1,9 @@
 from datetime import time
+from typing import Optional
 
 from django import forms
 from django.contrib.auth import get_user_model
+from django.contrib.contenttypes.models import ContentType
 from django.core.exceptions import ValidationError
 from django.utils import timezone
 from django.utils.translation import ugettext_lazy as _
@@ -9,7 +11,7 @@ from django.utils.translation import ugettext_lazy as _
 from django_select2.forms import ModelSelect2MultipleWidget, Select2Widget
 from material import Layout, Fieldset, Row
 
-from .models import Group, Person, School, SchoolTerm, Announcement
+from .models import Group, Person, School, SchoolTerm, Announcement, AnnouncementRecipient
 
 
 class PersonAccountForm(forms.ModelForm):
@@ -149,26 +151,44 @@ class AnnouncementForm(forms.ModelForm):
     valid_until_date = forms.DateField(label=_("Date"))
     valid_until_time = forms.TimeField(label=_("Time"))
 
+    persons = forms.ModelMultipleChoiceField(Person.objects.all(), label=_("Persons"), required=False)
+    groups = forms.ModelMultipleChoiceField(Group.objects.all(), label=_("Groups"), required=False)
+
     layout = Layout(
         Fieldset(
             _("From when until when should the announcement be displayed?"),
             Row("valid_from_date", "valid_from_time", "valid_until_date", "valid_until_time"),
         ),
+        Fieldset(_("Who should see the announcement?"), Row("groups", "persons")),
         Fieldset(_("Write your announcement:"), "title", "description"),
     )
 
-    @classmethod
-    def get_initial(cls):
-        return {
-            "valid_from_date": timezone.datetime.now(),
-            "valid_from_time": time(0,0),
-            "valid_until_date": timezone.datetime.now(),
-            "valid_until_time": time(23, 59)
-        }
+    def __init__(self, *args, **kwargs):
+        if "instance" not in kwargs:
+            kwargs["initial"] = {
+                "valid_from_date": timezone.datetime.now(),
+                "valid_from_time": time(0, 0),
+                "valid_until_date": timezone.datetime.now(),
+                "valid_until_time": time(23, 59),
+            }
+        else:
+            announcement = kwargs["instance"]
+
+            # Fill special fields from given announcement instance
+            kwargs["initial"] = {
+                "valid_from_date": announcement.valid_from.date(),
+                "valid_from_time": announcement.valid_from.time(),
+                "valid_until_date": announcement.valid_until.date(),
+                "valid_until_time": announcement.valid_until.time(),
+                "groups": announcement.get_recipients_for_model(Group),
+                "persons": announcement.get_recipients_for_model(Person),
+            }
+        super().__init__(*args, **kwargs)
 
     def clean(self):
         data = super().clean()
 
+        # Check date and time
         from_date = data["valid_from_date"]
         from_time = data["valid_from_time"]
         until_date = data["valid_until_date"]
@@ -189,16 +209,31 @@ class AnnouncementForm(forms.ModelForm):
         data["valid_from"] = valid_from
         data["valid_until"] = valid_until
 
+        # Check recipients
+        if "groups" not in data and "persons" not in data:
+            raise ValidationError(_("You need at least one recipient."))
+
+        recipients = []
+        recipients += data.get("groups", [])
+        recipients += data.get("persons", [])
+
+        data["recipients"] = recipients
+
         return data
 
-    def save(self, _ = False):
+    def save(self, _=False):
+        # Save announcement
         a = self.instance if self.instance is not None else Announcement()
-
         a.valid_from = self.cleaned_data["valid_from"]
         a.valid_until = self.cleaned_data["valid_until"]
         a.title = self.cleaned_data["title"]
         a.description = self.cleaned_data["description"]
+        a.save()
 
+        # Save recipients
+        a.recipients.all().delete()
+        for recipient in self.cleaned_data["recipients"]:
+            a.recipients.create(recipient=recipient)
         a.save()
 
         return a
diff --git a/aleksis/core/models.py b/aleksis/core/models.py
index 9f001cc714584c9c4694d44b5f53f72971f3f6b9..aef59f28a6d81af6a0a970bdc90eedfdfe05f501 100644
--- a/aleksis/core/models.py
+++ b/aleksis/core/models.py
@@ -330,6 +330,12 @@ class Announcement(ExtensibleModel):
             persons += recipient.persons
         return persons
 
+    def get_recipients_for_model(self, obj: Union[models.Model]) -> Sequence[models.Model]:
+        """ Get all recipients for this announcement with a special content type (provided through model) """
+
+        ct = ContentType.objects.get_for_model(obj)
+        return [r.recipient for r in self.recipients.filter(content_type=ct)]
+
     def __str__(self):
         return self.title
 
diff --git a/aleksis/core/templates/core/announcement/list.html b/aleksis/core/templates/core/announcement/list.html
index e3fe5e4a0fc1ac6e1de1c7d023b72b11bd84cd7e..9f84617e255c78b7ee37e502c212e0704aa1da5e 100644
--- a/aleksis/core/templates/core/announcement/list.html
+++ b/aleksis/core/templates/core/announcement/list.html
@@ -30,16 +30,24 @@
         <td>{{ announcement.valid_until }}</td>
         <td>{{ announcement.recipients.all|join:", " }}</td>
         <td>
-          <a class="btn-flat waves-effect waves-orange orange-text" href="{% url "edit_announcement" announcement.id %}">
+          <a class="btn-flat waves-effect waves-orange orange-text"
+             href="{% url "edit_announcement" announcement.id %}">
             <i class="material-icons left">edit</i>
             {% trans "Edit" %}
           </a>
+          <form action="{% url "delete_announcement" announcement.id %}" method="post">
+            {% csrf_token %}
+            <button class="btn-flat waves-effect waves-re red-text" type="submit">
+              <i class="material-icons left">delete</i>
+              {% trans "Delete" %}
+            </button>
+          </form>
         </td>
       </tr>
     {% empty %}
       <tr>
-        <td colspan="4">
-          <p class="flow-text">{% trans "There are no announcements." %}</p>
+        <td colspan="5">
+          <p class="flow-text center-align">{% trans "There are no announcements." %}</p>
         </td>
       </tr>
     {% endfor %}
diff --git a/aleksis/core/urls.py b/aleksis/core/urls.py
index 894ffcfc2d3bef8d8cd52d5d7c53400f12684c3a..e5320dd02f05a884a8891c7793305f8c0672d7fc 100644
--- a/aleksis/core/urls.py
+++ b/aleksis/core/urls.py
@@ -38,6 +38,7 @@ urlpatterns = [
     path("announcements/", views.announcements, name="announcements"),
     path("announcement/create/", views.announcement_form, name="add_announcement"),
     path("announcement/edit/<int:pk>/", views.announcement_form, name="edit_announcement"),
+    path("announcement/delete/<int:pk>/", views.delete_announcement, name="delete_announcement"),
     path("maintenance-mode/", include("maintenance_mode.urls")),
     path("impersonate/", include("impersonate.urls")),
     path("__i18n__/", include("django.conf.urls.i18n")),
diff --git a/aleksis/core/views.py b/aleksis/core/views.py
index 4008d18960c15ac752b38fba33b79c4fdcf54c85..68773c76398542863bef6df3316ca3799a643e6a 100644
--- a/aleksis/core/views.py
+++ b/aleksis/core/views.py
@@ -293,17 +293,11 @@ def announcement_form(request: HttpRequest, pk: Optional[int] = None) -> HttpRes
         announcement = get_object_or_404(Announcement, pk=pk)
         form = AnnouncementForm(
             request.POST or None,
-            instance=announcement,
-            initial={
-                "valid_from_date": announcement.valid_from.date(),
-                "valid_from_time": announcement.valid_from.time(),
-                "valid_until_date": announcement.valid_until.date(),
-                "valid_until_time": announcement.valid_until.time()
-            }
+            instance=announcement
         )
         context["mode"] = "edit"
     else:
-        form = AnnouncementForm(request.POST or None, initial=AnnouncementForm.get_initial())
+        form = AnnouncementForm(request.POST or None)
         context["mode"] = "add"
 
     if request.method == "POST":
@@ -316,3 +310,13 @@ def announcement_form(request: HttpRequest, pk: Optional[int] = None) -> HttpRes
     context["form"] = form
 
     return render(request, "core/announcement/form.html", context)
+
+
+@admin_required
+def delete_announcement(request: HttpRequest, pk: int) -> HttpResponse:
+    if request.method == "POST":
+        announcement = get_object_or_404(Announcement, pk=pk)
+        announcement.delete()
+        messages.success(request, _("The announcement has been deleted."))
+
+    return redirect("announcements")