prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Add cancelled registrations to event in api v2
  ### Is your feature request related to a problem? Please describe.
  API v2 doesn't return a cancelled registration when you've cancelled a registration (in the event serializer). So we cannot display stuff like 'Your registration is cancelled (after the deadline)'.
  
  ### Describe the solution you'd like
  Also return a registration if it's cancelled, and include fields like is_cancelled, is_late_cancellation, etc.
  
  ### Motivation
  This makes it possible to show nice status texts like in the old app and the website.
  
  ### Describe alternatives you've considered
  Leaving out the messages for cancelled registrations. In that case, you can only see that there is no register button, but not why.
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `website/events/api/v2/serializers/event_registration.py`
  Content:
  ```
  1 from rest_framework import serializers
  2 
  3 from events.models import EventRegistration
  4 from members.api.v2.serializers.member import MemberSerializer
  5 from payments.api.v2.serializers import PaymentSerializer
  6 
  7 
  8 class EventRegistrationSerializer(serializers.ModelSerializer):
  9     """Serializer for event registrations."""
  10 
  11     def __init__(self, *args, **kwargs):
  12         # Don't pass the 'fields' arg up to the superclass
  13         fields = kwargs.pop("fields", {"pk", "member", "name"})
  14 
  15         # Instantiate the superclass normally
  16         super().__init__(*args, **kwargs)
  17 
  18         allowed = set(fields)
  19         existing = set(self.fields.keys())
  20         for field_name in existing - allowed:
  21             self.fields.pop(field_name)
  22 
  23     class Meta:
  24         model = EventRegistration
  25         fields = (
  26             "pk",
  27             "present",
  28             "queue_position",
  29             "date",
  30             "payment",
  31             "member",
  32             "name",
  33         )
  34 
  35     payment = PaymentSerializer()
  36     member = MemberSerializer(detailed=False, read_only=True)
  37
  ```
  
  Path: `website/events/api/v2/serializers/event.py`
  Content:
  ```
  1 from rest_framework import serializers
  2 
  3 from activemembers.api.v2.serializers.member_group import MemberGroupSerializer
  4 from announcements.api.v2.serializers import SlideSerializer
  5 from documents.api.v2.serializers.document import DocumentSerializer
  6 from events import services
  7 from events.api.v2.serializers.event_registration import EventRegistrationSerializer
  8 from events.models import Event, EventRegistration
  9 from thaliawebsite.api.v2.serializers import CleanedHTMLSerializer
  10 from utils.snippets import create_google_maps_url
  11 
  12 
  13 class EventSerializer(serializers.ModelSerializer):
  14     """Serializer for events."""
  15 
  16     class Meta:
  17         model = Event
  18         fields = (
  19             "pk",
  20             "title",
  21             "description",
  22             "start",
  23             "end",
  24             "category",
  25             "registration_start",
  26             "registration_end",
  27             "cancel_deadline",
  28             "optional_registrations",
  29             "location",
  30             "price",
  31             "fine",
  32             "num_participants",
  33             "max_participants",
  34             "no_registration_message",
  35             "cancel_too_late_message",
  36             "has_fields",
  37             "food_event",
  38             "maps_url",
  39             "user_permissions",
  40             "user_registration",
  41             "organiser",
  42             "slide",
  43             "documents",
  44         )
  45 
  46     description = CleanedHTMLSerializer()
  47     organiser = MemberGroupSerializer()
  48     user_registration = serializers.SerializerMethodField("_user_registration")
  49     num_participants = serializers.SerializerMethodField("_num_participants")
  50     maps_url = serializers.SerializerMethodField("_maps_url")
  51     price = serializers.DecimalField(max_digits=5, decimal_places=2)
  52     fine = serializers.DecimalField(max_digits=5, decimal_places=2)
  53     slide = SlideSerializer()
  54     documents = DocumentSerializer(many=True)
  55     user_permissions = serializers.SerializerMethodField("_user_permissions")
  56 
  57     def _user_registration(self, instance):
  58         try:
  59             if self.context["request"].member:
  60                 reg = instance.eventregistration_set.get(
  61                     member=self.context["request"].member, date_cancelled=None
  62                 )
  63                 return EventRegistrationSerializer(
  64                     reg,
  65                     context=self.context,
  66                     fields=("pk", "present", "queue_position", "date", "payment"),
  67                 ).data
  68         except EventRegistration.DoesNotExist:
  69             pass
  70         return None
  71 
  72     def _num_participants(self, instance):
  73         if (
  74             instance.max_participants
  75             and instance.participants.count() > instance.max_participants
  76         ):
  77             return instance.max_participants
  78         return instance.participants.count()
  79 
  80     def _user_permissions(self, instance):
  81         member = self.context["request"].member
  82         return services.event_permissions(member, instance)
  83 
  84     def _maps_url(self, instance):
  85         return create_google_maps_url(instance.map_location, zoom=13, size="450x250")
  86
  ```
  --- 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()
  
  ```
  
golden_diff: diff --git a/website/events/api/v2/serializers/event.py b/website/events/api/v2/serializers/event.py
  --- a/website/events/api/v2/serializers/event.py
  +++ b/website/events/api/v2/serializers/event.py
  @@ -58,12 +58,20 @@
           try:
               if self.context["request"].member:
                   reg = instance.eventregistration_set.get(
  -                    member=self.context["request"].member, date_cancelled=None
  +                    member=self.context["request"].member
                   )
                   return EventRegistrationSerializer(
                       reg,
                       context=self.context,
  -                    fields=("pk", "present", "queue_position", "date", "payment"),
  +                    fields=(
  +                        "pk",
  +                        "present",
  +                        "queue_position",
  +                        "is_cancelled",
  +                        "is_late_cancellation",
  +                        "date",
  +                        "payment",
  +                    ),
                   ).data
           except EventRegistration.DoesNotExist:
               pass
  diff --git a/website/events/api/v2/serializers/event_registration.py b/website/events/api/v2/serializers/event_registration.py
  --- a/website/events/api/v2/serializers/event_registration.py
  +++ b/website/events/api/v2/serializers/event_registration.py
  @@ -34,3 +34,16 @@
   
       payment = PaymentSerializer()
       member = MemberSerializer(detailed=False, read_only=True)
  +    is_cancelled = serializers.SerializerMethodField("_is_cancelled")
  +    is_late_cancellation = serializers.SerializerMethodField("_is_late_cancellation")
  +    queue_position = serializers.SerializerMethodField("_queue_position")
  +
  +    def _is_late_cancellation(self, instance):
  +        return instance.is_late_cancellation()
  +
  +    def _queue_position(self, instance):
  +        pos = instance.queue_position
  +        return pos if pos and pos > 0 else None
  +
  +    def _is_cancelled(self, instance):
  +        return instance.date_cancelled is not None
  
verification_info: {"golden_diff": "diff --git a/website/events/api/v2/serializers/event.py b/website/events/api/v2/serializers/event.py\n--- a/website/events/api/v2/serializers/event.py\n+++ b/website/events/api/v2/serializers/event.py\n@@ -58,12 +58,20 @@\n         try:\n             if self.context[\"request\"].member:\n                 reg = instance.eventregistration_set.get(\n-                    member=self.context[\"request\"].member, date_cancelled=None\n+                    member=self.context[\"request\"].member\n                 )\n                 return EventRegistrationSerializer(\n                     reg,\n                     context=self.context,\n-                    fields=(\"pk\", \"present\", \"queue_position\", \"date\", \"payment\"),\n+                    fields=(\n+                        \"pk\",\n+                        \"present\",\n+                        \"queue_position\",\n+                        \"is_cancelled\",\n+                        \"is_late_cancellation\",\n+                        \"date\",\n+                        \"payment\",\n+                    ),\n                 ).data\n         except EventRegistration.DoesNotExist:\n             pass\ndiff --git a/website/events/api/v2/serializers/event_registration.py b/website/events/api/v2/serializers/event_registration.py\n--- a/website/events/api/v2/serializers/event_registration.py\n+++ b/website/events/api/v2/serializers/event_registration.py\n@@ -34,3 +34,16 @@\n \n     payment = PaymentSerializer()\n     member = MemberSerializer(detailed=False, read_only=True)\n+    is_cancelled = serializers.SerializerMethodField(\"_is_cancelled\")\n+    is_late_cancellation = serializers.SerializerMethodField(\"_is_late_cancellation\")\n+    queue_position = serializers.SerializerMethodField(\"_queue_position\")\n+\n+    def _is_late_cancellation(self, instance):\n+        return instance.is_late_cancellation()\n+\n+    def _queue_position(self, instance):\n+        pos = instance.queue_position\n+        return pos if pos and pos > 0 else None\n+\n+    def _is_cancelled(self, instance):\n+        return instance.date_cancelled is not None\n", "issue": "Add cancelled registrations to event in api v2\n### Is your feature request related to a problem? Please describe.\r\nAPI v2 doesn't return a cancelled registration when you've cancelled a registration (in the event serializer). So we cannot display stuff like 'Your registration is cancelled (after the deadline)'.\r\n\r\n### Describe the solution you'd like\r\nAlso return a registration if it's cancelled, and include fields like is_cancelled, is_late_cancellation, etc.\r\n\r\n### Motivation\r\nThis makes it possible to show nice status texts like in the old app and the website.\r\n\r\n### Describe alternatives you've considered\r\nLeaving out the messages for cancelled registrations. In that case, you can only see that there is no register button, but not why.\r\n\n", "before_files": [{"content": "from rest_framework import serializers\n\nfrom events.models import EventRegistration\nfrom members.api.v2.serializers.member import MemberSerializer\nfrom payments.api.v2.serializers import PaymentSerializer\n\n\nclass EventRegistrationSerializer(serializers.ModelSerializer):\n    \"\"\"Serializer for event registrations.\"\"\"\n\n    def __init__(self, *args, **kwargs):\n        # Don't pass the 'fields' arg up to the superclass\n        fields = kwargs.pop(\"fields\", {\"pk\", \"member\", \"name\"})\n\n        # Instantiate the superclass normally\n        super().__init__(*args, **kwargs)\n\n        allowed = set(fields)\n        existing = set(self.fields.keys())\n        for field_name in existing - allowed:\n            self.fields.pop(field_name)\n\n    class Meta:\n        model = EventRegistration\n        fields = (\n            \"pk\",\n            \"present\",\n            \"queue_position\",\n            \"date\",\n            \"payment\",\n            \"member\",\n            \"name\",\n        )\n\n    payment = PaymentSerializer()\n    member = MemberSerializer(detailed=False, read_only=True)\n", "path": "website/events/api/v2/serializers/event_registration.py"}, {"content": "from rest_framework import serializers\n\nfrom activemembers.api.v2.serializers.member_group import MemberGroupSerializer\nfrom announcements.api.v2.serializers import SlideSerializer\nfrom documents.api.v2.serializers.document import DocumentSerializer\nfrom events import services\nfrom events.api.v2.serializers.event_registration import EventRegistrationSerializer\nfrom events.models import Event, EventRegistration\nfrom thaliawebsite.api.v2.serializers import CleanedHTMLSerializer\nfrom utils.snippets import create_google_maps_url\n\n\nclass EventSerializer(serializers.ModelSerializer):\n    \"\"\"Serializer for events.\"\"\"\n\n    class Meta:\n        model = Event\n        fields = (\n            \"pk\",\n            \"title\",\n            \"description\",\n            \"start\",\n            \"end\",\n            \"category\",\n            \"registration_start\",\n            \"registration_end\",\n            \"cancel_deadline\",\n            \"optional_registrations\",\n            \"location\",\n            \"price\",\n            \"fine\",\n            \"num_participants\",\n            \"max_participants\",\n            \"no_registration_message\",\n            \"cancel_too_late_message\",\n            \"has_fields\",\n            \"food_event\",\n            \"maps_url\",\n            \"user_permissions\",\n            \"user_registration\",\n            \"organiser\",\n            \"slide\",\n            \"documents\",\n        )\n\n    description = CleanedHTMLSerializer()\n    organiser = MemberGroupSerializer()\n    user_registration = serializers.SerializerMethodField(\"_user_registration\")\n    num_participants = serializers.SerializerMethodField(\"_num_participants\")\n    maps_url = serializers.SerializerMethodField(\"_maps_url\")\n    price = serializers.DecimalField(max_digits=5, decimal_places=2)\n    fine = serializers.DecimalField(max_digits=5, decimal_places=2)\n    slide = SlideSerializer()\n    documents = DocumentSerializer(many=True)\n    user_permissions = serializers.SerializerMethodField(\"_user_permissions\")\n\n    def _user_registration(self, instance):\n        try:\n            if self.context[\"request\"].member:\n                reg = instance.eventregistration_set.get(\n                    member=self.context[\"request\"].member, date_cancelled=None\n                )\n                return EventRegistrationSerializer(\n                    reg,\n                    context=self.context,\n                    fields=(\"pk\", \"present\", \"queue_position\", \"date\", \"payment\"),\n                ).data\n        except EventRegistration.DoesNotExist:\n            pass\n        return None\n\n    def _num_participants(self, instance):\n        if (\n            instance.max_participants\n            and instance.participants.count() > instance.max_participants\n        ):\n            return instance.max_participants\n        return instance.participants.count()\n\n    def _user_permissions(self, instance):\n        member = self.context[\"request\"].member\n        return services.event_permissions(member, instance)\n\n    def _maps_url(self, instance):\n        return create_google_maps_url(instance.map_location, zoom=13, size=\"450x250\")\n", "path": "website/events/api/v2/serializers/event.py"}], "after_files": [{"content": "from rest_framework import serializers\n\nfrom events.models import EventRegistration\nfrom members.api.v2.serializers.member import MemberSerializer\nfrom payments.api.v2.serializers import PaymentSerializer\n\n\nclass EventRegistrationSerializer(serializers.ModelSerializer):\n    \"\"\"Serializer for event registrations.\"\"\"\n\n    def __init__(self, *args, **kwargs):\n        # Don't pass the 'fields' arg up to the superclass\n        fields = kwargs.pop(\"fields\", {\"pk\", \"member\", \"name\"})\n\n        # Instantiate the superclass normally\n        super().__init__(*args, **kwargs)\n\n        allowed = set(fields)\n        existing = set(self.fields.keys())\n        for field_name in existing - allowed:\n            self.fields.pop(field_name)\n\n    class Meta:\n        model = EventRegistration\n        fields = (\n            \"pk\",\n            \"present\",\n            \"queue_position\",\n            \"date\",\n            \"payment\",\n            \"member\",\n            \"name\",\n        )\n\n    payment = PaymentSerializer()\n    member = MemberSerializer(detailed=False, read_only=True)\n    is_cancelled = serializers.SerializerMethodField(\"_is_cancelled\")\n    is_late_cancellation = serializers.SerializerMethodField(\"_is_late_cancellation\")\n    queue_position = serializers.SerializerMethodField(\"_queue_position\")\n\n    def _is_late_cancellation(self, instance):\n        return instance.is_late_cancellation()\n\n    def _queue_position(self, instance):\n        pos = instance.queue_position\n        return pos if pos and pos > 0 else None\n\n    def _is_cancelled(self, instance):\n        return instance.date_cancelled is not None\n", "path": "website/events/api/v2/serializers/event_registration.py"}, {"content": "from rest_framework import serializers\n\nfrom activemembers.api.v2.serializers.member_group import MemberGroupSerializer\nfrom announcements.api.v2.serializers import SlideSerializer\nfrom documents.api.v2.serializers.document import DocumentSerializer\nfrom events import services\nfrom events.api.v2.serializers.event_registration import EventRegistrationSerializer\nfrom events.models import Event, EventRegistration\nfrom thaliawebsite.api.v2.serializers import CleanedHTMLSerializer\nfrom utils.snippets import create_google_maps_url\n\n\nclass EventSerializer(serializers.ModelSerializer):\n    \"\"\"Serializer for events.\"\"\"\n\n    class Meta:\n        model = Event\n        fields = (\n            \"pk\",\n            \"title\",\n            \"description\",\n            \"start\",\n            \"end\",\n            \"category\",\n            \"registration_start\",\n            \"registration_end\",\n            \"cancel_deadline\",\n            \"optional_registrations\",\n            \"location\",\n            \"price\",\n            \"fine\",\n            \"num_participants\",\n            \"max_participants\",\n            \"no_registration_message\",\n            \"cancel_too_late_message\",\n            \"has_fields\",\n            \"food_event\",\n            \"maps_url\",\n            \"user_permissions\",\n            \"user_registration\",\n            \"organiser\",\n            \"slide\",\n            \"documents\",\n        )\n\n    description = CleanedHTMLSerializer()\n    organiser = MemberGroupSerializer()\n    user_registration = serializers.SerializerMethodField(\"_user_registration\")\n    num_participants = serializers.SerializerMethodField(\"_num_participants\")\n    maps_url = serializers.SerializerMethodField(\"_maps_url\")\n    price = serializers.DecimalField(max_digits=5, decimal_places=2)\n    fine = serializers.DecimalField(max_digits=5, decimal_places=2)\n    slide = SlideSerializer()\n    documents = DocumentSerializer(many=True)\n    user_permissions = serializers.SerializerMethodField(\"_user_permissions\")\n\n    def _user_registration(self, instance):\n        try:\n            if self.context[\"request\"].member:\n                reg = instance.eventregistration_set.get(\n                    member=self.context[\"request\"].member\n                )\n                return EventRegistrationSerializer(\n                    reg,\n                    context=self.context,\n                    fields=(\n                        \"pk\",\n                        \"present\",\n                        \"queue_position\",\n                        \"is_cancelled\",\n                        \"is_late_cancellation\",\n                        \"date\",\n                        \"payment\",\n                    ),\n                ).data\n        except EventRegistration.DoesNotExist:\n            pass\n        return None\n\n    def _num_participants(self, instance):\n        if (\n            instance.max_participants\n            and instance.participants.count() > instance.max_participants\n        ):\n            return instance.max_participants\n        return instance.participants.count()\n\n    def _user_permissions(self, instance):\n        member = self.context[\"request\"].member\n        return services.event_permissions(member, instance)\n\n    def _maps_url(self, instance):\n        return create_google_maps_url(instance.map_location, zoom=13, size=\"450x250\")\n", "path": "website/events/api/v2/serializers/event.py"}]}