Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • aptivate/client-projects/internewshid
1 result
Show changes
Commits on Source (14)
Showing
with 198 additions and 52 deletions
......@@ -8,7 +8,7 @@ class HidAppConfig(AppConfig):
def ready(self):
from dashboard.widget_pool import register_widget
from hid.filters import (
AgeFilter,
AgeRangeFilter,
CategoryFilter,
EnnumeratorFilter,
GenderFilter,
......@@ -27,7 +27,7 @@ class HidAppConfig(AppConfig):
register_filter('time_range', TimeRangeFilter())
register_filter('location', LocationFilter())
register_filter('gender', GenderFilter())
register_filter('age', AgeFilter())
register_filter('age_range', AgeRangeFilter())
register_filter('ennumerator', EnnumeratorFilter())
register_filter('source', SourceFilter())
register_filter('tags', TagsFilter())
......
......@@ -11,9 +11,11 @@ class CategoryFilter(object):
class TagsFilter(object):
def apply(self, filters, query_dict, **kwargs):
tags = kwargs.get('tags', None)
tags = query_dict.get('tags', None)
if tags is not None:
filters.update(tags=tags)
filters.setdefault('terms', []).append(
'tags:{}'.format(tags)
)
class TimeRangeFilter(object):
......@@ -42,11 +44,16 @@ class GenderFilter(object):
filters.update(gender=gender)
class AgeFilter(object):
class AgeRangeFilter(object):
def apply(self, filters, query_dict, **kwargs):
age = query_dict.get('age', None)
if age is not None:
filters.update(age=age)
from_age = query_dict.get('from_age', None)
to_age = query_dict.get('to_age', None)
if from_age is not None and to_age is not None:
filters.update(
from_age=from_age,
to_age=to_age
)
class EnnumeratorFilter(object):
......
......@@ -302,7 +302,7 @@
"name": "feedback",
"page": 1,
"position": 2,
"settings": "{\"label\":\"Feedback\",\"columns\":[\"select_item\",\"created\",\"timestamp\",\"body\",\"translation\",\"category\",\"tags\",\"location\",\"gender\",\"age\",\"ennumerator\",\"source\"],\"filters\":{\"terms\":[]},\"dynamic_filters\":[\"time_range\",\"category\",\"tags\",\"gender\",\"age\",\"location\",\"ennumerator\",\"source\"],\"categories\":[\"bangladesh-refugee-crisis-sectors\"]}",
"settings": "{\"label\":\"Feedback\",\"columns\":[\"select_item\",\"created\",\"timestamp\",\"body\",\"translation\",\"category\",\"tags\",\"location\",\"gender\",\"age\",\"ennumerator\",\"source\"],\"filters\":{\"terms\":[]},\"dynamic_filters\":[\"time_range\",\"category\",\"tags\",\"gender\",\"age_range\",\"location\",\"ennumerator\",\"source\"],\"categories\":[\"bangladesh-refugee-crisis-sectors\"]}",
"tab_type": "view-and-edit-table"
},
"model": "tabbed_page.tabinstance",
......
......@@ -188,13 +188,6 @@ class ViewAndEditTableTab(object):
genders.sort()
return {'items': genders}
def _get_age_options(self, items_list, **kwargs):
ages = list(set(filter(None, [
item['age'] for item in items_list
])))
ages.sort()
return {'items': ages}
def _get_ennumerator_options(self, items_list, **kwargs):
ennumerators = list(set(filter(None, [
item['ennumerator'] for item in items_list
......@@ -243,7 +236,6 @@ class ViewAndEditTableTab(object):
category_options = self._get_category_options(**kwargs)
location_options = self._get_location_options(items, **kwargs)
gender_options = self._get_gender_options(items, **kwargs)
age_options = self._get_age_options(items, **kwargs)
ennumerator_options = self._get_ennumerator_options(items, **kwargs)
source_options = self._get_source_options(items, **kwargs)
......@@ -274,7 +266,6 @@ class ViewAndEditTableTab(object):
'category_options': category_options,
'locations': location_options,
'gender': gender_options,
'age': age_options,
'ennumerator': ennumerator_options,
'source_filters': source_options,
'next': reverse('tabbed-page', kwargs={
......
{% if age.items %}
{% load i18n %}
<div class="filter-age form-group input-group">
<label class="control-label" for="age-selector">{% trans "Age" %}</label>
<select id="age-selector" name="age" class="form-control">
<option value="All Ages" selected="selected">All Ages</option>
{% for age in age.items %}
<option value="{{ age }}">{{ age | title }}</option>
{% endfor %}
</select>
</div>
{% endif %}
{% load i18n %}
<div class="filter-age form-group input-group">
<label class="control-label">{% trans "Ages" %}</label>
<input type="number" value="{{ filters.from_age }}" class="form-control" name="from_age">
<input type="number" value="{{ filters.to_age }}" class="form-control" name="to_age">
</div>
......@@ -5,7 +5,7 @@
<select id="ennumerator-selector" name="ennumerator" class="form-control">
<option value="All Ennumerators" selected="selected">All Enumerators</option>
{% for ennumerator in ennumerator.items %}
<option value="{{ ennumerator }}">{{ ennumerator | title }}</option>
<option value="{{ ennumerator }}"{% if ennumerator == request.GET.ennumerator %} selected="selected"{% endif %}>{{ ennumerator | title }}</option>
{% endfor %}
</select>
</div>
......
......@@ -5,7 +5,7 @@
<select id="gender-selector" name="gender" class="form-control">
<option value="All Genders" selected="selected">All Genders</option>
{% for gender in gender.items %}
<option value="{{ gender }}">{{ gender | title }}</option>
<option value="{{ gender }}"{% if gender == request.GET.gender %} selected="selected"{% endif %}>{{ gender | title }}</option>
{% endfor %}
</select>
</div>
......
......@@ -5,7 +5,7 @@
<select id="location-selector" name="location" class="form-control">
<option value="All Locations" selected="selected">All Locations</option>
{% for location in locations.items %}
<option value="{{ location }}">{{ location | title }}</option>
<option value="{{ location }}"{% if location == request.GET.location %} selected="selected"{% endif %}>{{ location | title }}</option>
{% endfor %}
</select>
</div>
......
{% load i18n %}
<div class="filter-tags form-group input-group">
<label class="control-label" for="tags-selector">{% trans "Tags" %}</label>
<input type="text" placeholder="All Tags" name="tags" class="form-control">
<input type="text" placeholder="All Tags" name="tags" class="form-control" value="{{ request.GET.tags }}">
</div>
......@@ -446,6 +446,97 @@ def test_table_items_filtered_by_date_range():
assert too_new['id'] not in ids
@pytest.mark.django_db
def test_table_items_filtered_by_age_range():
too_old = transport.items.create({
'body': "Too old item",
'age': '38'
})
in_range_1 = transport.items.create({
'body': "In range item 1",
'age': '37',
})
in_range_2 = transport.items.create({
'body': "In range item 1",
'age': '36',
})
too_young = transport.items.create({
'body': "Too young item",
'age': '35',
})
page = TabbedPageFactory()
tab_instance = TabInstanceFactory(page=page)
request = MagicMock(session={'THREADED_FILTERS': {}}, GET={
'from_age': '36',
'to_age': '37',
})
tab = ViewAndEditTableTab()
context_data = tab.get_context_data(
tab_instance, request, categories=[],
dynamic_filters=['age_range']
)
table = context_data['table']
ids = [t['id'] for t in table.data.data]
assert in_range_1['id'] in ids
assert in_range_2['id'] in ids
assert too_old['id'] not in ids
assert too_young['id'] not in ids
@pytest.mark.django_db
def test_table_items_filtered_by_tags():
tags = TaxonomyFactory(name="Tags")
not_tags = TaxonomyFactory(name="Not tags")
female_item = transport.items.create({
'body': 'Message from female',
})
male_item = transport.items.create({
'body': 'Message from male',
})
another_item = transport.items.create({
'body': 'Another message',
})
tags = TaxonomyFactory(name='tags')
female_term = TermFactory(name='female', taxonomy=tags)
male_term = TermFactory(name='male', taxonomy=tags)
non_tag_term = TermFactory(name='female', taxonomy=not_tags)
transport.items.add_terms(
female_item['id'], female_term.taxonomy.slug, female_term.name)
transport.items.add_terms(
male_item['id'], male_term.taxonomy.slug, male_term.name)
transport.items.add_terms(
another_item['id'], non_tag_term.taxonomy.slug, non_tag_term.name)
page = TabbedPageFactory()
tab_instance = TabInstanceFactory(page=page)
request = MagicMock(session={'THREADED_FILTERS': {}},
GET={'tags': 'female'})
tab = ViewAndEditTableTab()
context_data = tab.get_context_data(
tab_instance, request,
dynamic_filters=['tags']
)
table = context_data['table']
ids = [t['id'] for t in table.data.data]
assert ids == [female_item['id']]
@pytest.mark.django_db
def test_dynamic_filters_read_from_tab_instance():
page = TabbedPageFactory(name='main')
......
......@@ -109,6 +109,38 @@ def test_filter_by_date_range():
assert payload[1]['body'] == "In range item 2"
@pytest.mark.django_db
def test_filter_by_age_range():
create_item(
body="Too old item",
age='38'
)
create_item(
body="In range item 1",
age='34'
)
create_item(
body="In range item 2",
age='37'
)
create_item(
body="Too young item",
age='33'
)
payload = get(data={
'from_age': '34',
'to_age': '37'
}).data
assert len(payload) == 2
assert payload[0]['body'] == "In range item 1"
assert payload[1]['body'] == "In range item 2"
@pytest.mark.django_db
def test_filter_by_location():
create_item(body='item1', location='foo')
......@@ -122,6 +154,26 @@ def test_filter_by_location():
assert payload[0]['location'] == 'somewhere'
@pytest.mark.django_db
def test_filter_by_enumerator():
create_item(
body='item1',
ennumerator='Yasmin')
create_item(
body='item2',
ennumerator='Collected by ....Mohammed yousuf@ Mohammed Ullah'
)
payload = get(
data={
'ennumerator': 'Collected by ....Mohammed yousuf@ Mohammed Ullah',
}
).data
assert len(payload) == 1
assert payload[0]['body'] == 'item2'
@pytest.mark.django_db
def test_filter_by_multiple_terms():
# TODO: Refactor to use the REST API when we can add
......@@ -159,6 +211,22 @@ def test_filter_by_term_works_when_term_name_includes_colon():
assert payload[0]['body'] == item['body']
@pytest.mark.django_db
def test_empty_term_filter_ignored():
taxonomy = create_taxonomy(name='taxonomy').data
term = add_term(taxonomy=taxonomy['slug'], name='my term').data
item1 = create_item(body='item 1').data
item2 = create_item(body='item 2').data
categorize_item(item1, term)
term_filter = '{}:'.format(taxonomy['slug'])
payload = get(data={'terms': [term_filter]}).data
assert len(payload) == 2
assert payload[0]['body'] == item1['body']
assert payload[1]['body'] == item2['body']
@pytest.mark.django_db
def test_item_listed_with_associated_terms():
# TODO: Refactor to use the REST API when we can add
......
......@@ -63,22 +63,15 @@ class ItemViewSet(viewsets.ModelViewSet, BulkDestroyModelMixin):
terms = self.request.query_params.getlist('terms', [])
for taxonomy_and_term in terms:
(taxonomy, term) = taxonomy_and_term.split(':', 1)
matches = Term.objects.filter(
name=term, taxonomy__slug=taxonomy
)
if len(matches) == 0:
# If the term doesn't exist, there can be no matches
return Item.objects.none()
items = items.filter(terms__id=matches[0].id)
if term:
matches = Term.objects.filter(
name=term, taxonomy__slug=taxonomy
)
if len(matches) == 0:
# If the term doesn't exist, there can be no matches
return Item.objects.none()
tags = self.request.query_params.get('tags', None)
if tags is not None:
exact_match_items = items.filter(terms__name__iexact=tags)
if exact_match_items.exists():
items = exact_match_items
else:
items = items.filter(terms__name__icontains=tags)
items = items.filter(terms__id=matches[0].id)
location = self.request.query_params.get('location', None)
if location is not None:
......@@ -88,9 +81,11 @@ class ItemViewSet(viewsets.ModelViewSet, BulkDestroyModelMixin):
if gender is not None:
items = items.filter(gender__icontains=gender)
age = self.request.query_params.get('age', None)
if age is not None:
items = items.filter(age__icontains=age)
from_age = self.request.query_params.get('from_age', None)
to_age = self.request.query_params.get('to_age', None)
if from_age is not None and to_age is not None:
items = items.filter(age__range=[from_age, to_age])
ennumerator = self.request.query_params.get('ennumerator', None)
if ennumerator is not None:
......