From 30cd430c2747e422174399a0f2459e0036aee166 Mon Sep 17 00:00:00 2001 From: Mardanov Timur Rustemovich Date: Wed, 16 Jan 2019 13:42:02 +0300 Subject: [PATCH] fix --- graphene_django/filter/fields.py | 17 ++++++++++++++++- graphene_django/filter/utils.py | 9 +++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/graphene_django/filter/fields.py b/graphene_django/filter/fields.py index 2b3d787..dd2ec27 100644 --- a/graphene_django/filter/fields.py +++ b/graphene_django/filter/fields.py @@ -113,6 +113,8 @@ class DjangoFilterConnectionField(DjangoConnectionField): if not _parent: _parent = is_parent_set(info) + source_class = default_manager.source + def new_resolver(root, info, **args): #filters @@ -122,7 +124,20 @@ class DjangoFilterConnectionField(DjangoConnectionField): qs = default_manager.filter() if filters: - qs = qs.filter().filter(make_qs(filters)) + base_filters, relationship_filters = make_qs(filters) + qs = qs.filter().filter(base_filters) + + if relationship_filters: + rels = {} + for item in relationship_filters.items(): + rel_field = getattr(source_class, item[0], None) + if rel_field is None: + raise Exception('This relationship field not found ' + 'in source class') + node_class = rel_field.build_manager(0, item[0]).definition['node_class'] + rels[item[0]] = node_class.nodes.get(uid=item[1]) + for item in rels.items(): + qs = qs.has(**{item[0]: item[1]}) if order: qs = qs.order_by(order) diff --git a/graphene_django/filter/utils.py b/graphene_django/filter/utils.py index cf0da3a..1295d2a 100644 --- a/graphene_django/filter/utils.py +++ b/graphene_django/filter/utils.py @@ -14,11 +14,16 @@ def get_filterset_class(filterset_class, **meta): def make_qs(filters): + relationship_filters = {} for item in filters.items(): - if '__equal' in item[0]: + if item[0].endswith('__equal'): filters.pop(item[0]) filters[item[0].split("__")[0]] = item[1] - return reduce(lambda init, nx: init & Q(**{nx[0]: nx[1]}), filters.items(), Q()) + elif item[0].endswith('__has'): + filters.pop(item[0]) + relationship_filters[item[0].split("__")[0]] = item[1] + base_filters = reduce(lambda init, nx: init & Q(**{nx[0]: nx[1]}), filters.items(), Q()) + return base_filters, relationship_filters def get_filtering_args_from_filterset(filterset_class, type):