We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Nutzer löschen
Als Manager möchte ich einen Nutzer löschen können. Dafür soll es in der Liste der Nutzer sowie auf der Bearbeitungsseite eines Nutzers eine entsprechende Schaltfläche geben.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `ephios/user_management/urls.py`
Content:
```
1 from django.urls import path
2 
3 from ephios.user_management import views
4 
5 app_name = "user_management"
6 urlpatterns = [
7     path("profile/", views.ProfileView.as_view(), name="profile"),
8     path("groups/", views.GroupListView.as_view(), name="group_list"),
9     path("groups/<int:pk>/edit", views.GroupUpdateView.as_view(), name="group_edit"),
10     path("groups/<int:pk>/delete", views.GroupDeleteView.as_view(), name="group_delete"),
11     path("groups/create", views.GroupCreateView.as_view(), name="group_add"),
12     path(
13         "users/",
14         views.UserProfileListView.as_view(),
15         name="userprofile_list",
16     ),
17     path(
18         "users/<int:pk>/edit",
19         views.UserProfileUpdateView.as_view(),
20         name="userprofile_edit",
21     ),
22     path(
23         "users/create/",
24         views.UserProfileCreateView.as_view(),
25         name="userprofile_create",
26     ),
27 ]
28
```

Path: `ephios/user_management/views.py`
Content:
```
1 from django.contrib import messages
2 from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
3 from django.contrib.auth.models import Group
4 from django.shortcuts import redirect
5 from django.urls import reverse
6 from django.utils.translation import gettext as _
7 from django.views.generic import (
8     CreateView,
9     DeleteView,
10     DetailView,
11     ListView,
12     TemplateView,
13     UpdateView,
14 )
15 from django.views.generic.detail import SingleObjectMixin
16 from guardian.shortcuts import get_objects_for_group
17 
18 from ephios.user_management import mail
19 from ephios.user_management.forms import GroupForm, QualificationGrantFormset, UserProfileForm
20 from ephios.user_management.models import UserProfile
21 
22 
23 class ProfileView(LoginRequiredMixin, DetailView):
24     def get_object(self, queryset=None):
25         return self.request.user
26 
27 
28 class UserProfileListView(PermissionRequiredMixin, ListView):
29     model = UserProfile
30     permission_required = "user_management.view_userprofile"
31 
32 
33 class UserProfileCreateView(PermissionRequiredMixin, TemplateView):
34     template_name = "user_management/userprofile_form.html"
35     permission_required = "user_management.add_userprofile"
36     model = UserProfile
37 
38     def get_context_data(self, **kwargs):
39         kwargs.setdefault("userprofile_form", UserProfileForm(self.request.POST or None))
40         kwargs.setdefault(
41             "qualification_formset", QualificationGrantFormset(self.request.POST or None)
42         )
43         return super().get_context_data(**kwargs)
44 
45     def post(self, request, *args, **kwargs):
46         userprofile_form = UserProfileForm(self.request.POST)
47         qualification_formset = QualificationGrantFormset(self.request.POST)
48         if all((userprofile_form.is_valid(), qualification_formset.is_valid())):
49             userprofile = userprofile_form.save()
50             qualification_formset.instance = userprofile
51             qualification_formset.save()
52             messages.success(self.request, _("User added successfully."))
53             if userprofile.is_active:
54                 mail.send_account_creation_info(userprofile)
55             return redirect(reverse("user_management:userprofile_list"))
56         else:
57             return self.render_to_response(
58                 self.get_context_data(
59                     userprofile_form=userprofile_form, qualification_formset=qualification_formset
60                 )
61             )
62 
63 
64 class UserProfileUpdateView(PermissionRequiredMixin, SingleObjectMixin, TemplateView):
65     model = UserProfile
66     permission_required = "user_management.change_userprofile"
67     template_name = "user_management/userprofile_form.html"
68 
69     def get_userprofile_form(self):
70         return UserProfileForm(
71             self.request.POST or None,
72             initial={
73                 "groups": self.get_object().groups.all(),
74             },
75             instance=self.object,
76         )
77 
78     def get_qualification_formset(self):
79         return QualificationGrantFormset(self.request.POST or None, instance=self.object)
80 
81     def get_context_data(self, **kwargs):
82         self.object = self.get_object()
83         kwargs.setdefault("userprofile_form", self.get_userprofile_form())
84         kwargs.setdefault("qualification_formset", self.get_qualification_formset())
85         return super().get_context_data(**kwargs)
86 
87     def post(self, request, *args, **kwargs):
88         self.object = self.get_object()
89         userprofile_form = self.get_userprofile_form()
90         qualification_formset = self.get_qualification_formset()
91         if all((userprofile_form.is_valid(), qualification_formset.is_valid())):
92             userprofile = userprofile_form.save()
93             qualification_formset.save()
94             messages.success(self.request, _("User updated successfully."))
95             if userprofile.is_active:
96                 mail.send_account_update_info(userprofile)
97             return redirect(reverse("user_management:userprofile_list"))
98         else:
99             return self.render_to_response(
100                 self.get_context_data(
101                     userprofile_form=userprofile_form, qualification_formset=qualification_formset
102                 )
103             )
104 
105 
106 class GroupListView(PermissionRequiredMixin, ListView):
107     model = Group
108     permission_required = "auth.view_group"
109     template_name = "user_management/group_list.html"
110 
111 
112 class GroupCreateView(PermissionRequiredMixin, CreateView):
113     model = Group
114     permission_required = "auth.add_group"
115     template_name = "user_management/group_form.html"
116     form_class = GroupForm
117 
118     def get_form_kwargs(self):
119         kwargs = super().get_form_kwargs()
120         kwargs["initial"] = {
121             "users": UserProfile.objects.none(),
122             "can_add_event": False,
123             "publish_event_for_group": Group.objects.none(),
124         }
125         return kwargs
126 
127     def get_success_url(self):
128         messages.success(self.request, _("Group created successfully."))
129         return reverse("user_management:group_list")
130 
131 
132 class GroupUpdateView(PermissionRequiredMixin, UpdateView):
133     model = Group
134     permission_required = "auth.change_group"
135     template_name = "user_management/group_form.html"
136     form_class = GroupForm
137 
138     def get_form_kwargs(self):
139         kwargs = super().get_form_kwargs()
140         kwargs["initial"] = {
141             "users": self.object.user_set.all(),
142             "can_view_past_event": self.object.permissions.filter(
143                 codename="view_past_event"
144             ).exists(),
145             "can_add_event": self.object.permissions.filter(codename="add_event").exists(),
146             "publish_event_for_group": get_objects_for_group(
147                 self.object, "publish_event_for_group", klass=Group
148             ),
149         }
150         return kwargs
151 
152     def get_success_url(self):
153         messages.success(self.request, _("Group updated successfully."))
154         return reverse("user_management:group_list")
155 
156 
157 class GroupDeleteView(PermissionRequiredMixin, DeleteView):
158     model = Group
159     permission_required = "auth.delete_group"
160     template_name = "user_management/group_confirm_delete.html"
161 
162     def get_success_url(self):
163         return reverse("user_management:group_list")
164
```

