Repository: carpentries/amy

Issue:
API: add filtering by workshop type in published events
We need to grab DC-only, or SWC-only published events. Probably there's no need to return type of the event in the structure, just filtering.



Discussion:

Resolving patch:
diff --git a/api/serializers.py b/api/serializers.py
--- a/api/serializers.py
+++ b/api/serializers.py
@@ -1,6 +1,6 @@
 from rest_framework import serializers
 
-from workshops.models import Badge, Airport, Person, Event, TodoItem
+from workshops.models import Badge, Airport, Person, Event, TodoItem, Tag
 
 
 class PersonUsernameSerializer(serializers.ModelSerializer):
@@ -37,6 +37,12 @@ class Meta:
         fields = ('name', 'latitude', 'longitude', 'instructors', 'country')
 
 
+class TagSerializer(serializers.ModelSerializer):
+    class Meta:
+        model = Tag
+        fields = ('name', )
+
+
 class EventSerializer(serializers.ModelSerializer):
     humandate = serializers.SerializerMethodField()
     country = serializers.CharField()
@@ -44,6 +50,7 @@ class EventSerializer(serializers.ModelSerializer):
     end = serializers.DateField(format=None)
     url = serializers.URLField(source='website_url')
     eventbrite_id = serializers.CharField(source='reg_key')
+    tags = TagSerializer(many=True)
 
     def get_humandate(self, obj):
         """Render start and end dates as human-readable short date."""
@@ -72,6 +79,7 @@ class Meta:
         fields = (
             'slug', 'start', 'end', 'url', 'humandate', 'contact', 'country',
             'venue', 'address', 'latitude', 'longitude', 'eventbrite_id',
+            'tags',
         )
 
 
diff --git a/api/views.py b/api/views.py
--- a/api/views.py
+++ b/api/views.py
@@ -1,5 +1,6 @@
 import datetime
 
+from django.db.models import Q
 from rest_framework.generics import ListAPIView
 from rest_framework.metadata import SimpleMetadata
 from rest_framework.permissions import (
@@ -9,7 +10,7 @@
 from rest_framework.reverse import reverse
 from rest_framework.views import APIView
 
-from workshops.models import Badge, Airport, Event, TodoItem
+from workshops.models import Badge, Airport, Event, TodoItem, Tag
 from workshops.util import get_members, default_membership_cutoff
 
 from .serializers import (
@@ -134,6 +135,12 @@ def get_queryset(self):
         if host is not None:
             queryset = queryset.filter(host__pk=host)
 
+        tags = self.request.query_params.getlist('tag', None)
+        if tags:
+            tags = Tag.objects.filter(name__in=tags)
+            for tag in tags:
+                queryset = queryset.filter(tags=tag)
+
         return queryset
 
     def get_query_params_description(self):
@@ -141,6 +148,8 @@ def get_query_params_description(self):
             'administrator': 'ID of the organization responsible for admin '
                              'work on events.',
             'host': 'ID of the organization hosting the event.',
+            'tag': "Events' tag(s). You can use this parameter multiple "
+                   "times.",
         }
 
 


Test patch:
diff --git a/api/test/test_events.py b/api/test/test_events.py
--- a/api/test/test_events.py
+++ b/api/test/test_events.py
@@ -3,6 +3,7 @@
 from unittest.mock import patch
 
 from django.core.urlresolvers import reverse
+from django.http import QueryDict
 from rest_framework import status
 from rest_framework.test import APITestCase
 
@@ -114,6 +115,7 @@ def setUp(self):
                 'url': 'https://user.github.io/repository/',
                 'contact': 'sb@sth.edu',
                 'eventbrite_id': '12341234',
+                'tags': [],
             },
             {
                 'slug': 'event2',
@@ -130,6 +132,7 @@ def setUp(self):
                 'url': 'https://user.github.io/repository/',
                 'contact': 'sb@sth.edu',
                 'eventbrite_id': None,
+                'tags': [],
             },
             {
                 'slug': 'event1',
@@ -144,10 +147,12 @@ def setUp(self):
                 'url': 'https://user.github.io/repository/',
                 'contact': 'sb@sth.edu',
                 'eventbrite_id': None,
+                'tags': [],
             },
         ]
 
-    @patch.object(PublishedEvents, 'request', query_params={}, create=True)
+    @patch.object(PublishedEvents, 'request', query_params=QueryDict(),
+                  create=True)
     def test_serialization(self, mock_request):
         # we're mocking a request here because it's not possible to create
         # a fake request context for the view