We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Community Roles: Date range validation
Currently, an end date earlier than start date is allowed.  

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `amy/communityroles/forms.py`
Content:
```
1 from collections import defaultdict
2 from typing import Any, Optional
3 
4 from django import forms
5 from django.core.exceptions import ObjectDoesNotExist, ValidationError
6 
7 from workshops.fields import HeavySelect2Widget, ModelSelect2Widget
8 from workshops.forms import SELECT2_SIDEBAR, BootstrapHelper, WidgetOverrideMixin
9 
10 from .models import CommunityRole, CommunityRoleConfig
11 
12 
13 class CommunityRoleForm(WidgetOverrideMixin, forms.ModelForm):
14     class Meta:
15         model = CommunityRole
16         fields = (
17             "config",
18             "person",
19             "award",
20             "start",
21             "end",
22             "inactivation",
23             "membership",
24             "url",
25             "generic_relation_content_type",
26             "generic_relation_pk",
27         )
28         widgets = {
29             "config": HeavySelect2Widget(
30                 data_view="api:communityroleconfig-list", attrs=SELECT2_SIDEBAR
31             ),
32             "person": ModelSelect2Widget(
33                 data_view="person-lookup", attrs=SELECT2_SIDEBAR
34             ),
35             "award": ModelSelect2Widget(
36                 data_view="award-lookup", attrs=SELECT2_SIDEBAR
37             ),
38             "membership": ModelSelect2Widget(
39                 data_view="membership-lookup", attrs=SELECT2_SIDEBAR
40             ),
41             "generic_relation_content_type": forms.Select(
42                 # "disabled" means the browsers will not send the field during POST.
43                 # See how it's handled in `clean()` method below.
44                 attrs={"disabled": ""},
45             ),
46             "generic_relation_pk": HeavySelect2Widget(
47                 data_view="generic-object-lookup", attrs=SELECT2_SIDEBAR
48             ),
49         }
50         labels = {
51             "generic_relation_content_type": "Generic relation object type",
52             "generic_relation_pk": "Generic relation object",
53         }
54 
55     class Media:
56         js = ("communityrole_form.js",)
57 
58     def __init__(self, *args, **kwargs):
59         form_tag = kwargs.pop("form_tag", True)
60         super().__init__(*args, **kwargs)
61         bootstrap_kwargs = {
62             "add_cancel_button": False,
63             "form_tag": form_tag,
64         }
65         self.helper = BootstrapHelper(**bootstrap_kwargs)
66 
67     def clean(self) -> dict[str, Any]:
68         """Validate form according to rules set up in related Community Role
69         configuration."""
70         cleaned_data = super().clean()
71         errors: defaultdict[str, list[ValidationError]] = defaultdict(list)
72         config: Optional[CommunityRoleConfig] = cleaned_data.get("config")
73 
74         # Config is required, but field validation for 'config' should raise
75         # validation error first.
76         if not config:
77             return cleaned_data
78 
79         # Award required?
80         if config.link_to_award and not cleaned_data.get("award"):
81             errors["award"].append(
82                 ValidationError(f"Award is required with community role {config}")
83             )
84 
85         # Specific award badge required?
86         if (badge := config.award_badge_limit) and (award := cleaned_data.get("award")):
87             if award.badge != badge:
88                 errors["award"].append(
89                     ValidationError(
90                         f"Award badge must be {badge} for community role {config}"
91                     )
92                 )
93 
94         # Membership required?
95         if config.link_to_membership and not cleaned_data.get("membership"):
96             errors["membership"].append(
97                 ValidationError(f"Membership is required with community role {config}")
98             )
99 
100         # Additional URL supported?
101         if not config.additional_url and cleaned_data.get("url"):
102             errors["url"].append(
103                 ValidationError(f"URL is not supported for community role {config}")
104             )
105 
106         # Widget for `generic_relation_content_type` is disabled in HTML, which
107         # makes browsers not send it. The code below sets the default value to
108         # the same value as in related config.
109         generic_relation_content_type = config.generic_relation_content_type
110 
111         # Generic relation object must exist
112         if config.generic_relation_content_type and generic_relation_content_type:
113             model_class = generic_relation_content_type.model_class()
114             try:
115                 model_class._base_manager.get(
116                     pk=cleaned_data.get("generic_relation_pk")
117                 )
118             except ObjectDoesNotExist:
119                 errors["generic_relation_pk"].append(
120                     ValidationError(
121                         f"Generic relation object of model {model_class.__name__} "
122                         "doesn't exist"
123                     )
124                 )
125 
126         if errors:
127             raise ValidationError(errors)
128 
129         return cleaned_data
130
```
--- 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/amy/communityroles/forms.py b/amy/communityroles/forms.py
--- a/amy/communityroles/forms.py
+++ b/amy/communityroles/forms.py
@@ -127,3 +127,11 @@
             raise ValidationError(errors)
 
         return cleaned_data
