prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  API: don't return todos with unknown start
  This breaks the timeline.
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `api/views.py`
  Content:
  ```
  1 import datetime
  2 
  3 from django.db.models import Q
  4 from rest_framework.generics import ListAPIView
  5 from rest_framework.metadata import SimpleMetadata
  6 from rest_framework.permissions import (
  7     IsAuthenticatedOrReadOnly, IsAuthenticated
  8 )
  9 from rest_framework.response import Response
  10 from rest_framework.reverse import reverse
  11 from rest_framework.views import APIView
  12 
  13 from workshops.models import Badge, Airport, Event, TodoItem, Tag
  14 from workshops.util import get_members, default_membership_cutoff
  15 
  16 from .serializers import (
  17     PersonNameEmailSerializer,
  18     ExportBadgesSerializer,
  19     ExportInstructorLocationsSerializer,
  20     EventSerializer,
  21     TodoSerializer,
  22 )
  23 
  24 
  25 class QueryMetadata(SimpleMetadata):
  26     """Additionally include info about query parameters."""
  27 
  28     def determine_metadata(self, request, view):
  29         data = super().determine_metadata(request, view)
  30 
  31         try:
  32             data['query_params'] = view.get_query_params_description()
  33         except AttributeError:
  34             pass
  35 
  36         return data
  37 
  38 
  39 class ApiRoot(APIView):
  40     def get(self, request, format=None):
  41         return Response({
  42             'export-badges': reverse('api:export-badges', request=request,
  43                                      format=format),
  44             'export-instructors': reverse('api:export-instructors',
  45                                           request=request, format=format),
  46             'export-members': reverse('api:export-members', request=request,
  47                                       format=format),
  48             'events-published': reverse('api:events-published',
  49                                         request=request, format=format),
  50             'user-todos': reverse('api:user-todos',
  51                                   request=request, format=format),
  52         })
  53 
  54 
  55 class ExportBadgesView(ListAPIView):
  56     """List all badges and people who have them."""
  57     permission_classes = (IsAuthenticatedOrReadOnly, )
  58     paginator = None  # disable pagination
  59 
  60     queryset = Badge.objects.prefetch_related('person_set')
  61     serializer_class = ExportBadgesSerializer
  62 
  63 
  64 class ExportInstructorLocationsView(ListAPIView):
  65     """List all airports and instructors located near them."""
  66     permission_classes = (IsAuthenticatedOrReadOnly, )
  67     paginator = None  # disable pagination
  68 
  69     queryset = Airport.objects.exclude(person=None) \
  70                               .prefetch_related('person_set')
  71     serializer_class = ExportInstructorLocationsSerializer
  72 
  73 
  74 class ExportMembersView(ListAPIView):
  75     """Show everyone who qualifies as an SCF member."""
  76     permission_classes = (IsAuthenticatedOrReadOnly, )
  77     paginator = None  # disable pagination
  78 
  79     serializer_class = PersonNameEmailSerializer
  80 
  81     def get_queryset(self):
  82         earliest_default, latest_default = default_membership_cutoff()
  83 
  84         earliest = self.request.query_params.get('earliest', None)
  85         if earliest is not None:
  86             try:
  87                 earliest = datetime.datetime.strptime(earliest, '%Y-%m-%d') \
  88                                             .date()
  89             except ValueError:
  90                 earliest = earliest_default
  91         else:
  92             earliest = earliest_default
  93 
  94         latest = self.request.query_params.get('latest', None)
  95         if latest is not None:
  96             try:
  97                 latest = datetime.datetime.strptime(latest, '%Y-%m-%d').date()
  98             except ValueError:
  99                 latest = latest_default
  100         else:
  101             latest = latest_default
  102 
  103         return get_members(earliest, latest)
  104 
  105     def get_query_params_description(self):
  106         return {
  107             'earliest': 'Date of earliest workshop someone taught at.'
  108                         '  Defaults to -2*365 days from current date.',
  109             'latest': 'Date of latest workshop someone taught at.'
  110                       '  Defaults to current date.',
  111         }
  112 
  113 
  114 class PublishedEvents(ListAPIView):
  115     """List published events."""
  116 
  117     # only events that have both a starting date and a URL
  118     permission_classes = (IsAuthenticatedOrReadOnly, )
  119     paginator = None  # disable pagination
  120 
  121     serializer_class = EventSerializer
  122 
  123     metadata_class = QueryMetadata
  124 
  125     def get_queryset(self):
  126         """Optionally restrict the returned event set to events hosted by
  127         specific host or administered by specific admin."""
  128         queryset = Event.objects.published_events()
  129 
  130         administrator = self.request.query_params.get('administrator', None)
  131         if administrator is not None:
  132             queryset = queryset.filter(administrator__pk=administrator)
  133 
  134         host = self.request.query_params.get('host', None)
  135         if host is not None:
  136             queryset = queryset.filter(host__pk=host)
  137 
  138         tags = self.request.query_params.getlist('tag', None)
  139         if tags:
  140             tags = Tag.objects.filter(name__in=tags)
  141             for tag in tags:
  142                 queryset = queryset.filter(tags=tag)
  143 
  144         return queryset
  145 
  146     def get_query_params_description(self):
  147         return {
  148             'administrator': 'ID of the organization responsible for admin '
  149                              'work on events.',
  150             'host': 'ID of the organization hosting the event.',
  151             'tag': "Events' tag(s). You can use this parameter multiple "
  152                    "times.",
  153         }
  154 
  155 
  156 class UserTodoItems(ListAPIView):
  157     permission_classes = (IsAuthenticated, )
  158     paginator = None
  159     serializer_class = TodoSerializer
  160 
  161     def get_queryset(self):
  162         """Return current TODOs for currently logged in user."""
  163         return TodoItem.objects.user(self.request.user) \
  164                                .incomplete() \
  165                                .select_related('event')
  166
  ```
  --- 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/api/views.py b/api/views.py
  --- a/api/views.py
  +++ b/api/views.py
  @@ -162,4 +162,5 @@
           """Return current TODOs for currently logged in user."""
           return TodoItem.objects.user(self.request.user) \
                                  .incomplete() \
  +                               .exclude(due=None) \
                                  .select_related('event')
  