Path: `ephios/user_management/forms.py`
Content:
```
1 from django import forms
2 from django.contrib.auth.forms import ReadOnlyPasswordHashField
3 from django.contrib.auth.models import Group
4 from django.contrib.auth.password_validation import validate_password
5 from django.forms import (
6     BooleanField,
7     ModelForm,
8     ModelMultipleChoiceField,
9     TextInput,
10     inlineformset_factory,
11 )
12 from django.utils.translation import gettext as _
13 from django_select2.forms import Select2MultipleWidget, Select2Widget
14 from guardian.shortcuts import assign_perm, remove_perm
15 
16 from ephios.extra.widgets import CustomDateInput
17 from ephios.user_management.models import QualificationGrant, UserProfile
18 from ephios.user_management.widgets import MultiUserProfileWidget
19 
20 
21 class UserCreationForm(forms.ModelForm):
22     """A form for creating new users. Includes all the required
23     fields, plus a repeated password."""
24 
25     password = forms.CharField(label=_("Password"), widget=forms.PasswordInput)
26     password_validation = forms.CharField(
27         label=_("Password confirmation"), widget=forms.PasswordInput
28     )
29     field_order = ["email", "password", "password_validation"]
30 
31     class Meta:
32         model = UserProfile
33         fields = (
34             "email",
35             "first_name",
36             "last_name",
37             "date_of_birth",
38             "phone",
39         )
40 
41     def clean_password_validation(self):
42         # Check that the two password entries match
43         password = self.cleaned_data.get("password")
44         password_validation = self.cleaned_data.get("password_validation")
45         if password and password_validation and password != password_validation:
46             raise forms.ValidationError(_("Passwords don't match"))
47         return password_validation
48 
49     def _post_clean(self):
50         super()._post_clean()
51         # Validate the password after self.instance is updated with form data
52         # by super().
53         password = self.cleaned_data.get("password_validation")
54         if password:
55             try:
56                 validate_password(password, self.instance)
57             except forms.ValidationError as error:
58                 self.add_error("password", error)
59 
60     def save(self, commit=True):
61         # Save the provided password in hashed format
62         user = super().save(commit=False)
63         user.set_password(self.cleaned_data["password"])
64         if commit:
65             user.save()
66         return user
67 
68 
69 class UserChangeForm(forms.ModelForm):
70     """A form for updating users. Includes all the fields on
71     the user, but replaces the password field with admin's
72     password hash display field.
73     """
74 
75     password = ReadOnlyPasswordHashField()
76 
77     class Meta:
78         model = UserProfile
79         fields = (
80             "email",
81             "password",
82             "first_name",
83             "last_name",
84             "date_of_birth",
85             "phone",
86             "is_active",
87             "is_staff",
88         )
89 
90     def clean_password(self):
91         # Regardless of what the user provides, return the initial value.
92         # This is done here, rather than on the field, because the
93         # field does not have access to the initial value
94         return self.initial["password"]
95 
96 
97 class GroupForm(ModelForm):
98     publish_event_for_group = ModelMultipleChoiceField(
99         label=_("Can publish event for group"),
100         queryset=Group.objects.all(),
101         required=False,
102         help_text=_("Choose groups that this group can make events visible for."),
103         widget=Select2MultipleWidget,
104     )
105     can_view_past_event = BooleanField(label=_("Can view past events"), required=False)
106     can_add_event = BooleanField(label=_("Can add event"), required=False)
107     users = ModelMultipleChoiceField(
108         label=_("Users"), queryset=UserProfile.objects.all(), widget=MultiUserProfileWidget
109     )
110 
111     field_order = [
112         "name",
113         "users",
114         "can_view_past_event",
115         "can_add_event",
116         "publish_event_for_group",
117     ]
118 
119     class Meta:
120         model = Group
121         fields = ["name"]
122 
123     def save(self, commit=True):
124         group = super().save(commit)
125 
126         group.user_set.set(self.cleaned_data["users"])
127 
128         if self.cleaned_data["can_view_past_event"]:
129             assign_perm("event_management.view_past_event", group)
130         else:
131             remove_perm("event_management.view_past_event", group)
132 
133         if self.cleaned_data["can_add_event"]:
134             assign_perm("event_management.add_event", group)
135             assign_perm("event_management.delete_event", group)
136 
137             if "publish_event_for_group" in self.changed_data:
138                 for target_group in self.cleaned_data["publish_event_for_group"].exlude(
139                     id__in=self.initial["publish_event_for_group"]
140                 ):
141                     assign_perm("publish_event_for_group", group, target_group)
142                 for target_group in self.initial["publish_event_for_group"].exclude(
143                     id__in=self.cleaned_data["publish_event_for_group"]
144                 ):
145                     remove_perm("publish_event_for_group", group, target_group)
146         else:
147             remove_perm("event_management.add_event", group)
148             remove_perm("event_management.delete_event", group)
149             for target_group in Group.objects.all():
150                 remove_perm("publish_event_for_group", group, target_group)
151 
152 
153 class UserProfileForm(ModelForm):
154     groups = ModelMultipleChoiceField(
155         label=_("Groups"), queryset=Group.objects.all(), widget=Select2MultipleWidget
156     )
157 
158     field_order = [
159         "email",
160         "first_name",
161         "last_name",
162         "date_of_birth",
163         "phone",
164         "groups",
165         "is_active",
166     ]
167 
168     class Meta:
169         model = UserProfile
170         fields = ["email", "first_name", "last_name", "date_of_birth", "phone", "is_active"]
171         widgets = {"date_of_birth": CustomDateInput(format="%Y-%m-%d")}
172         help_texts = {
173             "is_active": _("Inactive users cannot log in and do not get any notifications.")
174         }
175         labels = {"is_active": _("Active user")}
176 
177     def save(self, commit=True):
178         userprofile = super().save(commit)
179         userprofile.groups.set(self.cleaned_data["groups"])
180         userprofile.save()
181         return userprofile
182 
183 
184 class QualificationGrantForm(ModelForm):
185     model = QualificationGrant
186 
187     class Meta:
188         fields = ["qualification", "expires"]
189         widgets = {"qualification": Select2Widget, "expires": CustomDateInput(format="%Y-%m-%d")}
190 
191     def __init__(self, *args, **kwargs):
192         super().__init__(*args, **kwargs)
193         instance = getattr(self, "instance", None)
194         if instance and instance.pk:
195             self.fields["qualification"].disabled = True
196             self.fields["qualification"].widget = TextInput(
197                 attrs={"class": "form-control-plaintext"}
198             )
199             self.initial["qualification"] = instance.qualification.title
200 
201 
202 QualificationGrantFormset = inlineformset_factory(
203     UserProfile,
204     QualificationGrant,
205     form=QualificationGrantForm,
206     extra=0,
207 )
208
```
--- 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/ephios/user_management/forms.py b/ephios/user_management/forms.py
--- a/ephios/user_management/forms.py
+++ b/ephios/user_management/forms.py
@@ -149,6 +149,8 @@
             for target_group in Group.objects.all():
                 remove_perm("publish_event_for_group", group, target_group)
 
