graphql-python / graphql-python/graphene-django

Separating django-filter from relay connection

Open
#206 35 comments 37 reactions 0 assignees View on GitHub
✨enhancement Docs enhancement
Dominant language
Python
Stars
4.4k
Forks
760
PR merge metrics
No merged PRs in 30d

Description

### Problem
Right now, the use of django-filter is tightly coupled with the use of the relay graphql format. I think it would be useful to separate the two so that filtering can be applied to a normal graphql list as well.

### Solution
Pull out the django-filter logic from [DjangoFilterConnectionField](https://github.com/graphql-python/graphene-django/blob/master/graphene_django/filter/fields.py#L10) into something like `DjangoFilterMixin`. Then apply that mixin to `DjangoFilterConnectionField` and a new `DjangoFilterField`.

I've done something like this with success already. There's a lot of copy-pasta though, and I think others could benefit from it. Here's what we are currently using.
```python
from graphene import Field
from graphene_django.filter.utils import (
get_filtering_args_from_filterset,
get_filterset_class
)

class DjangoFilterField(Field):

def __init__(self, _type, fields=None, extra_filter_meta=None,
filterset_class=None, *args, **kwargs):

_fields = _type._meta.filter_fields
_model = _type._meta.model

self.fields = fields or _fields
meta = dict(model=_model, fields=self.fields)
if extra_filter_meta:
meta.update(extra_filter_meta)
self.filterset_class = get_filterset_class(filterset_class, **meta)
self.filtering_args = get_filtering_args_from_filterset(self.filterset_class, _type)
kwargs.setdefault('args', {})
kwargs['args'].update(self.filtering_args)
super().__init__(List(_type), *args, **kwargs)

@staticmethod
def list_resolver(manager, filterset_class, filtering_args,
root, args, context, info):
filter_kwargs = {k: v for k, v in args.items() if k in filtering_args}
qs = manager.get_queryset()
qs = filterset_class(data=filter_kwargs, queryset=qs).qs
return qs

def get_resolver(self, parent_resolver):
return partial(self.list_resolver, self.type._meta.model._default_manager,
self.filterset_class, self.filtering_args)
```

@syrusakbary
If this sounds like a good idea, I'd be happy to whip up the PR.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.