We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Locked questionnaires failing in editor form
#1445 introduced locked questionnaires. However, they are not dealt with correctly in the evaluation editor form. When initially opening the form, the locked questionnaires are correctly selected but are not handled correctly when saving the form.

Steps to reproduce:
1. As manager, assign a locked questionnaire as the only general questionnaire for an evaluation.
2. Enable the evaluation for editor review.
3. As editor, open the evaluation form and try to save it. Saving will fail with an error for the field "General questionnaires" ("This field is required.").

The locked questionnaire should count as a selected questionnaire and the form should be saved.
A test should be added for this use case.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `evap/contributor/forms.py`
Content:
```
1 from datetime import datetime, timedelta
2 import logging
3 
4 from django import forms
5 from django.conf import settings
6 from django.db.models import Q
7 from django.forms.widgets import CheckboxSelectMultiple
8 from django.utils.translation import gettext_lazy as _
9 from evap.evaluation.forms import UserModelMultipleChoiceField, UserModelChoiceField
10 from evap.evaluation.models import Course, Evaluation, Questionnaire, UserProfile
11 from evap.evaluation.tools import date_to_datetime
12 from evap.staff.forms import ContributionForm
13 
14 logger = logging.getLogger(__name__)
15 
16 
17 class EvaluationForm(forms.ModelForm):
18     general_questionnaires = forms.ModelMultipleChoiceField(queryset=None, widget=CheckboxSelectMultiple, label=_("General questionnaires"))
19     course = forms.ModelChoiceField(Course.objects.all(), disabled=True, required=False, widget=forms.HiddenInput())
20     name_de_field = forms.CharField(label=_("Name (German)"), disabled=True, required=False)
21     name_en_field = forms.CharField(label=_("Name (English)"), disabled=True, required=False)
22 
23     class Meta:
24         model = Evaluation
25         fields = ('name_de_field', 'name_en_field', 'vote_start_datetime', 'vote_end_date', 'general_questionnaires', 'course')
26 
27     def __init__(self, *args, **kwargs):
28         super().__init__(*args, **kwargs)
29 
30         self.fields['name_de_field'].initial = self.instance.full_name_de
31         self.fields['name_en_field'].initial = self.instance.full_name_en
32 
33         self.fields['general_questionnaires'].queryset = Questionnaire.objects.general_questionnaires().filter(
34             Q(visibility=Questionnaire.Visibility.EDITORS) | Q(contributions__evaluation=self.instance)).distinct()
35 
36         self.fields['vote_start_datetime'].localize = True
37         self.fields['vote_end_date'].localize = True
38 
39         if self.instance.general_contribution:
40             self.fields['general_questionnaires'].initial = [q.pk for q in self.instance.general_contribution.questionnaires.all()]
41 
42         if not self.instance.allow_editors_to_edit:
43             for field in self._meta.fields:
44                 self.fields[field].disabled = True
45 
46     def clean(self):
47         super().clean()
48 
49         vote_start_datetime = self.cleaned_data.get('vote_start_datetime')
50         vote_end_date = self.cleaned_data.get('vote_end_date')
51         if vote_start_datetime and vote_end_date:
52             if vote_start_datetime.date() > vote_end_date:
53                 self.add_error("vote_start_datetime", "")
54                 self.add_error("vote_end_date", _("The first day of evaluation must be before the last one."))
55 
56     def clean_vote_end_date(self):
57         vote_end_date = self.cleaned_data.get('vote_end_date')
58 
59         # The actual deadline is EVALUATION_END_OFFSET_HOURS:00 AM of the day after vote_end_date.
60         # Therefore an evaluation date 24h + EVALUATION_END_OFFSET_HOURS in the past would technically still be in the future.
61         if vote_end_date and date_to_datetime(vote_end_date) + timedelta(hours=24 + settings.EVALUATION_END_OFFSET_HOURS) < datetime.now():
62             raise forms.ValidationError(_("The last day of evaluation must be in the future."))
63         return vote_end_date
64 
65     def clean_general_questionnaires(self):
66         # Ensure all locked questionnaires still have the same status (included or not)
67         locked_qs = self.fields['general_questionnaires'].queryset.filter(is_locked=True)
68 
69         not_locked = [q for q in self.cleaned_data.get('general_questionnaires') if q not in locked_qs]
70         locked = [q.pk for q in self.instance.general_contribution.questionnaires.filter(is_locked=True)]
71 
72         return not_locked + locked
73 
74     def save(self, *args, **kw):
75         evaluation = super().save(*args, **kw)
76         evaluation.general_contribution.questionnaires.set(self.cleaned_data.get('general_questionnaires'))
77         return evaluation
78 
79 
80 class EditorContributionForm(ContributionForm):
81     def __init__(self, *args, **kwargs):
82         super().__init__(*args, **kwargs)
83 
84         existing_contributor_pk = self.instance.contributor.pk if self.instance.contributor else None
85 
86         self.fields['questionnaires'].queryset = Questionnaire.objects.contributor_questionnaires().filter(
87             Q(visibility=Questionnaire.Visibility.EDITORS) | Q(contributions__evaluation=self.evaluation)).distinct()
88         self.fields['contributor'].queryset = UserProfile.objects.filter(
89             (Q(is_active=True) & Q(is_proxy_user=False)) | Q(pk=existing_contributor_pk)
90         )
91 
92 
93 class DelegatesForm(forms.ModelForm):
94     delegates = UserModelMultipleChoiceField(queryset=UserProfile.objects.exclude(is_active=False).exclude(is_proxy_user=True),
95                                              required=False)
96 
97     class Meta:
98         model = UserProfile
99         fields = ('delegates',)
100         field_classes = {
101             'delegates': UserModelMultipleChoiceField,
102         }
103 
104     def __init__(self, *args, **kwargs):
105         super().__init__(*args, **kwargs)
106 
107     def save(self, *args, **kw):
108         super().save(*args, **kw)
109         logger.info('User "{}" edited the settings.'.format(self.instance.email))
110 
111 
112 class DelegateSelectionForm(forms.Form):
113     delegate_to = UserModelChoiceField(label=_("Delegate to"),
114                                        queryset=UserProfile.objects.exclude(is_active=False).exclude(is_proxy_user=True))
115
```
--- 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/evap/contributor/forms.py b/evap/contributor/forms.py
--- a/evap/contributor/forms.py
+++ b/evap/contributor/forms.py
@@ -15,7 +15,7 @@
 
 
 class EvaluationForm(forms.ModelForm):
