We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Django: adapt admin code for 3.x
It seems that we missed an upgrade to make it fully compatible with Django 3.x

We are using `admin.ACTION_CHECKBOX_NAME` when it was deprecated and it was removed already:

> The compatibility import of django.contrib.admin.helpers.ACTION_CHECKBOX_NAME in django.contrib.admin is removed.

(from https://docs.djangoproject.com/en/4.0/releases/3.1/#id1)

The code lives at https://github.com/readthedocs/readthedocs.org/blob/e94c26074e9abdf7056b4e6502c52f8a6b128055/readthedocs/notifications/views.py#L48

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `readthedocs/notifications/views.py`
Content:
```
1 """Django views for the notifications app."""
2 from django.contrib import admin, messages
3 from django.http import HttpResponseRedirect
4 from django.views.generic import FormView
5 
6 from .forms import SendNotificationForm
7 
8 
9 class SendNotificationView(FormView):
10 
11     """
12     Form view for sending notifications to users from admin pages.
13 
14     Accepts the following additional parameters:
15 
16     :param queryset: Queryset to use to determine the users to send emails to
17     :param action_name: Name of the action to pass to the form template,
18         determines the action to pass back to the admin view
19     :param notification_classes: List of :py:class:`Notification` classes to
20         display in the form
21     """
22 
23     form_class = SendNotificationForm
24     template_name = "notifications/send_notification_form.html"
25     action_name = "send_email"
26     notification_classes = []
27 
28     def get_form_kwargs(self):
29         """
30         Override form kwargs based on input fields.
31 
32         The admin posts to this view initially, so detect the send button on
33         form post variables. Drop additional fields if we see the send button.
34         """
35         kwargs = super().get_form_kwargs()
36         kwargs["notification_classes"] = self.notification_classes
37         if "send" not in self.request.POST:
38             kwargs.pop("data", None)
39             kwargs.pop("files", None)
40         return kwargs
41 
42     def get_initial(self):
43         """Add selected ids to initial form data."""
44         initial = super().get_initial()
45         initial["_selected_action"] = self.request.POST.getlist(
46             admin.ACTION_CHECKBOX_NAME,
47         )
48         return initial
49 
50     def form_valid(self, form):
51         """If form is valid, send notification to recipients."""
52         count = 0
53         notification_cls = form.cleaned_data["source"]
54         for obj in self.get_queryset().all():
55             for recipient in self.get_object_recipients(obj):
56                 notification = notification_cls(
57                     context_object=obj,
58                     request=self.request,
59                     user=recipient,
60                 )
61                 notification.send()
62                 count += 1
63         if count == 0:
64             self.message_user("No recipients to send to", level=messages.ERROR)
65         else:
66             self.message_user("Queued {} messages".format(count))
67         return HttpResponseRedirect(self.request.get_full_path())
68 
69     def get_object_recipients(self, obj):
70         """
71         Iterate over queryset objects and return User objects.
72 
73         This allows for non-User querysets to pass back a list of Users to send
74         to. By default, assume we're working with :py:class:`User` objects and
75         just yield the single object.
76 
77         For example, this could be made to return project owners with::
78 
79             for owner in AdminPermission.members(project):
80                 yield owner
81 
82         :param obj: object from queryset, type is dependent on model class
83         :rtype: django.contrib.auth.models.User
84         """
85         yield obj
86 
87     def get_queryset(self):
88         return self.kwargs.get("queryset")
89 
90     def get_context_data(self, **kwargs):
91         """Return queryset in context."""
92         context = super().get_context_data(**kwargs)
93         recipients = []
94         for obj in self.get_queryset().all():
95             recipients.extend(self.get_object_recipients(obj))
96         context["recipients"] = recipients
97         context["action_name"] = self.action_name
98         return context
99 
100     def message_user(
101         self,
102         message,
103         level=messages.INFO,
104         extra_tags="",
105         fail_silently=False,
106     ):
107         """
108         Implementation of.
109 
110         :py:meth:`django.contrib.admin.options.ModelAdmin.message_user`
111 
112         Send message through messages framework
113         """
114         # TODO generalize this or check if implementation in ModelAdmin is
115         # usable here
116         messages.add_message(
117             self.request,
118             level,
119             message,
120             extra_tags=extra_tags,
121             fail_silently=fail_silently,
122         )
123
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/readthedocs/notifications/views.py b/readthedocs/notifications/views.py
--- a/readthedocs/notifications/views.py
+++ b/readthedocs/notifications/views.py
@@ -1,5 +1,5 @@
 """Django views for the notifications app."""
-from django.contrib import admin, messages
+from django.contrib import messages
 from django.http import HttpResponseRedirect
 from django.views.generic import FormView
 
@@ -42,9 +42,7 @@
     def get_initial(self):
         """Add selected ids to initial form data."""
         initial = super().get_initial()
-        initial["_selected_action"] = self.request.POST.getlist(
-            admin.ACTION_CHECKBOX_NAME,
-        )
+        initial["_selected_action"] = self.request.POST.getlist("_selected_action")
         return initial
 
     def form_valid(self, form):

{"golden_diff": "diff --git a/readthedocs/notifications/views.py b/readthedocs/notifications/views.py\n--- a/readthedocs/notifications/views.py\n+++ b/readthedocs/notifications/views.py\n@@ -1,5 +1,5 @@\n \"\"\"Django views for the notifications app.\"\"\"\n-from django.contrib import admin, messages\n+from django.contrib import messages\n from django.http import HttpResponseRedirect\n from django.views.generic import FormView\n \n@@ -42,9 +42,7 @@\n     def get_initial(self):\n         \"\"\"Add selected ids to initial form data.\"\"\"\n         initial = super().get_initial()\n-        initial[\"_selected_action\"] = self.request.POST.getlist(\n-            admin.ACTION_CHECKBOX_NAME,\n-        )\n+        initial[\"_selected_action\"] = self.request.POST.getlist(\"_selected_action\")\n         return initial\n \n     def form_valid(self, form):\n", "issue": "Django: adapt admin code for 3.x\nIt seems that we missed an upgrade to make it fully compatible with Django 3.x\r\n\r\nWe are using `admin.ACTION_CHECKBOX_NAME` when it was deprecated and it was removed already:\r\n\r\n> The compatibility import of django.contrib.admin.helpers.ACTION_CHECKBOX_NAME in django.contrib.admin is removed.\r\n\r\n(from https://docs.djangoproject.com/en/4.0/releases/3.1/#id1)\r\n\r\nThe code lives at https://github.com/readthedocs/readthedocs.org/blob/e94c26074e9abdf7056b4e6502c52f8a6b128055/readthedocs/notifications/views.py#L48\n", "before_files": [{"content": "\"\"\"Django views for the notifications app.\"\"\"\nfrom django.contrib import admin, messages\nfrom django.http import HttpResponseRedirect\nfrom django.views.generic import FormView\n\nfrom .forms import SendNotificationForm\n\n\nclass SendNotificationView(FormView):\n\n    \"\"\"\n    Form view for sending notifications to users from admin pages.\n\n    Accepts the following additional parameters:\n\n    :param queryset: Queryset to use to determine the users to send emails to\n    :param action_name: Name of the action to pass to the form template,\n        determines the action to pass back to the admin view\n    :param notification_classes: List of :py:class:`Notification` classes to\n        display in the form\n    \"\"\"\n\n    form_class = SendNotificationForm\n    template_name = \"notifications/send_notification_form.html\"\n    action_name = \"send_email\"\n    notification_classes = []\n\n    def get_form_kwargs(self):\n        \"\"\"\n        Override form kwargs based on input fields.\n\n        The admin posts to this view initially, so detect the send button on\n        form post variables. Drop additional fields if we see the send button.\n        \"\"\"\n        kwargs = super().get_form_kwargs()\n        kwargs[\"notification_classes\"] = self.notification_classes\n        if \"send\" not in self.request.POST:\n            kwargs.pop(\"data\", None)\n            kwargs.pop(\"files\", None)\n        return kwargs\n\n    def get_initial(self):\n        \"\"\"Add selected ids to initial form data.\"\"\"\n        initial = super().get_initial()\n        initial[\"_selected_action\"] = self.request.POST.getlist(\n            admin.ACTION_CHECKBOX_NAME,\n        )\n        return initial\n\n    def form_valid(self, form):\n        \"\"\"If form is valid, send notification to recipients.\"\"\"\n        count = 0\n        notification_cls = form.cleaned_data[\"source\"]\n        for obj in self.get_queryset().all():\n            for recipient in self.get_object_recipients(obj):\n                notification = notification_cls(\n                    context_object=obj,\n                    request=self.request,\n                    user=recipient,\n                )\n                notification.send()\n                count += 1\n        if count == 0:\n            self.message_user(\"No recipients to send to\", level=messages.ERROR)\n        else:\n            self.message_user(\"Queued {} messages\".format(count))\n        return HttpResponseRedirect(self.request.get_full_path())\n\n    def get_object_recipients(self, obj):\n        \"\"\"\n        Iterate over queryset objects and return User objects.\n\n        This allows for non-User querysets to pass back a list of Users to send\n        to. By default, assume we're working with :py:class:`User` objects and\n        just yield the single object.\n\n        For example, this could be made to return project owners with::\n\n            for owner in AdminPermission.members(project):\n                yield owner\n\n        :param obj: object from queryset, type is dependent on model class\n        :rtype: django.contrib.auth.models.User\n        \"\"\"\n        yield obj\n\n    def get_queryset(self):\n        return self.kwargs.get(\"queryset\")\n\n    def get_context_data(self, **kwargs):\n        \"\"\"Return queryset in context.\"\"\"\n        context = super().get_context_data(**kwargs)\n        recipients = []\n        for obj in self.get_queryset().all():\n            recipients.extend(self.get_object_recipients(obj))\n        context[\"recipients\"] = recipients\n        context[\"action_name\"] = self.action_name\n        return context\n\n    def message_user(\n        self,\n        message,\n        level=messages.INFO,\n        extra_tags=\"\",\n        fail_silently=False,\n    ):\n        \"\"\"\n        Implementation of.\n\n        :py:meth:`django.contrib.admin.options.ModelAdmin.message_user`\n\n        Send message through messages framework\n        \"\"\"\n        # TODO generalize this or check if implementation in ModelAdmin is\n        # usable here\n        messages.add_message(\n            self.request,\n            level,\n            message,\n            extra_tags=extra_tags,\n            fail_silently=fail_silently,\n        )\n", "path": "readthedocs/notifications/views.py"}], "after_files": [{"content": "\"\"\"Django views for the notifications app.\"\"\"\nfrom django.contrib import messages\nfrom django.http import HttpResponseRedirect\nfrom django.views.generic import FormView\n\nfrom .forms import SendNotificationForm\n\n\nclass SendNotificationView(FormView):\n\n    \"\"\"\n    Form view for sending notifications to users from admin pages.\n\n    Accepts the following additional parameters:\n\n    :param queryset: Queryset to use to determine the users to send emails to\n    :param action_name: Name of the action to pass to the form template,\n        determines the action to pass back to the admin view\n    :param notification_classes: List of :py:class:`Notification` classes to\n        display in the form\n    \"\"\"\n\n    form_class = SendNotificationForm\n    template_name = \"notifications/send_notification_form.html\"\n    action_name = \"send_email\"\n    notification_classes = []\n\n    def get_form_kwargs(self):\n        \"\"\"\n        Override form kwargs based on input fields.\n\n        The admin posts to this view initially, so detect the send button on\n        form post variables. Drop additional fields if we see the send button.\n        \"\"\"\n        kwargs = super().get_form_kwargs()\n        kwargs[\"notification_classes\"] = self.notification_classes\n        if \"send\" not in self.request.POST:\n            kwargs.pop(\"data\", None)\n            kwargs.pop(\"files\", None)\n        return kwargs\n\n    def get_initial(self):\n        \"\"\"Add selected ids to initial form data.\"\"\"\n        initial = super().get_initial()\n        initial[\"_selected_action\"] = self.request.POST.getlist(\"_selected_action\")\n        return initial\n\n    def form_valid(self, form):\n        \"\"\"If form is valid, send notification to recipients.\"\"\"\n        count = 0\n        notification_cls = form.cleaned_data[\"source\"]\n        for obj in self.get_queryset().all():\n            for recipient in self.get_object_recipients(obj):\n                notification = notification_cls(\n                    context_object=obj,\n                    request=self.request,\n                    user=recipient,\n                )\n                notification.send()\n                count += 1\n        if count == 0:\n            self.message_user(\"No recipients to send to\", level=messages.ERROR)\n        else:\n            self.message_user(\"Queued {} messages\".format(count))\n        return HttpResponseRedirect(self.request.get_full_path())\n\n    def get_object_recipients(self, obj):\n        \"\"\"\n        Iterate over queryset objects and return User objects.\n\n        This allows for non-User querysets to pass back a list of Users to send\n        to. By default, assume we're working with :py:class:`User` objects and\n        just yield the single object.\n\n        For example, this could be made to return project owners with::\n\n            for owner in AdminPermission.members(project):\n                yield owner\n\n        :param obj: object from queryset, type is dependent on model class\n        :rtype: django.contrib.auth.models.User\n        \"\"\"\n        yield obj\n\n    def get_queryset(self):\n        return self.kwargs.get(\"queryset\")\n\n    def get_context_data(self, **kwargs):\n        \"\"\"Return queryset in context.\"\"\"\n        context = super().get_context_data(**kwargs)\n        recipients = []\n        for obj in self.get_queryset().all():\n            recipients.extend(self.get_object_recipients(obj))\n        context[\"recipients\"] = recipients\n        context[\"action_name\"] = self.action_name\n        return context\n\n    def message_user(\n        self,\n        message,\n        level=messages.INFO,\n        extra_tags=\"\",\n        fail_silently=False,\n    ):\n        \"\"\"\n        Implementation of.\n\n        :py:meth:`django.contrib.admin.options.ModelAdmin.message_user`\n\n        Send message through messages framework\n        \"\"\"\n        # TODO generalize this or check if implementation in ModelAdmin is\n        # usable here\n        messages.add_message(\n            self.request,\n            level,\n            message,\n            extra_tags=extra_tags,\n            fail_silently=fail_silently,\n        )\n", "path": "readthedocs/notifications/views.py"}]}