prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Add API endpoint for event slugs
  ### Is your feature request related to a problem? Please describe.
  For the app we want to get events based on their slug, this is currently not possible.
  
  ### Describe the solution you'd like
  Add an API endpoint for event slugs.
  
  
  </issue>
  <code>
  [start of website/events/api/v2/urls.py]
  1 """Events app API v2 urls."""
  2 from django.urls import path
  3 
  4 from events.api.v2.views import (
  5     EventDetailView,
  6     EventListView,
  7     EventRegistrationDetailView,
  8     EventRegistrationFieldsView,
  9     EventRegistrationsView,
  10     ExternalEventDetailView,
  11     ExternalEventListView,
  12     MarkPresentAPIView,
  13 )
  14 
  15 app_name = "events"
  16 
  17 urlpatterns = [
  18     path("events/", EventListView.as_view(), name="events-list"),
  19     path(
  20         "events/<int:pk>/",
  21         EventDetailView.as_view(),
  22         name="event-detail",
  23     ),
  24     path(
  25         "events/<int:pk>/registrations/",
  26         EventRegistrationsView.as_view(),
  27         name="event-registrations",
  28     ),
  29     path(
  30         "events/<int:event_id>/registrations/<int:pk>/",
  31         EventRegistrationDetailView.as_view(),
  32         name="event-registration-detail",
  33     ),
  34     path(
  35         "events/<int:event_id>/registrations/<int:registration_id>/fields/",
  36         EventRegistrationFieldsView.as_view(),
  37         name="event-registration-fields",
  38     ),
  39     path(
  40         "events/<int:pk>/mark-present/<uuid:token>/",
  41         MarkPresentAPIView.as_view(),
  42         name="mark-present",
  43     ),
  44     path(
  45         "events/external/", ExternalEventListView.as_view(), name="external-events-list"
  46     ),
  47     path(
  48         "events/external/<int:pk>/",
  49         ExternalEventDetailView.as_view(),
  50         name="external-event-detail",
  51     ),
  52 ]
  53
  [end of website/events/api/v2/urls.py]
  [start of website/events/api/v2/serializers/event.py]
  1 from rest_framework import serializers
  2 
  3 from activemembers.api.v2.serializers.member_group import MemberGroupSerializer
  4 from documents.api.v2.serializers.document import DocumentSerializer
  5 from events import services
  6 from events.api.v2.serializers.event_registration import EventRegistrationSerializer
  7 from events.models import Event
  8 from payments.api.v2.serializers.payment_amount import PaymentAmountSerializer
  9 from thaliawebsite.api.v2.serializers import CleanedHTMLSerializer
  10 from thaliawebsite.api.v2.serializers.cleaned_model_serializer import (
  11     CleanedModelSerializer,
  12 )
  13 from utils.snippets import create_google_maps_url
  14 
  15 
  16 class EventSerializer(CleanedModelSerializer):
  17     """Serializer for events."""
  18 
  19     class Meta:
  20         model = Event
  21         fields = (
  22             "pk",
  23             "title",
  24             "description",
  25             "caption",
  26             "start",
  27             "end",
  28             "category",
  29             "registration_start",
  30             "registration_end",
  31             "cancel_deadline",
  32             "optional_registrations",
  33             "location",
  34             "price",
  35             "fine",
  36             "num_participants",
  37             "max_participants",
  38             "no_registration_message",
  39             "registration_status",
  40             "cancel_too_late_message",
  41             "has_fields",
  42             "food_event",
  43             "maps_url",
  44             "user_permissions",
  45             "user_registration",
  46             "organisers",
  47             "documents",
  48         )
  49 
  50     description = CleanedHTMLSerializer()
  51     organisers = MemberGroupSerializer(many=True)
  52     user_registration = serializers.SerializerMethodField("_user_registration")
  53     num_participants = serializers.SerializerMethodField("_num_participants")
  54     maps_url = serializers.SerializerMethodField("_maps_url")
  55     registration_status = serializers.SerializerMethodField("_registration_status")
  56     price = PaymentAmountSerializer()
  57     fine = PaymentAmountSerializer()
  58     documents = DocumentSerializer(many=True)
  59     user_permissions = serializers.SerializerMethodField("_user_permissions")
  60 
  61     def _user_registration(self, instance: Event):
  62         if self.context["request"].member and len(instance.member_registration) > 0:
  63             registration = instance.member_registration[-1]
  64             return EventRegistrationSerializer(
  65                 registration,
  66                 context=self.context,
  67                 fields=(
  68                     "pk",
  69                     "present",
  70                     "queue_position",
  71                     "is_cancelled",
  72                     "is_late_cancellation",
  73                     "date",
  74                     "payment",
  75                 ),
  76             ).data
  77         return None
  78 
  79     def _registration_status(self, instance: Event):
  80         if self.context["request"].member and len(instance.member_registration) > 0:
  81             registration = instance.member_registration[-1]
  82         else:
  83             registration = None
  84         status = services.registration_status(
  85             instance, registration, self.context["request"].member
  86         )
  87         cancel_status = services.cancel_status(instance, registration)
  88 
  89         status_str = services.registration_status_string(status, instance, registration)
  90         cancel_str = services.cancel_info_string(instance, cancel_status, status)
  91         if services.show_cancel_status(status) and cancel_str != "":
  92             return f"{status_str} {cancel_str}"
  93         return f"{status_str}"
  94 
  95     def _num_participants(self, instance: Event):
  96         if instance.max_participants:
  97             return min(instance.participant_count, instance.max_participants)
  98         return instance.participant_count
  99 
  100     def _user_permissions(self, instance):
  101         member = self.context["request"].member
  102         return services.event_permissions(member, instance, registration_prefetch=True)
  103 
  104     def _maps_url(self, instance):
  105         return create_google_maps_url(instance.map_location, zoom=13, size="450x250")
  106
  [end of website/events/api/v2/serializers/event.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
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
  @@ -1,4 +1,5 @@
   from rest_framework import serializers
  +from rest_framework.reverse import reverse
   
   from activemembers.api.v2.serializers.member_group import MemberGroupSerializer
   from documents.api.v2.serializers.document import DocumentSerializer
  @@ -20,6 +21,8 @@
           model = Event
           fields = (
               "pk",
  +            "slug",
  +            "url",
               "title",
               "description",
               "caption",
  @@ -57,6 +60,7 @@
       fine = PaymentAmountSerializer()
       documents = DocumentSerializer(many=True)
       user_permissions = serializers.SerializerMethodField("_user_permissions")
  +    url = serializers.SerializerMethodField("_url")
   
       def _user_registration(self, instance: Event):
           if self.context["request"].member and len(instance.member_registration) > 0:
  @@ -101,5 +105,18 @@
           member = self.context["request"].member
           return services.event_permissions(member, instance, registration_prefetch=True)
   
  +    def _url(self, instance: Event):
  +        if instance.slug is None:
  +            return reverse(
  +                "events:event",
  +                kwargs={"pk": instance.pk},
  +                request=self.context["request"],
  +            )
  +        return reverse(
  +            "events:event",
  +            kwargs={"slug": instance.slug},
  +            request=self.context["request"],
  +        )
  +
       def _maps_url(self, instance):
           return create_google_maps_url(instance.map_location, zoom=13, size="450x250")
  diff --git a/website/events/api/v2/urls.py b/website/events/api/v2/urls.py
  --- a/website/events/api/v2/urls.py
  +++ b/website/events/api/v2/urls.py
  @@ -21,6 +21,11 @@
           EventDetailView.as_view(),
           name="event-detail",
       ),
  +    path(
  +        "events/<slug:slug>/",
  +        EventDetailView.as_view(lookup_field="slug"),
  +        name="event-detail",
  +    ),
       path(
           "events/<int:pk>/registrations/",
           EventRegistrationsView.as_view(),
  
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@@ -1,4 +1,5 @@\n from rest_framework import serializers\n+from rest_framework.reverse import reverse\n \n from activemembers.api.v2.serializers.member_group import MemberGroupSerializer\n from documents.api.v2.serializers.document import DocumentSerializer\n@@ -20,6 +21,8 @@\n         model = Event\n         fields = (\n             \"pk\",\n+            \"slug\",\n+            \"url\",\n             \"title\",\n             \"description\",\n             \"caption\",\n@@ -57,6 +60,7 @@\n     fine = PaymentAmountSerializer()\n     documents = DocumentSerializer(many=True)\n     user_permissions = serializers.SerializerMethodField(\"_user_permissions\")\n+    url = serializers.SerializerMethodField(\"_url\")\n \n     def _user_registration(self, instance: Event):\n         if self.context[\"request\"].member and len(instance.member_registration) > 0:\n@@ -101,5 +105,18 @@\n         member = self.context[\"request\"].member\n         return services.event_permissions(member, instance, registration_prefetch=True)\n \n+    def _url(self, instance: Event):\n+        if instance.slug is None:\n+            return reverse(\n+                \"events:event\",\n+                kwargs={\"pk\": instance.pk},\n+                request=self.context[\"request\"],\n+            )\n+        return reverse(\n+            \"events:event\",\n+            kwargs={\"slug\": instance.slug},\n+            request=self.context[\"request\"],\n+        )\n+\n     def _maps_url(self, instance):\n         return create_google_maps_url(instance.map_location, zoom=13, size=\"450x250\")\ndiff --git a/website/events/api/v2/urls.py b/website/events/api/v2/urls.py\n--- a/website/events/api/v2/urls.py\n+++ b/website/events/api/v2/urls.py\n@@ -21,6 +21,11 @@\n         EventDetailView.as_view(),\n         name=\"event-detail\",\n     ),\n+    path(\n+        \"events/<slug:slug>/\",\n+        EventDetailView.as_view(lookup_field=\"slug\"),\n+        name=\"event-detail\",\n+    ),\n     path(\n         \"events/<int:pk>/registrations/\",\n         EventRegistrationsView.as_view(),\n", "issue": "Add API endpoint for event slugs\n### Is your feature request related to a problem? Please describe.\r\nFor the app we want to get events based on their slug, this is currently not possible.\r\n\r\n### Describe the solution you'd like\r\nAdd an API endpoint for event slugs.\r\n\n", "before_files": [{"content": "\"\"\"Events app API v2 urls.\"\"\"\nfrom django.urls import path\n\nfrom events.api.v2.views import (\n    EventDetailView,\n    EventListView,\n    EventRegistrationDetailView,\n    EventRegistrationFieldsView,\n    EventRegistrationsView,\n    ExternalEventDetailView,\n    ExternalEventListView,\n    MarkPresentAPIView,\n)\n\napp_name = \"events\"\n\nurlpatterns = [\n    path(\"events/\", EventListView.as_view(), name=\"events-list\"),\n    path(\n        \"events/<int:pk>/\",\n        EventDetailView.as_view(),\n        name=\"event-detail\",\n    ),\n    path(\n        \"events/<int:pk>/registrations/\",\n        EventRegistrationsView.as_view(),\n        name=\"event-registrations\",\n    ),\n    path(\n        \"events/<int:event_id>/registrations/<int:pk>/\",\n        EventRegistrationDetailView.as_view(),\n        name=\"event-registration-detail\",\n    ),\n    path(\n        \"events/<int:event_id>/registrations/<int:registration_id>/fields/\",\n        EventRegistrationFieldsView.as_view(),\n        name=\"event-registration-fields\",\n    ),\n    path(\n        \"events/<int:pk>/mark-present/<uuid:token>/\",\n        MarkPresentAPIView.as_view(),\n        name=\"mark-present\",\n    ),\n    path(\n        \"events/external/\", ExternalEventListView.as_view(), name=\"external-events-list\"\n    ),\n    path(\n        \"events/external/<int:pk>/\",\n        ExternalEventDetailView.as_view(),\n        name=\"external-event-detail\",\n    ),\n]\n", "path": "website/events/api/v2/urls.py"}, {"content": "from rest_framework import serializers\n\nfrom activemembers.api.v2.serializers.member_group import MemberGroupSerializer\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\nfrom payments.api.v2.serializers.payment_amount import PaymentAmountSerializer\nfrom thaliawebsite.api.v2.serializers import CleanedHTMLSerializer\nfrom thaliawebsite.api.v2.serializers.cleaned_model_serializer import (\n    CleanedModelSerializer,\n)\nfrom utils.snippets import create_google_maps_url\n\n\nclass EventSerializer(CleanedModelSerializer):\n    \"\"\"Serializer for events.\"\"\"\n\n    class Meta:\n        model = Event\n        fields = (\n            \"pk\",\n            \"title\",\n            \"description\",\n            \"caption\",\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            \"registration_status\",\n            \"cancel_too_late_message\",\n            \"has_fields\",\n            \"food_event\",\n            \"maps_url\",\n            \"user_permissions\",\n            \"user_registration\",\n            \"organisers\",\n            \"documents\",\n        )\n\n    description = CleanedHTMLSerializer()\n    organisers = MemberGroupSerializer(many=True)\n    user_registration = serializers.SerializerMethodField(\"_user_registration\")\n    num_participants = serializers.SerializerMethodField(\"_num_participants\")\n    maps_url = serializers.SerializerMethodField(\"_maps_url\")\n    registration_status = serializers.SerializerMethodField(\"_registration_status\")\n    price = PaymentAmountSerializer()\n    fine = PaymentAmountSerializer()\n    documents = DocumentSerializer(many=True)\n    user_permissions = serializers.SerializerMethodField(\"_user_permissions\")\n\n    def _user_registration(self, instance: Event):\n        if self.context[\"request\"].member and len(instance.member_registration) > 0:\n            registration = instance.member_registration[-1]\n            return EventRegistrationSerializer(\n                registration,\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        return None\n\n    def _registration_status(self, instance: Event):\n        if self.context[\"request\"].member and len(instance.member_registration) > 0:\n            registration = instance.member_registration[-1]\n        else:\n            registration = None\n        status = services.registration_status(\n            instance, registration, self.context[\"request\"].member\n        )\n        cancel_status = services.cancel_status(instance, registration)\n\n        status_str = services.registration_status_string(status, instance, registration)\n        cancel_str = services.cancel_info_string(instance, cancel_status, status)\n        if services.show_cancel_status(status) and cancel_str != \"\":\n            return f\"{status_str} {cancel_str}\"\n        return f\"{status_str}\"\n\n    def _num_participants(self, instance: Event):\n        if instance.max_participants:\n            return min(instance.participant_count, instance.max_participants)\n        return instance.participant_count\n\n    def _user_permissions(self, instance):\n        member = self.context[\"request\"].member\n        return services.event_permissions(member, instance, registration_prefetch=True)\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"}]}