+        return group
+
 
 class UserProfileForm(ModelForm):
     groups = ModelMultipleChoiceField(
diff --git a/ephios/user_management/urls.py b/ephios/user_management/urls.py
--- a/ephios/user_management/urls.py
+++ b/ephios/user_management/urls.py
@@ -19,6 +19,11 @@
         views.UserProfileUpdateView.as_view(),
         name="userprofile_edit",
     ),
+    path(
+        "users/<int:pk>/delete",
+        views.UserProfileDeleteView.as_view(),
+        name="userprofile_delete",
+    ),
     path(
         "users/create/",
         views.UserProfileCreateView.as_view(),
diff --git a/ephios/user_management/views.py b/ephios/user_management/views.py
--- a/ephios/user_management/views.py
+++ b/ephios/user_management/views.py
@@ -49,7 +49,12 @@
             userprofile = userprofile_form.save()
             qualification_formset.instance = userprofile
             qualification_formset.save()
-            messages.success(self.request, _("User added successfully."))
+            messages.success(
+                self.request,
+                _("User {name} ({user}) added successfully.").format(
+                    name=userprofile.get_full_name(), user=userprofile
+                ),
+            )
             if userprofile.is_active:
                 mail.send_account_creation_info(userprofile)
             return redirect(reverse("user_management:userprofile_list"))
@@ -91,7 +96,12 @@
         if all((userprofile_form.is_valid(), qualification_formset.is_valid())):
             userprofile = userprofile_form.save()
             qualification_formset.save()
-            messages.success(self.request, _("User updated successfully."))
+            messages.success(
+                self.request,
+                _("User {name} ({user}) updated successfully.").format(
+                    name=self.object.get_full_name(), user=self.object
+                ),
+            )
             if userprofile.is_active:
                 mail.send_account_update_info(userprofile)
             return redirect(reverse("user_management:userprofile_list"))
@@ -103,6 +113,21 @@
             )
 
 
+class UserProfileDeleteView(PermissionRequiredMixin, DeleteView):
+    model = UserProfile
+    permission_required = "user_management.delete_userprofile"
+    template_name = "user_management/userprofile_confirm_delete.html"
+
+    def get_success_url(self):
+        messages.info(
+            self.request,
+            _("The user {name} ({user}) was deleted.").format(
+                name=self.object.get_full_name(), user=self.object
+            ),
+        )
+        return reverse("user_management:userprofile_list")
+
+
 class GroupListView(PermissionRequiredMixin, ListView):
     model = Group
     permission_required = "auth.view_group"
@@ -125,7 +150,9 @@
         return kwargs
 
     def get_success_url(self):
-        messages.success(self.request, _("Group created successfully."))
+        messages.success(
+            self.request, _('Group "{group}" created successfully.').format(group=self.object)
+        )
         return reverse("user_management:group_list")
 
 
@@ -150,7 +177,9 @@
         return kwargs
 
     def get_success_url(self):
-        messages.success(self.request, _("Group updated successfully."))
+        messages.success(
+            self.request, _('Group "{group}" updated successfully.').format(group=self.object)
+        )
         return reverse("user_management:group_list")
 
 
@@ -160,4 +189,5 @@
     template_name = "user_management/group_confirm_delete.html"
 
     def get_success_url(self):
+        messages.info(self.request, _('The group "{group}" was deleted.').format(group=self.object))
         return reverse("user_management:group_list")