-    general_questionnaires = forms.ModelMultipleChoiceField(queryset=None, widget=CheckboxSelectMultiple, label=_("General questionnaires"))
+    general_questionnaires = forms.ModelMultipleChoiceField(queryset=None, required=False, widget=CheckboxSelectMultiple, label=_("General questionnaires"))
     course = forms.ModelChoiceField(Course.objects.all(), disabled=True, required=False, widget=forms.HiddenInput())
     name_de_field = forms.CharField(label=_("Name (German)"), disabled=True, required=False)
     name_en_field = forms.CharField(label=_("Name (English)"), disabled=True, required=False)
@@ -64,10 +64,14 @@
 
     def clean_general_questionnaires(self):
         # Ensure all locked questionnaires still have the same status (included or not)
-        locked_qs = self.fields['general_questionnaires'].queryset.filter(is_locked=True)
+        not_locked = []
+        if self.cleaned_data.get('general_questionnaires'):
+            not_locked = list(self.cleaned_data.get('general_questionnaires').filter(is_locked=False))
 
-        not_locked = [q for q in self.cleaned_data.get('general_questionnaires') if q not in locked_qs]
-        locked = [q.pk for q in self.instance.general_contribution.questionnaires.filter(is_locked=True)]
+        locked = list(self.instance.general_contribution.questionnaires.filter(is_locked=True))
+
+        if not not_locked + locked:
+            self.add_error("general_questionnaires", _("At least one questionnaire must be selected."))
 
         return not_locked + locked

