Commit 27ca6370 by Ibrahim Committed by Ibrahim Ahmed

Add hidden boolean filter to programs

LEARNER-1122
parent 5be88fcc
import logging import logging
import django_filters
from django.conf import settings from django.conf import settings
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.db.models import QuerySet from django.db.models import QuerySet
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django_filters import rest_framework as filters
from drf_haystack.filters import HaystackFilter as DefaultHaystackFilter from drf_haystack.filters import HaystackFilter as DefaultHaystackFilter
from drf_haystack.filters import HaystackFacetFilter from drf_haystack.filters import HaystackFacetFilter
from drf_haystack.query import FacetQueryBuilder from drf_haystack.query import FacetQueryBuilder
...@@ -98,7 +98,7 @@ class HaystackFilter(HaystackRequestFilterMixin, DefaultHaystackFilter): ...@@ -98,7 +98,7 @@ class HaystackFilter(HaystackRequestFilterMixin, DefaultHaystackFilter):
return filters return filters
class CharListFilter(django_filters.CharFilter): class CharListFilter(filters.CharFilter):
""" Filters a field via a comma-delimited list of values. """ """ Filters a field via a comma-delimited list of values. """
def filter(self, qs, value): # pylint: disable=method-hidden def filter(self, qs, value): # pylint: disable=method-hidden
...@@ -111,9 +111,9 @@ class CharListFilter(django_filters.CharFilter): ...@@ -111,9 +111,9 @@ class CharListFilter(django_filters.CharFilter):
class UUIDListFilter(CharListFilter): class UUIDListFilter(CharListFilter):
""" Filters a field via a comma-delimited list of UUIDs. """ """ Filters a field via a comma-delimited list of UUIDs. """
def __init__(self, name='uuid', label=None, widget=None, action=None, def __init__(self, name='uuid', label=None, widget=None, method=None, lookup_expr='in', required=False,
lookup_expr='in', required=False, distinct=False, exclude=False, **kwargs): distinct=False, exclude=False, **kwargs):
super().__init__(name=name, label=label, widget=widget, action=action, lookup_expr=lookup_expr, super().__init__(name=name, label=label, widget=widget, method=method, lookup_expr=lookup_expr,
required=required, distinct=distinct, exclude=exclude, **kwargs) required=required, distinct=distinct, exclude=exclude, **kwargs)
...@@ -121,14 +121,14 @@ class FilterSetMixin: ...@@ -121,14 +121,14 @@ class FilterSetMixin:
def _apply_filter(self, name, queryset, value): def _apply_filter(self, name, queryset, value):
return getattr(queryset, name)() if cast2int(value, name) else queryset return getattr(queryset, name)() if cast2int(value, name) else queryset
def filter_active(self, queryset, value): def filter_active(self, queryset, name, value):
return self._apply_filter('active', queryset, value) return self._apply_filter(name, queryset, value)
def filter_marketable(self, queryset, value): def filter_marketable(self, queryset, name, value):
return self._apply_filter('marketable', queryset, value) return self._apply_filter(name, queryset, value)
class CourseFilter(django_filters.FilterSet): class CourseFilter(filters.FilterSet):
keys = CharListFilter(name='key', lookup_expr='in') keys = CharListFilter(name='key', lookup_expr='in')
class Meta: class Meta:
...@@ -136,9 +136,9 @@ class CourseFilter(django_filters.FilterSet): ...@@ -136,9 +136,9 @@ class CourseFilter(django_filters.FilterSet):
fields = ['keys'] fields = ['keys']
class CourseRunFilter(FilterSetMixin, django_filters.FilterSet): class CourseRunFilter(FilterSetMixin, filters.FilterSet):
active = django_filters.MethodFilter() active = filters.BooleanFilter(method='filter_active')
marketable = django_filters.MethodFilter() marketable = filters.BooleanFilter(method='filter_marketable')
keys = CharListFilter(name='key', lookup_expr='in') keys = CharListFilter(name='key', lookup_expr='in')
@property @property
...@@ -155,20 +155,22 @@ class CourseRunFilter(FilterSetMixin, django_filters.FilterSet): ...@@ -155,20 +155,22 @@ class CourseRunFilter(FilterSetMixin, django_filters.FilterSet):
fields = ['keys', 'hidden'] fields = ['keys', 'hidden']
class ProgramFilter(FilterSetMixin, django_filters.FilterSet): class ProgramFilter(FilterSetMixin, filters.FilterSet):
marketable = django_filters.MethodFilter() marketable = filters.BooleanFilter(method='filter_marketable')
status = django_filters.MultipleChoiceFilter(choices=ProgramStatus.choices) status = filters.MultipleChoiceFilter(choices=ProgramStatus.choices)
type = django_filters.CharFilter(name='type__name', lookup_expr='iexact') type = filters.CharFilter(name='type__name', lookup_expr='iexact')
types = CharListFilter(name='type__slug', lookup_expr='in') types = CharListFilter(name='type__slug', lookup_expr='in')
uuids = UUIDListFilter() uuids = UUIDListFilter()
class Meta: class Meta:
model = Program model = Program
fields = ('hidden', 'marketable', 'status', 'type', 'types',)
class OrganizationFilter(django_filters.FilterSet): class OrganizationFilter(filters.FilterSet):
tags = CharListFilter(name='tags__name', lookup_expr='in') tags = CharListFilter(name='tags__name', lookup_expr='in')
uuids = UUIDListFilter() uuids = UUIDListFilter()
class Meta: class Meta:
model = Organization model = Organization
fields = ('tags', 'uuids',)
...@@ -226,6 +226,23 @@ class ProgramViewSetTests(SerializationMixin, APITestCase): ...@@ -226,6 +226,23 @@ class ProgramViewSetTests(SerializationMixin, APITestCase):
url = self.list_path + '?status=active&status=retired' url = self.list_path + '?status=active&status=retired'
self.assert_list_results(url, [retired, active], 8) self.assert_list_results(url, [retired, active], 8)
def test_filter_by_hidden(self):
""" Endpoint should filter programs by their hidden attribute value. """
hidden = ProgramFactory(hidden=True)
not_hidden = ProgramFactory(hidden=False)
url = self.list_path + '?hidden=True'
self.assert_list_results(url, [hidden], 8)
url = self.list_path + '?hidden=False'
self.assert_list_results(url, [not_hidden], 8)
url = self.list_path + '?hidden=1'
self.assert_list_results(url, [hidden], 8)
url = self.list_path + '?hidden=0'
self.assert_list_results(url, [not_hidden], 8)
def test_list_exclude_utm(self): def test_list_exclude_utm(self):
""" Verify the endpoint returns marketing URLs without UTM parameters. """ """ Verify the endpoint returns marketing URLs without UTM parameters. """
url = self.list_path + '?exclude_utm=1' url = self.list_path + '?exclude_utm=1'
......
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import viewsets from rest_framework import viewsets
from rest_framework.filters import DjangoFilterBackend
from rest_framework.permissions import IsAuthenticated from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework_extensions.cache.mixins import CacheResponseMixin from rest_framework_extensions.cache.mixins import CacheResponseMixin
......
...@@ -7,7 +7,7 @@ msgid "" ...@@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-06-01 16:02+0500\n" "POT-Creation-Date: 2017-06-01 18:07+0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
...@@ -441,6 +441,12 @@ msgstr "" ...@@ -441,6 +441,12 @@ msgstr ""
msgid "Allow courses in this program to be purchased in a single transaction" msgid "Allow courses in this program to be purchased in a single transaction"
msgstr "" msgstr ""
#: apps/course_metadata/models.py
msgid ""
"Hide program on marketing site landing and search pages. This program MAY "
"have a detail page."
msgstr ""
#: apps/course_metadata/views.py #: apps/course_metadata/views.py
msgid "Update excluded course runs" msgid "Update excluded course runs"
msgstr "" msgstr ""
......
...@@ -7,7 +7,7 @@ msgid "" ...@@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-06-01 16:02+0500\n" "POT-Creation-Date: 2017-06-01 18:07+0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
......
...@@ -7,7 +7,7 @@ msgid "" ...@@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-06-01 16:02+0500\n" "POT-Creation-Date: 2017-06-01 18:07+0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
...@@ -552,6 +552,14 @@ msgstr "" ...@@ -552,6 +552,14 @@ msgstr ""
"Àllöw çöürsés ïn thïs prögräm tö ßé pürçhäséd ïn ä sïnglé tränsäçtïön Ⱡ'σяєм" "Àllöw çöürsés ïn thïs prögräm tö ßé pürçhäséd ïn ä sïnglé tränsäçtïön Ⱡ'σяєм"
" ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя #" " ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя #"
#: apps/course_metadata/models.py
msgid ""
"Hide program on marketing site landing and search pages. This program MAY "
"have a detail page."
msgstr ""
"Hïdé prögräm ön märkétïng sïté ländïng änd séärçh pägés. Thïs prögräm MÀÝ "
"hävé ä détäïl pägé. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σ#"
#: apps/course_metadata/views.py #: apps/course_metadata/views.py
msgid "Update excluded course runs" msgid "Update excluded course runs"
msgstr "Ûpdäté éxçlüdéd çöürsé rüns Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє#" msgstr "Ûpdäté éxçlüdéd çöürsé rüns Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє#"
......
...@@ -7,7 +7,7 @@ msgid "" ...@@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-06-01 16:02+0500\n" "POT-Creation-Date: 2017-06-01 18:07+0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
......
...@@ -7,7 +7,7 @@ django-choices==1.4.3 ...@@ -7,7 +7,7 @@ django-choices==1.4.3
django-compressor==2.1.1 django-compressor==2.1.1
django-contrib-comments==1.7.2 django-contrib-comments==1.7.2
django-extensions==1.7.8 django-extensions==1.7.8
django-filter==0.14.0 django-filter==1.0.4
django-fsm==2.4.0 django-fsm==2.4.0
django-guardian==1.4.5 django-guardian==1.4.5
django-haystack==2.5.0 django-haystack==2.5.0
......
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