Skip to content

Commit b4b93c3

Browse files
authored
Merge pull request #36 from cloudblue/fix/LITE-12790
LITE-12790 Namespaces support distinct assignment
2 parents 2dea1eb + 9b83329 commit b4b93c3

File tree

4 files changed

+45
-12
lines changed

4 files changed

+45
-12
lines changed

dj_rql/_dataclasses.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# Copyright © 2020 Ingram Micro Inc. All rights reserved.
2+
# Copyright © 2022 Ingram Micro Inc. All rights reserved.
33
#
44

55

@@ -40,3 +40,4 @@ def __init__(self, filter_name, operator, str_value, list_operator=None,
4040

4141
self.filter_lookup = kwargs.get('filter_lookup')
4242
self.django_lookup = kwargs.get('django_lookup')
43+
self.distinct = kwargs.get('distinct')

dj_rql/filter_cls.py

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# Copyright © 2021 Ingram Micro Inc. All rights reserved.
2+
# Copyright © 2022 Ingram Micro Inc. All rights reserved.
33
#
44

55
import decimal
@@ -553,9 +553,15 @@ def _get_filter_ordering_name(self, filter_item, filter_name):
553553

554554
return filter_item['orm_route']
555555

556-
def _build_filters(self, filters, filter_route='', orm_route='',
557-
orm_model=None, select_tree=None, parent_qs=None):
556+
def _build_filters(self, filters, **kwargs):
558557
""" Converter of provided nested filter configuration to linear inner representation. """
558+
filter_route = kwargs.get('filter_route', '')
559+
orm_route = kwargs.get('orm_route', '')
560+
orm_model = kwargs.get('orm_model')
561+
select_tree = kwargs.get('select_tree')
562+
parent_qs = kwargs.get('parent_qs')
563+
distinct = kwargs.get('distinct', False)
564+
559565
_model = orm_model or self.MODEL
560566

561567
if not orm_route:
@@ -591,16 +597,23 @@ def _build_filters(self, filters, filter_route='', orm_route='',
591597

592598
qs = item.get('qs')
593599
tree, p_qs = self._fill_select_tree(
594-
namespace, related_filter_route, select_tree,
600+
namespace,
601+
related_filter_route,
602+
select_tree,
595603
namespace=True,
596604
hidden=item.get('hidden', False),
597605
qs=qs,
598606
parent_qs=parent_qs,
599607
)
600608

601609
self._build_filters(
602-
item.get('filters', []), related_filter_route + '.',
603-
related_orm_route, related_model, select_tree=tree, parent_qs=p_qs,
610+
item.get('filters', []),
611+
filter_route=related_filter_route + '.',
612+
orm_route=related_orm_route,
613+
orm_model=related_model,
614+
select_tree=tree,
615+
parent_qs=p_qs,
616+
distinct=item.get('distinct', distinct),
604617
)
605618
continue
606619

@@ -624,15 +637,20 @@ def _build_filters(self, filters, filter_route='', orm_route='',
624637

625638
self._check_use_repr(item, field_filter_route)
626639
self._check_dynamic(item, field_filter_route, filter_route)
627-
self._build_filters_for_common_item(item, field_filter_route, orm_route, _model)
640+
self._build_filters_for_common_item(
641+
item, field_filter_route, orm_route, _model, distinct,
642+
)
628643

629-
def _build_filters_for_common_item(self, item, field_filter_route, orm_route, orm_model):
644+
def _build_filters_for_common_item(
645+
self, item, field_filter_route, orm_route, orm_model, distinct,
646+
):
630647
filter_name = item['filter']
631648
field = item.get('field')
632649
kwargs = {
633650
prop: item.get(prop)
634-
for prop in ('lookups', 'use_repr', 'null_values', 'distinct', 'openapi', 'hidden')
651+
for prop in ('lookups', 'use_repr', 'null_values', 'openapi', 'hidden')
635652
}
653+
kwargs['distinct'] = item.get('distinct', distinct)
636654

637655
if 'sources' in item:
638656
items = []

tests/dj_rf/filters.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# Copyright © 2021 Ingram Micro Inc. All rights reserved.
2+
# Copyright © 2022 Ingram Micro Inc. All rights reserved.
33
#
44
from cachetools import LFUCache, LRUCache
55

@@ -20,6 +20,7 @@
2020
}, {
2121
'namespace': 'publisher',
2222
'filters': ['id'],
23+
'distinct': False,
2324
'qs': NSR('publisher'),
2425
}]
2526

@@ -63,6 +64,7 @@ class BooksFilterClass(RQLFilterClass):
6364
}, {
6465
'namespace': 'author',
6566
'filters': AUTHOR_FILTERS,
67+
'distinct': True,
6668
'qs': SR('author', 'author__publisher'),
6769
}, {
6870
'namespace': 'page',

tests/test_filter_cls/test_apply_filters.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# Copyright © 2021 Ingram Micro Inc. All rights reserved.
2+
# Copyright © 2022 Ingram Micro Inc. All rights reserved.
33
#
44

55
from functools import partial
@@ -570,6 +570,18 @@ def test_distinct_on_field_no_field_in_filter():
570570
assert not qs.query.distinct
571571

572572

573+
@pytest.mark.django_db
574+
def test_default_distinct_from_namespace():
575+
_, qs = BooksFilterClass(book_qs).apply_filters('[email protected]')
576+
assert qs.query.distinct
577+
578+
579+
@pytest.mark.django_db
580+
def test_redefined_distinct_from_namespace():
581+
_, qs = BooksFilterClass(book_qs).apply_filters('author.publisher.id=1')
582+
assert not qs.query.distinct
583+
584+
573585
@pytest.mark.django_db
574586
def test_distinct_on_field_field_in_filter():
575587
_, qs = BooksFilterClass(book_qs).apply_filters('status=planning')

0 commit comments

Comments
 (0)