+
+    def clean_end(self):
+        """Validate that end >= start"""
+        start = self.cleaned_data.get("start")
+        end = self.cleaned_data.get("end")
+        if start and end and end < start:
+            raise ValidationError("Must not be earlier than start date.")
+        return end

{"golden_diff": "diff --git a/amy/communityroles/forms.py b/amy/communityroles/forms.py\n--- a/amy/communityroles/forms.py\n+++ b/amy/communityroles/forms.py\n@@ -127,3 +127,11 @@\n             raise ValidationError(errors)\n \n         return cleaned_data\n+\n+    def clean_end(self):\n+        \"\"\"Validate that end >= start\"\"\"\n+        start = self.cleaned_data.get(\"start\")\n+        end = self.cleaned_data.get(\"end\")\n+        if start and end and end < start:\n+            raise ValidationError(\"Must not be earlier than start date.\")\n+        return end\n", "issue": "Community Roles: Date range validation\nCurrently, an end date earlier than start date is allowed.  \n", "before_files": [{"content": "from collections import defaultdict\nfrom typing import Any, Optional\n\nfrom django import forms\nfrom django.core.exceptions import ObjectDoesNotExist, ValidationError\n\nfrom workshops.fields import HeavySelect2Widget, ModelSelect2Widget\nfrom workshops.forms import SELECT2_SIDEBAR, BootstrapHelper, WidgetOverrideMixin\n\nfrom .models import CommunityRole, CommunityRoleConfig\n\n\nclass CommunityRoleForm(WidgetOverrideMixin, forms.ModelForm):\n    class Meta:\n        model = CommunityRole\n        fields = (\n            \"config\",\n            \"person\",\n            \"award\",\n            \"start\",\n            \"end\",\n            \"inactivation\",\n            \"membership\",\n            \"url\",\n            \"generic_relation_content_type\",\n            \"generic_relation_pk\",\n        )\n        widgets = {\n            \"config\": HeavySelect2Widget(\n                data_view=\"api:communityroleconfig-list\", attrs=SELECT2_SIDEBAR\n            ),\n            \"person\": ModelSelect2Widget(\n                data_view=\"person-lookup\", attrs=SELECT2_SIDEBAR\n            ),\n            \"award\": ModelSelect2Widget(\n                data_view=\"award-lookup\", attrs=SELECT2_SIDEBAR\n            ),\n            \"membership\": ModelSelect2Widget(\n                data_view=\"membership-lookup\", attrs=SELECT2_SIDEBAR\n            ),\n            \"generic_relation_content_type\": forms.Select(\n                # \"disabled\" means the browsers will not send the field during POST.\n                # See how it's handled in `clean()` method below.\n                attrs={\"disabled\": \"\"},\n            ),\n            \"generic_relation_pk\": HeavySelect2Widget(\n                data_view=\"generic-object-lookup\", attrs=SELECT2_SIDEBAR\n            ),\n        }\n        labels = {\n            \"generic_relation_content_type\": \"Generic relation object type\",\n            \"generic_relation_pk\": \"Generic relation object\",\n        }\n\n    class Media:\n        js = (\"communityrole_form.js\",)\n\n    def __init__(self, *args, **kwargs):\n        form_tag = kwargs.pop(\"form_tag\", True)\n        super().__init__(*args, **kwargs)\n        bootstrap_kwargs = {\n            \"add_cancel_button\": False,\n            \"form_tag\": form_tag,\n        }\n        self.helper = BootstrapHelper(**bootstrap_kwargs)\n\n    def clean(self) -> dict[str, Any]:\n        \"\"\"Validate form according to rules set up in related Community Role\n        configuration.\"\"\"\n        cleaned_data = super().clean()\n        errors: defaultdict[str, list[ValidationError]] = defaultdict(list)\n        config: Optional[CommunityRoleConfig] = cleaned_data.get(\"config\")\n\n        # Config is required, but field validation for 'config' should raise\n        # validation error first.\n        if not config:\n            return cleaned_data\n\n        # Award required?\n        if config.link_to_award and not cleaned_data.get(\"award\"):\n            errors[\"award\"].append(\n                ValidationError(f\"Award is required with community role {config}\")\n            )\n\n        # Specific award badge required?\n        if (badge := config.award_badge_limit) and (award := cleaned_data.get(\"award\")):\n            if award.badge != badge:\n                errors[\"award\"].append(\n                    ValidationError(\n                        f\"Award badge must be {badge} for community role {config}\"\n                    )\n                )\n\n        # Membership required?\n        if config.link_to_membership and not cleaned_data.get(\"membership\"):\n            errors[\"membership\"].append(\n                ValidationError(f\"Membership is required with community role {config}\")\n            )\n\n        # Additional URL supported?\n        if not config.additional_url and cleaned_data.get(\"url\"):\n            errors[\"url\"].append(\n                ValidationError(f\"URL is not supported for community role {config}\")\n            )\n\n        # Widget for `generic_relation_content_type` is disabled in HTML, which\n        # makes browsers not send it. The code below sets the default value to\n        # the same value as in related config.\n        generic_relation_content_type = config.generic_relation_content_type\n\n        # Generic relation object must exist\n        if config.generic_relation_content_type and generic_relation_content_type:\n            model_class = generic_relation_content_type.model_class()\n            try:\n                model_class._base_manager.get(\n                    pk=cleaned_data.get(\"generic_relation_pk\")\n                )\n            except ObjectDoesNotExist:\n                errors[\"generic_relation_pk\"].append(\n                    ValidationError(\n                        f\"Generic relation object of model {model_class.__name__} \"\n                        \"doesn't exist\"\n                    )\n                )\n\n        if errors:\n            raise ValidationError(errors)\n\n        return cleaned_data\n", "path": "amy/communityroles/forms.py"}], "after_files": [{"content": "from collections import defaultdict\nfrom typing import Any, Optional\n\nfrom django import forms\nfrom django.core.exceptions import ObjectDoesNotExist, ValidationError\n\nfrom workshops.fields import HeavySelect2Widget, ModelSelect2Widget\nfrom workshops.forms import SELECT2_SIDEBAR, BootstrapHelper, WidgetOverrideMixin\n\nfrom .models import CommunityRole, CommunityRoleConfig\n\n\nclass CommunityRoleForm(WidgetOverrideMixin, forms.ModelForm):\n    class Meta:\n        model = CommunityRole\n        fields = (\n            \"config\",\n            \"person\",\n            \"award\",\n            \"start\",\n            \"end\",\n            \"inactivation\",\n            \"membership\",\n            \"url\",\n            \"generic_relation_content_type\",\n            \"generic_relation_pk\",\n        )\n        widgets = {\n            \"config\": HeavySelect2Widget(\n                data_view=\"api:communityroleconfig-list\", attrs=SELECT2_SIDEBAR\n            ),\n            \"person\": ModelSelect2Widget(\n                data_view=\"person-lookup\", attrs=SELECT2_SIDEBAR\n            ),\n            \"award\": ModelSelect2Widget(\n                data_view=\"award-lookup\", attrs=SELECT2_SIDEBAR\n            ),\n            \"membership\": ModelSelect2Widget(\n                data_view=\"membership-lookup\", attrs=SELECT2_SIDEBAR\n            ),\n            \"generic_relation_content_type\": forms.Select(\n                # \"disabled\" means the browsers will not send the field during POST.\n                # See how it's handled in `clean()` method below.\n                attrs={\"disabled\": \"\"},\n            ),\n            \"generic_relation_pk\": HeavySelect2Widget(\n                data_view=\"generic-object-lookup\", attrs=SELECT2_SIDEBAR\n            ),\n        }\n        labels = {\n            \"generic_relation_content_type\": \"Generic relation object type\",\n            \"generic_relation_pk\": \"Generic relation object\",\n        }\n\n    class Media:\n        js = (\"communityrole_form.js\",)\n\n    def __init__(self, *args, **kwargs):\n        form_tag = kwargs.pop(\"form_tag\", True)\n        super().__init__(*args, **kwargs)\n        bootstrap_kwargs = {\n            \"add_cancel_button\": False,\n            \"form_tag\": form_tag,\n        }\n        self.helper = BootstrapHelper(**bootstrap_kwargs)\n\n    def clean(self) -> dict[str, Any]:\n        \"\"\"Validate form according to rules set up in related Community Role\n        configuration.\"\"\"\n        cleaned_data = super().clean()\n        errors: defaultdict[str, list[ValidationError]] = defaultdict(list)\n        config: Optional[CommunityRoleConfig] = cleaned_data.get(\"config\")\n\n        # Config is required, but field validation for 'config' should raise\n        # validation error first.\n        if not config:\n            return cleaned_data\n\n        # Award required?\n        if config.link_to_award and not cleaned_data.get(\"award\"):\n            errors[\"award\"].append(\n                ValidationError(f\"Award is required with community role {config}\")\n            )\n\n        # Specific award badge required?\n        if (badge := config.award_badge_limit) and (award := cleaned_data.get(\"award\")):\n            if award.badge != badge:\n                errors[\"award\"].append(\n                    ValidationError(\n                        f\"Award badge must be {badge} for community role {config}\"\n                    )\n                )\n\n        # Membership required?\n        if config.link_to_membership and not cleaned_data.get(\"membership\"):\n            errors[\"membership\"].append(\n                ValidationError(f\"Membership is required with community role {config}\")\n            )\n\n        # Additional URL supported?\n        if not config.additional_url and cleaned_data.get(\"url\"):\n            errors[\"url\"].append(\n                ValidationError(f\"URL is not supported for community role {config}\")\n            )\n\n        # Widget for `generic_relation_content_type` is disabled in HTML, which\n        # makes browsers not send it. The code below sets the default value to\n        # the same value as in related config.\n        generic_relation_content_type = config.generic_relation_content_type\n\n        # Generic relation object must exist\n        if config.generic_relation_content_type and generic_relation_content_type:\n            model_class = generic_relation_content_type.model_class()\n            try:\n                model_class._base_manager.get(\n                    pk=cleaned_data.get(\"generic_relation_pk\")\n                )\n            except ObjectDoesNotExist:\n                errors[\"generic_relation_pk\"].append(\n                    ValidationError(\n                        f\"Generic relation object of model {model_class.__name__} \"\n                        \"doesn't exist\"\n                    )\n                )\n\n        if errors:\n            raise ValidationError(errors)\n\n        return cleaned_data\n\n    def clean_end(self):\n        \"\"\"Validate that end >= start\"\"\"\n        start = self.cleaned_data.get(\"start\")\n        end = self.cleaned_data.get(\"end\")\n        if start and end and end < start:\n            raise ValidationError(\"Must not be earlier than start date.\")\n        return end\n", "path": "amy/communityroles/forms.py"}]}