{"golden_diff": "diff --git a/evap/contributor/forms.py b/evap/contributor/forms.py\n--- a/evap/contributor/forms.py\n+++ b/evap/contributor/forms.py\n@@ -15,7 +15,7 @@\n \n \n class EvaluationForm(forms.ModelForm):\n-    general_questionnaires = forms.ModelMultipleChoiceField(queryset=None, widget=CheckboxSelectMultiple, label=_(\"General questionnaires\"))\n+    general_questionnaires = forms.ModelMultipleChoiceField(queryset=None, required=False, widget=CheckboxSelectMultiple, label=_(\"General questionnaires\"))\n     course = forms.ModelChoiceField(Course.objects.all(), disabled=True, required=False, widget=forms.HiddenInput())\n     name_de_field = forms.CharField(label=_(\"Name (German)\"), disabled=True, required=False)\n     name_en_field = forms.CharField(label=_(\"Name (English)\"), disabled=True, required=False)\n@@ -64,10 +64,14 @@\n \n     def clean_general_questionnaires(self):\n         # Ensure all locked questionnaires still have the same status (included or not)\n-        locked_qs = self.fields['general_questionnaires'].queryset.filter(is_locked=True)\n+        not_locked = []\n+        if self.cleaned_data.get('general_questionnaires'):\n+            not_locked = list(self.cleaned_data.get('general_questionnaires').filter(is_locked=False))\n \n-        not_locked = [q for q in self.cleaned_data.get('general_questionnaires') if q not in locked_qs]\n-        locked = [q.pk for q in self.instance.general_contribution.questionnaires.filter(is_locked=True)]\n+        locked = list(self.instance.general_contribution.questionnaires.filter(is_locked=True))\n+\n+        if not not_locked + locked:\n+            self.add_error(\"general_questionnaires\", _(\"At least one questionnaire must be selected.\"))\n \n         return not_locked + locked\n", "issue": "Locked questionnaires failing in editor form\n#1445 introduced locked questionnaires. However, they are not dealt with correctly in the evaluation editor form. When initially opening the form, the locked questionnaires are correctly selected but are not handled correctly when saving the form.\r\n\r\nSteps to reproduce:\r\n1. As manager, assign a locked questionnaire as the only general questionnaire for an evaluation.\r\n2. Enable the evaluation for editor review.\r\n3. As editor, open the evaluation form and try to save it. Saving will fail with an error for the field \"General questionnaires\" (\"This field is required.\").\r\n\r\nThe locked questionnaire should count as a selected questionnaire and the form should be saved.\r\nA test should be added for this use case.\n", "before_files": [{"content": "from datetime import datetime, timedelta\nimport logging\n\nfrom django import forms\nfrom django.conf import settings\nfrom django.db.models import Q\nfrom django.forms.widgets import CheckboxSelectMultiple\nfrom django.utils.translation import gettext_lazy as _\nfrom evap.evaluation.forms import UserModelMultipleChoiceField, UserModelChoiceField\nfrom evap.evaluation.models import Course, Evaluation, Questionnaire, UserProfile\nfrom evap.evaluation.tools import date_to_datetime\nfrom evap.staff.forms import ContributionForm\n\nlogger = logging.getLogger(__name__)\n\n\nclass EvaluationForm(forms.ModelForm):\n    general_questionnaires = forms.ModelMultipleChoiceField(queryset=None, widget=CheckboxSelectMultiple, label=_(\"General questionnaires\"))\n    course = forms.ModelChoiceField(Course.objects.all(), disabled=True, required=False, widget=forms.HiddenInput())\n    name_de_field = forms.CharField(label=_(\"Name (German)\"), disabled=True, required=False)\n    name_en_field = forms.CharField(label=_(\"Name (English)\"), disabled=True, required=False)\n\n    class Meta:\n        model = Evaluation\n        fields = ('name_de_field', 'name_en_field', 'vote_start_datetime', 'vote_end_date', 'general_questionnaires', 'course')\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\n        self.fields['name_de_field'].initial = self.instance.full_name_de\n        self.fields['name_en_field'].initial = self.instance.full_name_en\n\n        self.fields['general_questionnaires'].queryset = Questionnaire.objects.general_questionnaires().filter(\n            Q(visibility=Questionnaire.Visibility.EDITORS) | Q(contributions__evaluation=self.instance)).distinct()\n\n        self.fields['vote_start_datetime'].localize = True\n        self.fields['vote_end_date'].localize = True\n\n        if self.instance.general_contribution:\n            self.fields['general_questionnaires'].initial = [q.pk for q in self.instance.general_contribution.questionnaires.all()]\n\n        if not self.instance.allow_editors_to_edit:\n            for field in self._meta.fields:\n                self.fields[field].disabled = True\n\n    def clean(self):\n        super().clean()\n\n        vote_start_datetime = self.cleaned_data.get('vote_start_datetime')\n        vote_end_date = self.cleaned_data.get('vote_end_date')\n        if vote_start_datetime and vote_end_date:\n            if vote_start_datetime.date() > vote_end_date:\n                self.add_error(\"vote_start_datetime\", \"\")\n                self.add_error(\"vote_end_date\", _(\"The first day of evaluation must be before the last one.\"))\n\n    def clean_vote_end_date(self):\n        vote_end_date = self.cleaned_data.get('vote_end_date')\n\n        # The actual deadline is EVALUATION_END_OFFSET_HOURS:00 AM of the day after vote_end_date.\n        # Therefore an evaluation date 24h + EVALUATION_END_OFFSET_HOURS in the past would technically still be in the future.\n        if vote_end_date and date_to_datetime(vote_end_date) + timedelta(hours=24 + settings.EVALUATION_END_OFFSET_HOURS) < datetime.now():\n            raise forms.ValidationError(_(\"The last day of evaluation must be in the future.\"))\n        return vote_end_date\n\n    def clean_general_questionnaires(self):\n        # Ensure all locked questionnaires still have the same status (included or not)\n        locked_qs = self.fields['general_questionnaires'].queryset.filter(is_locked=True)\n\n        not_locked = [q for q in self.cleaned_data.get('general_questionnaires') if q not in locked_qs]\n        locked = [q.pk for q in self.instance.general_contribution.questionnaires.filter(is_locked=True)]\n\n        return not_locked + locked\n\n    def save(self, *args, **kw):\n        evaluation = super().save(*args, **kw)\n        evaluation.general_contribution.questionnaires.set(self.cleaned_data.get('general_questionnaires'))\n        return evaluation\n\n\nclass EditorContributionForm(ContributionForm):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\n        existing_contributor_pk = self.instance.contributor.pk if self.instance.contributor else None\n\n        self.fields['questionnaires'].queryset = Questionnaire.objects.contributor_questionnaires().filter(\n            Q(visibility=Questionnaire.Visibility.EDITORS) | Q(contributions__evaluation=self.evaluation)).distinct()\n        self.fields['contributor'].queryset = UserProfile.objects.filter(\n            (Q(is_active=True) & Q(is_proxy_user=False)) | Q(pk=existing_contributor_pk)\n        )\n\n\nclass DelegatesForm(forms.ModelForm):\n    delegates = UserModelMultipleChoiceField(queryset=UserProfile.objects.exclude(is_active=False).exclude(is_proxy_user=True),\n                                             required=False)\n\n    class Meta:\n        model = UserProfile\n        fields = ('delegates',)\n        field_classes = {\n            'delegates': UserModelMultipleChoiceField,\n        }\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\n    def save(self, *args, **kw):\n        super().save(*args, **kw)\n        logger.info('User \"{}\" edited the settings.'.format(self.instance.email))\n\n\nclass DelegateSelectionForm(forms.Form):\n    delegate_to = UserModelChoiceField(label=_(\"Delegate to\"),\n                                       queryset=UserProfile.objects.exclude(is_active=False).exclude(is_proxy_user=True))\n", "path": "evap/contributor/forms.py"}], "after_files": [{"content": "from datetime import datetime, timedelta\nimport logging\n\nfrom django import forms\nfrom django.conf import settings\nfrom django.db.models import Q\nfrom django.forms.widgets import CheckboxSelectMultiple\nfrom django.utils.translation import gettext_lazy as _\nfrom evap.evaluation.forms import UserModelMultipleChoiceField, UserModelChoiceField\nfrom evap.evaluation.models import Course, Evaluation, Questionnaire, UserProfile\nfrom evap.evaluation.tools import date_to_datetime\nfrom evap.staff.forms import ContributionForm\n\nlogger = logging.getLogger(__name__)\n\n\nclass EvaluationForm(forms.ModelForm):\n    general_questionnaires = forms.ModelMultipleChoiceField(queryset=None, required=False, widget=CheckboxSelectMultiple, label=_(\"General questionnaires\"))\n    course = forms.ModelChoiceField(Course.objects.all(), disabled=True, required=False, widget=forms.HiddenInput())\n    name_de_field = forms.CharField(label=_(\"Name (German)\"), disabled=True, required=False)\n    name_en_field = forms.CharField(label=_(\"Name (English)\"), disabled=True, required=False)\n\n    class Meta:\n        model = Evaluation\n        fields = ('name_de_field', 'name_en_field', 'vote_start_datetime', 'vote_end_date', 'general_questionnaires', 'course')\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\n        self.fields['name_de_field'].initial = self.instance.full_name_de\n        self.fields['name_en_field'].initial = self.instance.full_name_en\n\n        self.fields['general_questionnaires'].queryset = Questionnaire.objects.general_questionnaires().filter(\n            Q(visibility=Questionnaire.Visibility.EDITORS) | Q(contributions__evaluation=self.instance)).distinct()\n\n        self.fields['vote_start_datetime'].localize = True\n        self.fields['vote_end_date'].localize = True\n\n        if self.instance.general_contribution:\n            self.fields['general_questionnaires'].initial = [q.pk for q in self.instance.general_contribution.questionnaires.all()]\n\n        if not self.instance.allow_editors_to_edit:\n            for field in self._meta.fields:\n                self.fields[field].disabled = True\n\n    def clean(self):\n        super().clean()\n\n        vote_start_datetime = self.cleaned_data.get('vote_start_datetime')\n        vote_end_date = self.cleaned_data.get('vote_end_date')\n        if vote_start_datetime and vote_end_date:\n            if vote_start_datetime.date() > vote_end_date:\n                self.add_error(\"vote_start_datetime\", \"\")\n                self.add_error(\"vote_end_date\", _(\"The first day of evaluation must be before the last one.\"))\n\n    def clean_vote_end_date(self):\n        vote_end_date = self.cleaned_data.get('vote_end_date')\n\n        # The actual deadline is EVALUATION_END_OFFSET_HOURS:00 AM of the day after vote_end_date.\n        # Therefore an evaluation date 24h + EVALUATION_END_OFFSET_HOURS in the past would technically still be in the future.\n        if vote_end_date and date_to_datetime(vote_end_date) + timedelta(hours=24 + settings.EVALUATION_END_OFFSET_HOURS) < datetime.now():\n            raise forms.ValidationError(_(\"The last day of evaluation must be in the future.\"))\n        return vote_end_date\n\n    def clean_general_questionnaires(self):\n        # Ensure all locked questionnaires still have the same status (included or not)\n        not_locked = []\n        if self.cleaned_data.get('general_questionnaires'):\n            not_locked = list(self.cleaned_data.get('general_questionnaires').filter(is_locked=False))\n\n        locked = list(self.instance.general_contribution.questionnaires.filter(is_locked=True))\n\n        if not not_locked + locked:\n            self.add_error(\"general_questionnaires\", _(\"At least one questionnaire must be selected.\"))\n\n        return not_locked + locked\n\n    def save(self, *args, **kw):\n        evaluation = super().save(*args, **kw)\n        evaluation.general_contribution.questionnaires.set(self.cleaned_data.get('general_questionnaires'))\n        return evaluation\n\n\nclass EditorContributionForm(ContributionForm):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\n        existing_contributor_pk = self.instance.contributor.pk if self.instance.contributor else None\n\n        self.fields['questionnaires'].queryset = Questionnaire.objects.contributor_questionnaires().filter(\n            Q(visibility=Questionnaire.Visibility.EDITORS) | Q(contributions__evaluation=self.evaluation)).distinct()\n        self.fields['contributor'].queryset = UserProfile.objects.filter(\n            (Q(is_active=True) & Q(is_proxy_user=False)) | Q(pk=existing_contributor_pk)\n        )\n\n\nclass DelegatesForm(forms.ModelForm):\n    delegates = UserModelMultipleChoiceField(queryset=UserProfile.objects.exclude(is_active=False).exclude(is_proxy_user=True),\n                                             required=False)\n\n    class Meta:\n        model = UserProfile\n        fields = ('delegates',)\n        field_classes = {\n            'delegates': UserModelMultipleChoiceField,\n        }\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\n    def save(self, *args, **kw):\n        super().save(*args, **kw)\n        logger.info('User \"{}\" edited the settings.'.format(self.instance.email))\n\n\nclass DelegateSelectionForm(forms.Form):\n    delegate_to = UserModelChoiceField(label=_(\"Delegate to\"),\n                                       queryset=UserProfile.objects.exclude(is_active=False).exclude(is_proxy_user=True))\n", "path": "evap/contributor/forms.py"}]}