{"golden_diff": "diff --git a/ephios/user_management/forms.py b/ephios/user_management/forms.py\n--- a/ephios/user_management/forms.py\n+++ b/ephios/user_management/forms.py\n@@ -149,6 +149,8 @@\n             for target_group in Group.objects.all():\n                 remove_perm(\"publish_event_for_group\", group, target_group)\n \n+        return group\n+\n \n class UserProfileForm(ModelForm):\n     groups = ModelMultipleChoiceField(\ndiff --git a/ephios/user_management/urls.py b/ephios/user_management/urls.py\n--- a/ephios/user_management/urls.py\n+++ b/ephios/user_management/urls.py\n@@ -19,6 +19,11 @@\n         views.UserProfileUpdateView.as_view(),\n         name=\"userprofile_edit\",\n     ),\n+    path(\n+        \"users/<int:pk>/delete\",\n+        views.UserProfileDeleteView.as_view(),\n+        name=\"userprofile_delete\",\n+    ),\n     path(\n         \"users/create/\",\n         views.UserProfileCreateView.as_view(),\ndiff --git a/ephios/user_management/views.py b/ephios/user_management/views.py\n--- a/ephios/user_management/views.py\n+++ b/ephios/user_management/views.py\n@@ -49,7 +49,12 @@\n             userprofile = userprofile_form.save()\n             qualification_formset.instance = userprofile\n             qualification_formset.save()\n-            messages.success(self.request, _(\"User added successfully.\"))\n+            messages.success(\n+                self.request,\n+                _(\"User {name} ({user}) added successfully.\").format(\n+                    name=userprofile.get_full_name(), user=userprofile\n+                ),\n+            )\n             if userprofile.is_active:\n                 mail.send_account_creation_info(userprofile)\n             return redirect(reverse(\"user_management:userprofile_list\"))\n@@ -91,7 +96,12 @@\n         if all((userprofile_form.is_valid(), qualification_formset.is_valid())):\n             userprofile = userprofile_form.save()\n             qualification_formset.save()\n-            messages.success(self.request, _(\"User updated successfully.\"))\n+            messages.success(\n+                self.request,\n+                _(\"User {name} ({user}) updated successfully.\").format(\n+                    name=self.object.get_full_name(), user=self.object\n+                ),\n+            )\n             if userprofile.is_active:\n                 mail.send_account_update_info(userprofile)\n             return redirect(reverse(\"user_management:userprofile_list\"))\n@@ -103,6 +113,21 @@\n             )\n \n \n+class UserProfileDeleteView(PermissionRequiredMixin, DeleteView):\n+    model = UserProfile\n+    permission_required = \"user_management.delete_userprofile\"\n+    template_name = \"user_management/userprofile_confirm_delete.html\"\n+\n+    def get_success_url(self):\n+        messages.info(\n+            self.request,\n+            _(\"The user {name} ({user}) was deleted.\").format(\n+                name=self.object.get_full_name(), user=self.object\n+            ),\n+        )\n+        return reverse(\"user_management:userprofile_list\")\n+\n+\n class GroupListView(PermissionRequiredMixin, ListView):\n     model = Group\n     permission_required = \"auth.view_group\"\n@@ -125,7 +150,9 @@\n         return kwargs\n \n     def get_success_url(self):\n-        messages.success(self.request, _(\"Group created successfully.\"))\n+        messages.success(\n+            self.request, _('Group \"{group}\" created successfully.').format(group=self.object)\n+        )\n         return reverse(\"user_management:group_list\")\n \n \n@@ -150,7 +177,9 @@\n         return kwargs\n \n     def get_success_url(self):\n-        messages.success(self.request, _(\"Group updated successfully.\"))\n+        messages.success(\n+            self.request, _('Group \"{group}\" updated successfully.').format(group=self.object)\n+        )\n         return reverse(\"user_management:group_list\")\n \n \n@@ -160,4 +189,5 @@\n     template_name = \"user_management/group_confirm_delete.html\"\n \n     def get_success_url(self):\n+        messages.info(self.request, _('The group \"{group}\" was deleted.').format(group=self.object))\n         return reverse(\"user_management:group_list\")\n", "issue": "Nutzer l\u00f6schen\nAls Manager m\u00f6chte ich einen Nutzer l\u00f6schen k\u00f6nnen. Daf\u00fcr soll es in der Liste der Nutzer sowie auf der Bearbeitungsseite eines Nutzers eine entsprechende Schaltfl\u00e4che geben.\n", "before_files": [{"content": "from django.urls import path\n\nfrom ephios.user_management import views\n\napp_name = \"user_management\"\nurlpatterns = [\n    path(\"profile/\", views.ProfileView.as_view(), name=\"profile\"),\n    path(\"groups/\", views.GroupListView.as_view(), name=\"group_list\"),\n    path(\"groups/<int:pk>/edit\", views.GroupUpdateView.as_view(), name=\"group_edit\"),\n    path(\"groups/<int:pk>/delete\", views.GroupDeleteView.as_view(), name=\"group_delete\"),\n    path(\"groups/create\", views.GroupCreateView.as_view(), name=\"group_add\"),\n    path(\n        \"users/\",\n        views.UserProfileListView.as_view(),\n        name=\"userprofile_list\",\n    ),\n    path(\n        \"users/<int:pk>/edit\",\n        views.UserProfileUpdateView.as_view(),\n        name=\"userprofile_edit\",\n    ),\n    path(\n        \"users/create/\",\n        views.UserProfileCreateView.as_view(),\n        name=\"userprofile_create\",\n    ),\n]\n", "path": "ephios/user_management/urls.py"}, {"content": "from django.contrib import messages\nfrom django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin\nfrom django.contrib.auth.models import Group\nfrom django.shortcuts import redirect\nfrom django.urls import reverse\nfrom django.utils.translation import gettext as _\nfrom django.views.generic import (\n    CreateView,\n    DeleteView,\n    DetailView,\n    ListView,\n    TemplateView,\n    UpdateView,\n)\nfrom django.views.generic.detail import SingleObjectMixin\nfrom guardian.shortcuts import get_objects_for_group\n\nfrom ephios.user_management import mail\nfrom ephios.user_management.forms import GroupForm, QualificationGrantFormset, UserProfileForm\nfrom ephios.user_management.models import UserProfile\n\n\nclass ProfileView(LoginRequiredMixin, DetailView):\n    def get_object(self, queryset=None):\n        return self.request.user\n\n\nclass UserProfileListView(PermissionRequiredMixin, ListView):\n    model = UserProfile\n    permission_required = \"user_management.view_userprofile\"\n\n\nclass UserProfileCreateView(PermissionRequiredMixin, TemplateView):\n    template_name = \"user_management/userprofile_form.html\"\n    permission_required = \"user_management.add_userprofile\"\n    model = UserProfile\n\n    def get_context_data(self, **kwargs):\n        kwargs.setdefault(\"userprofile_form\", UserProfileForm(self.request.POST or None))\n        kwargs.setdefault(\n            \"qualification_formset\", QualificationGrantFormset(self.request.POST or None)\n        )\n        return super().get_context_data(**kwargs)\n\n    def post(self, request, *args, **kwargs):\n        userprofile_form = UserProfileForm(self.request.POST)\n        qualification_formset = QualificationGrantFormset(self.request.POST)\n        if all((userprofile_form.is_valid(), qualification_formset.is_valid())):\n            userprofile = userprofile_form.save()\n            qualification_formset.instance = userprofile\n            qualification_formset.save()\n            messages.success(self.request, _(\"User added successfully.\"))\n            if userprofile.is_active:\n                mail.send_account_creation_info(userprofile)\n            return redirect(reverse(\"user_management:userprofile_list\"))\n        else:\n            return self.render_to_response(\n                self.get_context_data(\n                    userprofile_form=userprofile_form, qualification_formset=qualification_formset\n                )\n            )\n\n\nclass UserProfileUpdateView(PermissionRequiredMixin, SingleObjectMixin, TemplateView):\n    model = UserProfile\n    permission_required = \"user_management.change_userprofile\"\n    template_name = \"user_management/userprofile_form.html\"\n\n    def get_userprofile_form(self):\n        return UserProfileForm(\n            self.request.POST or None,\n            initial={\n                \"groups\": self.get_object().groups.all(),\n            },\n            instance=self.object,\n        )\n\n    def get_qualification_formset(self):\n        return QualificationGrantFormset(self.request.POST or None, instance=self.object)\n\n    def get_context_data(self, **kwargs):\n        self.object = self.get_object()\n        kwargs.setdefault(\"userprofile_form\", self.get_userprofile_form())\n        kwargs.setdefault(\"qualification_formset\", self.get_qualification_formset())\n        return super().get_context_data(**kwargs)\n\n    def post(self, request, *args, **kwargs):\n        self.object = self.get_object()\n        userprofile_form = self.get_userprofile_form()\n        qualification_formset = self.get_qualification_formset()\n        if all((userprofile_form.is_valid(), qualification_formset.is_valid())):\n            userprofile = userprofile_form.save()\n            qualification_formset.save()\n            messages.success(self.request, _(\"User updated successfully.\"))\n            if userprofile.is_active:\n                mail.send_account_update_info(userprofile)\n            return redirect(reverse(\"user_management:userprofile_list\"))\n        else:\n            return self.render_to_response(\n                self.get_context_data(\n                    userprofile_form=userprofile_form, qualification_formset=qualification_formset\n                )\n            )\n\n\nclass GroupListView(PermissionRequiredMixin, ListView):\n    model = Group\n    permission_required = \"auth.view_group\"\n    template_name = \"user_management/group_list.html\"\n\n\nclass GroupCreateView(PermissionRequiredMixin, CreateView):\n    model = Group\n    permission_required = \"auth.add_group\"\n    template_name = \"user_management/group_form.html\"\n    form_class = GroupForm\n\n    def get_form_kwargs(self):\n        kwargs = super().get_form_kwargs()\n        kwargs[\"initial\"] = {\n            \"users\": UserProfile.objects.none(),\n            \"can_add_event\": False,\n            \"publish_event_for_group\": Group.objects.none(),\n        }\n        return kwargs\n\n    def get_success_url(self):\n        messages.success(self.request, _(\"Group created successfully.\"))\n        return reverse(\"user_management:group_list\")\n\n\nclass GroupUpdateView(PermissionRequiredMixin, UpdateView):\n    model = Group\n    permission_required = \"auth.change_group\"\n    template_name = \"user_management/group_form.html\"\n    form_class = GroupForm\n\n    def get_form_kwargs(self):\n        kwargs = super().get_form_kwargs()\n        kwargs[\"initial\"] = {\n            \"users\": self.object.user_set.all(),\n            \"can_view_past_event\": self.object.permissions.filter(\n                codename=\"view_past_event\"\n            ).exists(),\n            \"can_add_event\": self.object.permissions.filter(codename=\"add_event\").exists(),\n            \"publish_event_for_group\": get_objects_for_group(\n                self.object, \"publish_event_for_group\", klass=Group\n            ),\n        }\n        return kwargs\n\n    def get_success_url(self):\n        messages.success(self.request, _(\"Group updated successfully.\"))\n        return reverse(\"user_management:group_list\")\n\n\nclass GroupDeleteView(PermissionRequiredMixin, DeleteView):\n    model = Group\n    permission_required = \"auth.delete_group\"\n    template_name = \"user_management/group_confirm_delete.html\"\n\n    def get_success_url(self):\n        return reverse(\"user_management:group_list\")\n", "path": "ephios/user_management/views.py"}, {"content": "from django import forms\nfrom django.contrib.auth.forms import ReadOnlyPasswordHashField\nfrom django.contrib.auth.models import Group\nfrom django.contrib.auth.password_validation import validate_password\nfrom django.forms import (\n    BooleanField,\n    ModelForm,\n    ModelMultipleChoiceField,\n    TextInput,\n    inlineformset_factory,\n)\nfrom django.utils.translation import gettext as _\nfrom django_select2.forms import Select2MultipleWidget, Select2Widget\nfrom guardian.shortcuts import assign_perm, remove_perm\n\nfrom ephios.extra.widgets import CustomDateInput\nfrom ephios.user_management.models import QualificationGrant, UserProfile\nfrom ephios.user_management.widgets import MultiUserProfileWidget\n\n\nclass UserCreationForm(forms.ModelForm):\n    \"\"\"A form for creating new users. Includes all the required\n    fields, plus a repeated password.\"\"\"\n\n    password = forms.CharField(label=_(\"Password\"), widget=forms.PasswordInput)\n    password_validation = forms.CharField(\n        label=_(\"Password confirmation\"), widget=forms.PasswordInput\n    )\n    field_order = [\"email\", \"password\", \"password_validation\"]\n\n    class Meta:\n        model = UserProfile\n        fields = (\n            \"email\",\n            \"first_name\",\n            \"last_name\",\n            \"date_of_birth\",\n            \"phone\",\n        )\n\n    def clean_password_validation(self):\n        # Check that the two password entries match\n        password = self.cleaned_data.get(\"password\")\n        password_validation = self.cleaned_data.get(\"password_validation\")\n        if password and password_validation and password != password_validation:\n            raise forms.ValidationError(_(\"Passwords don't match\"))\n        return password_validation\n\n    def _post_clean(self):\n        super()._post_clean()\n        # Validate the password after self.instance is updated with form data\n        # by super().\n        password = self.cleaned_data.get(\"password_validation\")\n        if password:\n            try:\n                validate_password(password, self.instance)\n            except forms.ValidationError as error:\n                self.add_error(\"password\", error)\n\n    def save(self, commit=True):\n        # Save the provided password in hashed format\n        user = super().save(commit=False)\n        user.set_password(self.cleaned_data[\"password\"])\n        if commit:\n            user.save()\n        return user\n\n\nclass UserChangeForm(forms.ModelForm):\n    \"\"\"A form for updating users. Includes all the fields on\n    the user, but replaces the password field with admin's\n    password hash display field.\n    \"\"\"\n\n    password = ReadOnlyPasswordHashField()\n\n    class Meta:\n        model = UserProfile\n        fields = (\n            \"email\",\n            \"password\",\n            \"first_name\",\n            \"last_name\",\n            \"date_of_birth\",\n            \"phone\",\n            \"is_active\",\n            \"is_staff\",\n        )\n\n    def clean_password(self):\n        # Regardless of what the user provides, return the initial value.\n        # This is done here, rather than on the field, because the\n        # field does not have access to the initial value\n        return self.initial[\"password\"]\n\n\nclass GroupForm(ModelForm):\n    publish_event_for_group = ModelMultipleChoiceField(\n        label=_(\"Can publish event for group\"),\n        queryset=Group.objects.all(),\n        required=False,\n        help_text=_(\"Choose groups that this group can make events visible for.\"),\n        widget=Select2MultipleWidget,\n    )\n    can_view_past_event = BooleanField(label=_(\"Can view past events\"), required=False)\n    can_add_event = BooleanField(label=_(\"Can add event\"), required=False)\n    users = ModelMultipleChoiceField(\n        label=_(\"Users\"), queryset=UserProfile.objects.all(), widget=MultiUserProfileWidget\n    )\n\n    field_order = [\n        \"name\",\n        \"users\",\n        \"can_view_past_event\",\n        \"can_add_event\",\n        \"publish_event_for_group\",\n    ]\n\n    class Meta:\n        model = Group\n        fields = [\"name\"]\n\n    def save(self, commit=True):\n        group = super().save(commit)\n\n        group.user_set.set(self.cleaned_data[\"users\"])\n\n        if self.cleaned_data[\"can_view_past_event\"]:\n            assign_perm(\"event_management.view_past_event\", group)\n        else:\n            remove_perm(\"event_management.view_past_event\", group)\n\n        if self.cleaned_data[\"can_add_event\"]:\n            assign_perm(\"event_management.add_event\", group)\n            assign_perm(\"event_management.delete_event\", group)\n\n            if \"publish_event_for_group\" in self.changed_data:\n                for target_group in self.cleaned_data[\"publish_event_for_group\"].exlude(\n                    id__in=self.initial[\"publish_event_for_group\"]\n                ):\n                    assign_perm(\"publish_event_for_group\", group, target_group)\n                for target_group in self.initial[\"publish_event_for_group\"].exclude(\n                    id__in=self.cleaned_data[\"publish_event_for_group\"]\n                ):\n                    remove_perm(\"publish_event_for_group\", group, target_group)\n        else:\n            remove_perm(\"event_management.add_event\", group)\n            remove_perm(\"event_management.delete_event\", group)\n            for target_group in Group.objects.all():\n                remove_perm(\"publish_event_for_group\", group, target_group)\n\n\nclass UserProfileForm(ModelForm):\n    groups = ModelMultipleChoiceField(\n        label=_(\"Groups\"), queryset=Group.objects.all(), widget=Select2MultipleWidget\n    )\n\n    field_order = [\n        \"email\",\n        \"first_name\",\n        \"last_name\",\n        \"date_of_birth\",\n        \"phone\",\n        \"groups\",\n        \"is_active\",\n    ]\n\n    class Meta:\n        model = UserProfile\n        fields = [\"email\", \"first_name\", \"last_name\", \"date_of_birth\", \"phone\", \"is_active\"]\n        widgets = {\"date_of_birth\": CustomDateInput(format=\"%Y-%m-%d\")}\n        help_texts = {\n            \"is_active\": _(\"Inactive users cannot log in and do not get any notifications.\")\n        }\n        labels = {\"is_active\": _(\"Active user\")}\n\n    def save(self, commit=True):\n        userprofile = super().save(commit)\n        userprofile.groups.set(self.cleaned_data[\"groups\"])\n        userprofile.save()\n        return userprofile\n\n\nclass QualificationGrantForm(ModelForm):\n    model = QualificationGrant\n\n    class Meta:\n        fields = [\"qualification\", \"expires\"]\n        widgets = {\"qualification\": Select2Widget, \"expires\": CustomDateInput(format=\"%Y-%m-%d\")}\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        instance = getattr(self, \"instance\", None)\n        if instance and instance.pk:\n            self.fields[\"qualification\"].disabled = True\n            self.fields[\"qualification\"].widget = TextInput(\n                attrs={\"class\": \"form-control-plaintext\"}\n            )\n            self.initial[\"qualification\"] = instance.qualification.title\n\n\nQualificationGrantFormset = inlineformset_factory(\n    UserProfile,\n    QualificationGrant,\n    form=QualificationGrantForm,\n    extra=0,\n)\n", "path": "ephios/user_management/forms.py"}], "after_files": [{"content": "from django.urls import path\n\nfrom ephios.user_management import views\n\napp_name = \"user_management\"\nurlpatterns = [\n    path(\"profile/\", views.ProfileView.as_view(), name=\"profile\"),\n    path(\"groups/\", views.GroupListView.as_view(), name=\"group_list\"),\n    path(\"groups/<int:pk>/edit\", views.GroupUpdateView.as_view(), name=\"group_edit\"),\n    path(\"groups/<int:pk>/delete\", views.GroupDeleteView.as_view(), name=\"group_delete\"),\n    path(\"groups/create\", views.GroupCreateView.as_view(), name=\"group_add\"),\n    path(\n        \"users/\",\n        views.UserProfileListView.as_view(),\n        name=\"userprofile_list\",\n    ),\n    path(\n        \"users/<int:pk>/edit\",\n        views.UserProfileUpdateView.as_view(),\n        name=\"userprofile_edit\",\n    ),\n    path(\n        \"users/<int:pk>/delete\",\n        views.UserProfileDeleteView.as_view(),\n        name=\"userprofile_delete\",\n    ),\n    path(\n        \"users/create/\",\n        views.UserProfileCreateView.as_view(),\n        name=\"userprofile_create\",\n    ),\n]\n", "path": "ephios/user_management/urls.py"}, {"content": "from django.contrib import messages\nfrom django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin\nfrom django.contrib.auth.models import Group\nfrom django.shortcuts import redirect\nfrom django.urls import reverse\nfrom django.utils.translation import gettext as _\nfrom django.views.generic import (\n    CreateView,\n    DeleteView,\n    DetailView,\n    ListView,\n    TemplateView,\n    UpdateView,\n)\nfrom django.views.generic.detail import SingleObjectMixin\nfrom guardian.shortcuts import get_objects_for_group\n\nfrom ephios.user_management import mail\nfrom ephios.user_management.forms import GroupForm, QualificationGrantFormset, UserProfileForm\nfrom ephios.user_management.models import UserProfile\n\n\nclass ProfileView(LoginRequiredMixin, DetailView):\n    def get_object(self, queryset=None):\n        return self.request.user\n\n\nclass UserProfileListView(PermissionRequiredMixin, ListView):\n    model = UserProfile\n    permission_required = \"user_management.view_userprofile\"\n\n\nclass UserProfileCreateView(PermissionRequiredMixin, TemplateView):\n    template_name = \"user_management/userprofile_form.html\"\n    permission_required = \"user_management.add_userprofile\"\n    model = UserProfile\n\n    def get_context_data(self, **kwargs):\n        kwargs.setdefault(\"userprofile_form\", UserProfileForm(self.request.POST or None))\n        kwargs.setdefault(\n            \"qualification_formset\", QualificationGrantFormset(self.request.POST or None)\n        )\n        return super().get_context_data(**kwargs)\n\n    def post(self, request, *args, **kwargs):\n        userprofile_form = UserProfileForm(self.request.POST)\n        qualification_formset = QualificationGrantFormset(self.request.POST)\n        if all((userprofile_form.is_valid(), qualification_formset.is_valid())):\n            userprofile = userprofile_form.save()\n            qualification_formset.instance = userprofile\n            qualification_formset.save()\n            messages.success(\n                self.request,\n                _(\"User {name} ({user}) added successfully.\").format(\n                    name=userprofile.get_full_name(), user=userprofile\n                ),\n            )\n            if userprofile.is_active:\n                mail.send_account_creation_info(userprofile)\n            return redirect(reverse(\"user_management:userprofile_list\"))\n        else:\n            return self.render_to_response(\n                self.get_context_data(\n                    userprofile_form=userprofile_form, qualification_formset=qualification_formset\n                )\n            )\n\n\nclass UserProfileUpdateView(PermissionRequiredMixin, SingleObjectMixin, TemplateView):\n    model = UserProfile\n    permission_required = \"user_management.change_userprofile\"\n    template_name = \"user_management/userprofile_form.html\"\n\n    def get_userprofile_form(self):\n        return UserProfileForm(\n            self.request.POST or None,\n            initial={\n                \"groups\": self.get_object().groups.all(),\n            },\n            instance=self.object,\n        )\n\n    def get_qualification_formset(self):\n        return QualificationGrantFormset(self.request.POST or None, instance=self.object)\n\n    def get_context_data(self, **kwargs):\n        self.object = self.get_object()\n        kwargs.setdefault(\"userprofile_form\", self.get_userprofile_form())\n        kwargs.setdefault(\"qualification_formset\", self.get_qualification_formset())\n        return super().get_context_data(**kwargs)\n\n    def post(self, request, *args, **kwargs):\n        self.object = self.get_object()\n        userprofile_form = self.get_userprofile_form()\n        qualification_formset = self.get_qualification_formset()\n        if all((userprofile_form.is_valid(), qualification_formset.is_valid())):\n            userprofile = userprofile_form.save()\n            qualification_formset.save()\n            messages.success(\n                self.request,\n                _(\"User {name} ({user}) updated successfully.\").format(\n                    name=self.object.get_full_name(), user=self.object\n                ),\n            )\n            if userprofile.is_active:\n                mail.send_account_update_info(userprofile)\n            return redirect(reverse(\"user_management:userprofile_list\"))\n        else:\n            return self.render_to_response(\n                self.get_context_data(\n                    userprofile_form=userprofile_form, qualification_formset=qualification_formset\n                )\n            )\n\n\nclass UserProfileDeleteView(PermissionRequiredMixin, DeleteView):\n    model = UserProfile\n    permission_required = \"user_management.delete_userprofile\"\n    template_name = \"user_management/userprofile_confirm_delete.html\"\n\n    def get_success_url(self):\n        messages.info(\n            self.request,\n            _(\"The user {name} ({user}) was deleted.\").format(\n                name=self.object.get_full_name(), user=self.object\n            ),\n        )\n        return reverse(\"user_management:userprofile_list\")\n\n\nclass GroupListView(PermissionRequiredMixin, ListView):\n    model = Group\n    permission_required = \"auth.view_group\"\n    template_name = \"user_management/group_list.html\"\n\n\nclass GroupCreateView(PermissionRequiredMixin, CreateView):\n    model = Group\n    permission_required = \"auth.add_group\"\n    template_name = \"user_management/group_form.html\"\n    form_class = GroupForm\n\n    def get_form_kwargs(self):\n        kwargs = super().get_form_kwargs()\n        kwargs[\"initial\"] = {\n            \"users\": UserProfile.objects.none(),\n            \"can_add_event\": False,\n            \"publish_event_for_group\": Group.objects.none(),\n        }\n        return kwargs\n\n    def get_success_url(self):\n        messages.success(\n            self.request, _('Group \"{group}\" created successfully.').format(group=self.object)\n        )\n        return reverse(\"user_management:group_list\")\n\n\nclass GroupUpdateView(PermissionRequiredMixin, UpdateView):\n    model = Group\n    permission_required = \"auth.change_group\"\n    template_name = \"user_management/group_form.html\"\n    form_class = GroupForm\n\n    def get_form_kwargs(self):\n        kwargs = super().get_form_kwargs()\n        kwargs[\"initial\"] = {\n            \"users\": self.object.user_set.all(),\n            \"can_view_past_event\": self.object.permissions.filter(\n                codename=\"view_past_event\"\n            ).exists(),\n            \"can_add_event\": self.object.permissions.filter(codename=\"add_event\").exists(),\n            \"publish_event_for_group\": get_objects_for_group(\n                self.object, \"publish_event_for_group\", klass=Group\n            ),\n        }\n        return kwargs\n\n    def get_success_url(self):\n        messages.success(\n            self.request, _('Group \"{group}\" updated successfully.').format(group=self.object)\n        )\n        return reverse(\"user_management:group_list\")\n\n\nclass GroupDeleteView(PermissionRequiredMixin, DeleteView):\n    model = Group\n    permission_required = \"auth.delete_group\"\n    template_name = \"user_management/group_confirm_delete.html\"\n\n    def get_success_url(self):\n        messages.info(self.request, _('The group \"{group}\" was deleted.').format(group=self.object))\n        return reverse(\"user_management:group_list\")\n", "path": "ephios/user_management/views.py"}, {"content": "from django import forms\nfrom django.contrib.auth.forms import ReadOnlyPasswordHashField\nfrom django.contrib.auth.models import Group\nfrom django.contrib.auth.password_validation import validate_password\nfrom django.forms import (\n    BooleanField,\n    ModelForm,\n    ModelMultipleChoiceField,\n    TextInput,\n    inlineformset_factory,\n)\nfrom django.utils.translation import gettext as _\nfrom django_select2.forms import Select2MultipleWidget, Select2Widget\nfrom guardian.shortcuts import assign_perm, remove_perm\n\nfrom ephios.extra.widgets import CustomDateInput\nfrom ephios.user_management.models import QualificationGrant, UserProfile\nfrom ephios.user_management.widgets import MultiUserProfileWidget\n\n\nclass UserCreationForm(forms.ModelForm):\n    \"\"\"A form for creating new users. Includes all the required\n    fields, plus a repeated password.\"\"\"\n\n    password = forms.CharField(label=_(\"Password\"), widget=forms.PasswordInput)\n    password_validation = forms.CharField(\n        label=_(\"Password confirmation\"), widget=forms.PasswordInput\n    )\n    field_order = [\"email\", \"password\", \"password_validation\"]\n\n    class Meta:\n        model = UserProfile\n        fields = (\n            \"email\",\n            \"first_name\",\n            \"last_name\",\n            \"date_of_birth\",\n            \"phone\",\n        )\n\n    def clean_password_validation(self):\n        # Check that the two password entries match\n        password = self.cleaned_data.get(\"password\")\n        password_validation = self.cleaned_data.get(\"password_validation\")\n        if password and password_validation and password != password_validation:\n            raise forms.ValidationError(_(\"Passwords don't match\"))\n        return password_validation\n\n    def _post_clean(self):\n        super()._post_clean()\n        # Validate the password after self.instance is updated with form data\n        # by super().\n        password = self.cleaned_data.get(\"password_validation\")\n        if password:\n            try:\n                validate_password(password, self.instance)\n            except forms.ValidationError as error:\n                self.add_error(\"password\", error)\n\n    def save(self, commit=True):\n        # Save the provided password in hashed format\n        user = super().save(commit=False)\n        user.set_password(self.cleaned_data[\"password\"])\n        if commit:\n            user.save()\n        return user\n\n\nclass UserChangeForm(forms.ModelForm):\n    \"\"\"A form for updating users. Includes all the fields on\n    the user, but replaces the password field with admin's\n    password hash display field.\n    \"\"\"\n\n    password = ReadOnlyPasswordHashField()\n\n    class Meta:\n        model = UserProfile\n        fields = (\n            \"email\",\n            \"password\",\n            \"first_name\",\n            \"last_name\",\n            \"date_of_birth\",\n            \"phone\",\n            \"is_active\",\n            \"is_staff\",\n        )\n\n    def clean_password(self):\n        # Regardless of what the user provides, return the initial value.\n        # This is done here, rather than on the field, because the\n        # field does not have access to the initial value\n        return self.initial[\"password\"]\n\n\nclass GroupForm(ModelForm):\n    publish_event_for_group = ModelMultipleChoiceField(\n        label=_(\"Can publish event for group\"),\n        queryset=Group.objects.all(),\n        required=False,\n        help_text=_(\"Choose groups that this group can make events visible for.\"),\n        widget=Select2MultipleWidget,\n    )\n    can_view_past_event = BooleanField(label=_(\"Can view past events\"), required=False)\n    can_add_event = BooleanField(label=_(\"Can add event\"), required=False)\n    users = ModelMultipleChoiceField(\n        label=_(\"Users\"), queryset=UserProfile.objects.all(), widget=MultiUserProfileWidget\n    )\n\n    field_order = [\n        \"name\",\n        \"users\",\n        \"can_view_past_event\",\n        \"can_add_event\",\n        \"publish_event_for_group\",\n    ]\n\n    class Meta:\n        model = Group\n        fields = [\"name\"]\n\n    def save(self, commit=True):\n        group = super().save(commit)\n\n        group.user_set.set(self.cleaned_data[\"users\"])\n\n        if self.cleaned_data[\"can_view_past_event\"]:\n            assign_perm(\"event_management.view_past_event\", group)\n        else:\n            remove_perm(\"event_management.view_past_event\", group)\n\n        if self.cleaned_data[\"can_add_event\"]:\n            assign_perm(\"event_management.add_event\", group)\n            assign_perm(\"event_management.delete_event\", group)\n\n            if \"publish_event_for_group\" in self.changed_data:\n                for target_group in self.cleaned_data[\"publish_event_for_group\"].exlude(\n                    id__in=self.initial[\"publish_event_for_group\"]\n                ):\n                    assign_perm(\"publish_event_for_group\", group, target_group)\n                for target_group in self.initial[\"publish_event_for_group\"].exclude(\n                    id__in=self.cleaned_data[\"publish_event_for_group\"]\n                ):\n                    remove_perm(\"publish_event_for_group\", group, target_group)\n        else:\n            remove_perm(\"event_management.add_event\", group)\n            remove_perm(\"event_management.delete_event\", group)\n            for target_group in Group.objects.all():\n                remove_perm(\"publish_event_for_group\", group, target_group)\n\n        return group\n\n\nclass UserProfileForm(ModelForm):\n    groups = ModelMultipleChoiceField(\n        label=_(\"Groups\"), queryset=Group.objects.all(), widget=Select2MultipleWidget\n    )\n\n    field_order = [\n        \"email\",\n        \"first_name\",\n        \"last_name\",\n        \"date_of_birth\",\n        \"phone\",\n        \"groups\",\n        \"is_active\",\n    ]\n\n    class Meta:\n        model = UserProfile\n        fields = [\"email\", \"first_name\", \"last_name\", \"date_of_birth\", \"phone\", \"is_active\"]\n        widgets = {\"date_of_birth\": CustomDateInput(format=\"%Y-%m-%d\")}\n        help_texts = {\n            \"is_active\": _(\"Inactive users cannot log in and do not get any notifications.\")\n        }\n        labels = {\"is_active\": _(\"Active user\")}\n\n    def save(self, commit=True):\n        userprofile = super().save(commit)\n        userprofile.groups.set(self.cleaned_data[\"groups\"])\n        userprofile.save()\n        return userprofile\n\n\nclass QualificationGrantForm(ModelForm):\n    model = QualificationGrant\n\n    class Meta:\n        fields = [\"qualification\", \"expires\"]\n        widgets = {\"qualification\": Select2Widget, \"expires\": CustomDateInput(format=\"%Y-%m-%d\")}\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        instance = getattr(self, \"instance\", None)\n        if instance and instance.pk:\n            self.fields[\"qualification\"].disabled = True\n            self.fields[\"qualification\"].widget = TextInput(\n                attrs={\"class\": \"form-control-plaintext\"}\n            )\n            self.initial[\"qualification\"] = instance.qualification.title\n\n\nQualificationGrantFormset = inlineformset_factory(\n    UserProfile,\n    QualificationGrant,\n    form=QualificationGrantForm,\n    extra=0,\n)\n", "path": "ephios/user_management/forms.py"}]}