verification_info: {"golden_diff": "diff --git a/api/views.py b/api/views.py\n--- a/api/views.py\n+++ b/api/views.py\n@@ -162,4 +162,5 @@\n         \"\"\"Return current TODOs for currently logged in user.\"\"\"\n         return TodoItem.objects.user(self.request.user) \\\n                                .incomplete() \\\n+                               .exclude(due=None) \\\n                                .select_related('event')\n", "issue": "API: don't return todos with unknown start\nThis breaks the timeline.\n\n", "before_files": [{"content": "import datetime\n\nfrom django.db.models import Q\nfrom rest_framework.generics import ListAPIView\nfrom rest_framework.metadata import SimpleMetadata\nfrom rest_framework.permissions import (\n    IsAuthenticatedOrReadOnly, IsAuthenticated\n)\nfrom rest_framework.response import Response\nfrom rest_framework.reverse import reverse\nfrom rest_framework.views import APIView\n\nfrom workshops.models import Badge, Airport, Event, TodoItem, Tag\nfrom workshops.util import get_members, default_membership_cutoff\n\nfrom .serializers import (\n    PersonNameEmailSerializer,\n    ExportBadgesSerializer,\n    ExportInstructorLocationsSerializer,\n    EventSerializer,\n    TodoSerializer,\n)\n\n\nclass QueryMetadata(SimpleMetadata):\n    \"\"\"Additionally include info about query parameters.\"\"\"\n\n    def determine_metadata(self, request, view):\n        data = super().determine_metadata(request, view)\n\n        try:\n            data['query_params'] = view.get_query_params_description()\n        except AttributeError:\n            pass\n\n        return data\n\n\nclass ApiRoot(APIView):\n    def get(self, request, format=None):\n        return Response({\n            'export-badges': reverse('api:export-badges', request=request,\n                                     format=format),\n            'export-instructors': reverse('api:export-instructors',\n                                          request=request, format=format),\n            'export-members': reverse('api:export-members', request=request,\n                                      format=format),\n            'events-published': reverse('api:events-published',\n                                        request=request, format=format),\n            'user-todos': reverse('api:user-todos',\n                                  request=request, format=format),\n        })\n\n\nclass ExportBadgesView(ListAPIView):\n    \"\"\"List all badges and people who have them.\"\"\"\n    permission_classes = (IsAuthenticatedOrReadOnly, )\n    paginator = None  # disable pagination\n\n    queryset = Badge.objects.prefetch_related('person_set')\n    serializer_class = ExportBadgesSerializer\n\n\nclass ExportInstructorLocationsView(ListAPIView):\n    \"\"\"List all airports and instructors located near them.\"\"\"\n    permission_classes = (IsAuthenticatedOrReadOnly, )\n    paginator = None  # disable pagination\n\n    queryset = Airport.objects.exclude(person=None) \\\n                              .prefetch_related('person_set')\n    serializer_class = ExportInstructorLocationsSerializer\n\n\nclass ExportMembersView(ListAPIView):\n    \"\"\"Show everyone who qualifies as an SCF member.\"\"\"\n    permission_classes = (IsAuthenticatedOrReadOnly, )\n    paginator = None  # disable pagination\n\n    serializer_class = PersonNameEmailSerializer\n\n    def get_queryset(self):\n        earliest_default, latest_default = default_membership_cutoff()\n\n        earliest = self.request.query_params.get('earliest', None)\n        if earliest is not None:\n            try:\n                earliest = datetime.datetime.strptime(earliest, '%Y-%m-%d') \\\n                                            .date()\n            except ValueError:\n                earliest = earliest_default\n        else:\n            earliest = earliest_default\n\n        latest = self.request.query_params.get('latest', None)\n        if latest is not None:\n            try:\n                latest = datetime.datetime.strptime(latest, '%Y-%m-%d').date()\n            except ValueError:\n                latest = latest_default\n        else:\n            latest = latest_default\n\n        return get_members(earliest, latest)\n\n    def get_query_params_description(self):\n        return {\n            'earliest': 'Date of earliest workshop someone taught at.'\n                        '  Defaults to -2*365 days from current date.',\n            'latest': 'Date of latest workshop someone taught at.'\n                      '  Defaults to current date.',\n        }\n\n\nclass PublishedEvents(ListAPIView):\n    \"\"\"List published events.\"\"\"\n\n    # only events that have both a starting date and a URL\n    permission_classes = (IsAuthenticatedOrReadOnly, )\n    paginator = None  # disable pagination\n\n    serializer_class = EventSerializer\n\n    metadata_class = QueryMetadata\n\n    def get_queryset(self):\n        \"\"\"Optionally restrict the returned event set to events hosted by\n        specific host or administered by specific admin.\"\"\"\n        queryset = Event.objects.published_events()\n\n        administrator = self.request.query_params.get('administrator', None)\n        if administrator is not None:\n            queryset = queryset.filter(administrator__pk=administrator)\n\n        host = self.request.query_params.get('host', None)\n        if host is not None:\n            queryset = queryset.filter(host__pk=host)\n\n        tags = self.request.query_params.getlist('tag', None)\n        if tags:\n            tags = Tag.objects.filter(name__in=tags)\n            for tag in tags:\n                queryset = queryset.filter(tags=tag)\n\n        return queryset\n\n    def get_query_params_description(self):\n        return {\n            'administrator': 'ID of the organization responsible for admin '\n                             'work on events.',\n            'host': 'ID of the organization hosting the event.',\n            'tag': \"Events' tag(s). You can use this parameter multiple \"\n                   \"times.\",\n        }\n\n\nclass UserTodoItems(ListAPIView):\n    permission_classes = (IsAuthenticated, )\n    paginator = None\n    serializer_class = TodoSerializer\n\n    def get_queryset(self):\n        \"\"\"Return current TODOs for currently logged in user.\"\"\"\n        return TodoItem.objects.user(self.request.user) \\\n                               .incomplete() \\\n                               .select_related('event')\n", "path": "api/views.py"}], "after_files": [{"content": "import datetime\n\nfrom django.db.models import Q\nfrom rest_framework.generics import ListAPIView\nfrom rest_framework.metadata import SimpleMetadata\nfrom rest_framework.permissions import (\n    IsAuthenticatedOrReadOnly, IsAuthenticated\n)\nfrom rest_framework.response import Response\nfrom rest_framework.reverse import reverse\nfrom rest_framework.views import APIView\n\nfrom workshops.models import Badge, Airport, Event, TodoItem, Tag\nfrom workshops.util import get_members, default_membership_cutoff\n\nfrom .serializers import (\n    PersonNameEmailSerializer,\n    ExportBadgesSerializer,\n    ExportInstructorLocationsSerializer,\n    EventSerializer,\n    TodoSerializer,\n)\n\n\nclass QueryMetadata(SimpleMetadata):\n    \"\"\"Additionally include info about query parameters.\"\"\"\n\n    def determine_metadata(self, request, view):\n        data = super().determine_metadata(request, view)\n\n        try:\n            data['query_params'] = view.get_query_params_description()\n        except AttributeError:\n            pass\n\n        return data\n\n\nclass ApiRoot(APIView):\n    def get(self, request, format=None):\n        return Response({\n            'export-badges': reverse('api:export-badges', request=request,\n                                     format=format),\n            'export-instructors': reverse('api:export-instructors',\n                                          request=request, format=format),\n            'export-members': reverse('api:export-members', request=request,\n                                      format=format),\n            'events-published': reverse('api:events-published',\n                                        request=request, format=format),\n            'user-todos': reverse('api:user-todos',\n                                  request=request, format=format),\n        })\n\n\nclass ExportBadgesView(ListAPIView):\n    \"\"\"List all badges and people who have them.\"\"\"\n    permission_classes = (IsAuthenticatedOrReadOnly, )\n    paginator = None  # disable pagination\n\n    queryset = Badge.objects.prefetch_related('person_set')\n    serializer_class = ExportBadgesSerializer\n\n\nclass ExportInstructorLocationsView(ListAPIView):\n    \"\"\"List all airports and instructors located near them.\"\"\"\n    permission_classes = (IsAuthenticatedOrReadOnly, )\n    paginator = None  # disable pagination\n\n    queryset = Airport.objects.exclude(person=None) \\\n                              .prefetch_related('person_set')\n    serializer_class = ExportInstructorLocationsSerializer\n\n\nclass ExportMembersView(ListAPIView):\n    \"\"\"Show everyone who qualifies as an SCF member.\"\"\"\n    permission_classes = (IsAuthenticatedOrReadOnly, )\n    paginator = None  # disable pagination\n\n    serializer_class = PersonNameEmailSerializer\n\n    def get_queryset(self):\n        earliest_default, latest_default = default_membership_cutoff()\n\n        earliest = self.request.query_params.get('earliest', None)\n        if earliest is not None:\n            try:\n                earliest = datetime.datetime.strptime(earliest, '%Y-%m-%d') \\\n                                            .date()\n            except ValueError:\n                earliest = earliest_default\n        else:\n            earliest = earliest_default\n\n        latest = self.request.query_params.get('latest', None)\n        if latest is not None:\n            try:\n                latest = datetime.datetime.strptime(latest, '%Y-%m-%d').date()\n            except ValueError:\n                latest = latest_default\n        else:\n            latest = latest_default\n\n        return get_members(earliest, latest)\n\n    def get_query_params_description(self):\n        return {\n            'earliest': 'Date of earliest workshop someone taught at.'\n                        '  Defaults to -2*365 days from current date.',\n            'latest': 'Date of latest workshop someone taught at.'\n                      '  Defaults to current date.',\n        }\n\n\nclass PublishedEvents(ListAPIView):\n    \"\"\"List published events.\"\"\"\n\n    # only events that have both a starting date and a URL\n    permission_classes = (IsAuthenticatedOrReadOnly, )\n    paginator = None  # disable pagination\n\n    serializer_class = EventSerializer\n\n    metadata_class = QueryMetadata\n\n    def get_queryset(self):\n        \"\"\"Optionally restrict the returned event set to events hosted by\n        specific host or administered by specific admin.\"\"\"\n        queryset = Event.objects.published_events()\n\n        administrator = self.request.query_params.get('administrator', None)\n        if administrator is not None:\n            queryset = queryset.filter(administrator__pk=administrator)\n\n        host = self.request.query_params.get('host', None)\n        if host is not None:\n            queryset = queryset.filter(host__pk=host)\n\n        tags = self.request.query_params.getlist('tag', None)\n        if tags:\n            tags = Tag.objects.filter(name__in=tags)\n            for tag in tags:\n                queryset = queryset.filter(tags=tag)\n\n        return queryset\n\n    def get_query_params_description(self):\n        return {\n            'administrator': 'ID of the organization responsible for admin '\n                             'work on events.',\n            'host': 'ID of the organization hosting the event.',\n            'tag': \"Events' tag(s). You can use this parameter multiple \"\n                   \"times.\",\n        }\n\n\nclass UserTodoItems(ListAPIView):\n    permission_classes = (IsAuthenticated, )\n    paginator = None\n    serializer_class = TodoSerializer\n\n    def get_queryset(self):\n        \"\"\"Return current TODOs for currently logged in user.\"\"\"\n        return TodoItem.objects.user(self.request.user) \\\n                               .incomplete() \\\n                               .exclude(due=None) \\\n                               .select_related('event')\n", "path": "api/views.py"}]}