Commit 24f24af3 by Clinton Blackburn

Added support for filtering courses by one, or more, course keys

ECOM-5001
parent 4c8415e8
import django_filters
from django.contrib.auth import get_user_model
from django.utils.translation import ugettext as _
from drf_haystack.filters import HaystackFacetFilter
......@@ -6,6 +7,8 @@ from dry_rest_permissions.generics import DRYPermissionFiltersBase
from guardian.shortcuts import get_objects_for_user
from rest_framework.exceptions import PermissionDenied, NotFound
from course_discovery.apps.course_metadata.models import Course
User = get_user_model()
......@@ -52,3 +55,19 @@ class FacetQueryBuilderWithQueries(FacetQueryBuilder):
class HaystackFacetFilterWithQueries(HaystackFacetFilter):
query_builder_class = FacetQueryBuilderWithQueries
class CharListFilter(django_filters.CharFilter):
def filter(self, qs, value): # pylint: disable=method-hidden
if value not in (None, ''):
value = value.split(',')
return super(CharListFilter, self).filter(qs, value)
class CourseFilter(django_filters.FilterSet):
keys = CharListFilter(name='key', lookup_type='in')
class Meta:
model = Course
fields = ['keys']
......@@ -44,3 +44,13 @@ class CourseViewSetTests(SerializationMixin, APITestCase):
response = self.client.get(url)
self.assertListEqual(response.data['results'], self.serialize_course(courses, many=True))
def test_list_key_filter(self):
""" Verify the endpoint returns a list of courses filtered by the specified keys. """
courses = CourseFactory.create_batch(3)
courses = sorted(courses, key=lambda course: course.key.lower())
keys = ','.join([course.key for course in courses])
url = '{root}?keys={keys}'.format(root=reverse('api:v1:course-list'), keys=keys)
response = self.client.get(url)
self.assertListEqual(response.data['results'], self.serialize_course(courses, many=True))
......@@ -16,14 +16,14 @@ from drf_haystack.mixins import FacetMixin
from drf_haystack.viewsets import HaystackViewSet
from dry_rest_permissions.generics import DRYPermissions
from edx_rest_framework_extensions.permissions import IsSuperuser
from rest_framework import status, viewsets
from rest_framework import status, viewsets, filters
from rest_framework.decorators import detail_route, list_route
from rest_framework.exceptions import PermissionDenied, ParseError
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from course_discovery.apps.api import serializers
from course_discovery.apps.api.filters import PermissionsFilter, HaystackFacetFilterWithQueries
from course_discovery.apps.api.filters import PermissionsFilter, HaystackFacetFilterWithQueries, CourseFilter
from course_discovery.apps.api.pagination import PageNumberPagination
from course_discovery.apps.api.renderers import AffiliateWindowXMLRenderer, CourseRunCSVRenderer
from course_discovery.apps.catalogs.models import Catalog
......@@ -172,6 +172,8 @@ class CatalogViewSet(viewsets.ModelViewSet):
class CourseViewSet(viewsets.ReadOnlyModelViewSet):
""" Course resource. """
filter_backends = (filters.DjangoFilterBackend,)
filter_class = CourseFilter
lookup_field = 'key'
lookup_value_regex = COURSE_ID_REGEX
queryset = Course.objects.all()
......@@ -190,10 +192,16 @@ class CourseViewSet(viewsets.ReadOnlyModelViewSet):
def list(self, request, *args, **kwargs):
""" List all courses.
---
---
parameters:
- name: q
description: Elasticsearch querystring query
description: Elasticsearch querystring query. This filter takes precedence over other filters.
required: false
type: string
paramType: query
multiple: false
- name: keys
description: Filter by keys (comma-separated list)
required: false
type: string
paramType: query
......
......@@ -41,6 +41,7 @@ THIRD_PARTY_APPS = (
'guardian',
'dry_rest_permissions',
'compressor',
'django_filters',
)
PROJECT_APPS = (
......
cryptography==1.4
django==1.8.14
django-extensions==1.6.7
django-filter==0.13.0
django-guardian==1.4.4
django-haystack==2.4.1
django-libsass==0.7
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment