mirror of
https://github.com/graphql-python/graphene.git
synced 2025-02-02 20:54:16 +03:00
Filtering now available on nodes without defining fields
This commit is contained in:
parent
afd7aa8d72
commit
66189be4a9
|
@ -20,6 +20,7 @@ class DjangoConnectionField(ConnectionField):
|
|||
|
||||
|
||||
class ConnectionOrListField(Field):
|
||||
connection_field_class = ConnectionField
|
||||
|
||||
def internal_type(self, schema):
|
||||
model_field = self.type
|
||||
|
@ -27,7 +28,7 @@ class ConnectionOrListField(Field):
|
|||
if not field_object_type:
|
||||
raise SkipField()
|
||||
if is_node(field_object_type):
|
||||
field = ConnectionField(field_object_type)
|
||||
field = self.connection_field_class(field_object_type)
|
||||
else:
|
||||
field = Field(List(field_object_type))
|
||||
field.contribute_to_class(self.object_type, self.attname)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
try:
|
||||
import django_filters # noqa
|
||||
except:
|
||||
from graphene.contrib.django.utils import DJANGO_FILTER_INSTALLED
|
||||
|
||||
if not DJANGO_FILTER_INSTALLED:
|
||||
raise Exception(
|
||||
"Use of django filtering requires the django-filter package "
|
||||
"be installed. You can do so using `pip install django-filter`"
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
from .utils import DJANGO_FILTER_INSTALLED
|
||||
from ...core.classtypes.objecttype import ObjectTypeOptions
|
||||
from ...relay.types import Node
|
||||
from ...relay.utils import is_node
|
||||
|
||||
VALID_ATTRS = ('model', 'only_fields', 'exclude_fields',
|
||||
'filter_fields', 'filter_order_by')
|
||||
VALID_ATTRS = ('model', 'only_fields', 'exclude_fields')
|
||||
|
||||
if DJANGO_FILTER_INSTALLED:
|
||||
VALID_ATTRS += ('filter_fields', 'filter_order_by')
|
||||
|
||||
|
||||
class DjangoOptions(ObjectTypeOptions):
|
||||
|
|
|
@ -1,20 +1,23 @@
|
|||
import pytest
|
||||
|
||||
pytestmark = []
|
||||
from graphene import ObjectType, Schema
|
||||
from graphene.contrib.django.utils import DJANGO_FILTER_INSTALLED
|
||||
from graphene.relay import NodeField
|
||||
|
||||
try:
|
||||
import django_filters
|
||||
except ImportError:
|
||||
pytestmark.append(pytest.mark.skipif(True, reason='django_filters not installed'))
|
||||
else:
|
||||
from graphene.contrib.django.filter import (GlobalIDFilter, DjangoFilterConnectionField,
|
||||
GlobalIDMultipleChoiceFilter)
|
||||
from graphene.contrib.django.tests.filter.filters import ArticleFilter, PetFilter
|
||||
|
||||
from graphene.contrib.django import DjangoNode
|
||||
from graphene.contrib.django.forms import GlobalIDFormField, GlobalIDMultipleChoiceField
|
||||
from graphene.contrib.django.tests.models import Article, Pet, Reporter
|
||||
|
||||
pytestmark = []
|
||||
if DJANGO_FILTER_INSTALLED:
|
||||
import django_filters
|
||||
from graphene.contrib.django.filter import (GlobalIDFilter, DjangoFilterConnectionField,
|
||||
GlobalIDMultipleChoiceFilter)
|
||||
from graphene.contrib.django.tests.filter.filters import ArticleFilter, PetFilter
|
||||
else:
|
||||
pytestmark.append(pytest.mark.skipif(True, reason='django_filters not installed'))
|
||||
|
||||
pytestmark.append(pytest.mark.django_db)
|
||||
|
||||
|
||||
|
@ -124,6 +127,32 @@ def test_filter_filterset_information_on_meta():
|
|||
assert_orderable(field)
|
||||
|
||||
|
||||
def test_filter_filterset_information_on_meta_related():
|
||||
class ReporterFilterNode(DjangoNode):
|
||||
class Meta:
|
||||
model = Reporter
|
||||
filter_fields = ['first_name', 'articles']
|
||||
filter_order_by = True
|
||||
|
||||
class ArticleFilterNode(DjangoNode):
|
||||
class Meta:
|
||||
model = Article
|
||||
filter_fields = ['headline', 'reporter']
|
||||
filter_order_by = True
|
||||
|
||||
class Query(ObjectType):
|
||||
all_reporters = DjangoFilterConnectionField(ReporterFilterNode)
|
||||
all_articles = DjangoFilterConnectionField(ArticleFilterNode)
|
||||
reporter = NodeField(ReporterFilterNode)
|
||||
article = NodeField(ArticleFilterNode)
|
||||
|
||||
schema = Schema(query=Query)
|
||||
schema.schema # Trigger the schema loading
|
||||
articles_field = schema.get_type('ReporterFilterNode')._meta.fields_map['articles']
|
||||
assert_arguments(articles_field, 'headline', 'reporter')
|
||||
assert_orderable(articles_field)
|
||||
|
||||
|
||||
def test_global_id_field_implicit():
|
||||
field = DjangoFilterConnectionField(ArticleNode, fields=['id'])
|
||||
filterset_class = field.resolver_fn.get_filterset_class()
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import pytest
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
|
||||
try:
|
||||
import django_filters # noqa
|
||||
except ImportError:
|
||||
pytestmark = pytest.mark.skipif(True, reason='django_filters not installed')
|
||||
else:
|
||||
from graphene.contrib.django.utils import DJANGO_FILTER_INSTALLED
|
||||
|
||||
if DJANGO_FILTER_INSTALLED:
|
||||
from graphene.contrib.django.filter.resolvers import FilterConnectionResolver
|
||||
from graphene.contrib.django.tests.filter.filters import ReporterFilter, ArticleFilter
|
||||
else:
|
||||
pytestmark = pytest.mark.skipif(True, reason='django_filters not installed')
|
||||
|
||||
from graphene.contrib.django.tests.models import Reporter, Article
|
||||
from graphene.contrib.django.tests.test_resolvers import ReporterNode, ArticleNode
|
||||
|
|
|
@ -5,6 +5,7 @@ from django.db import models
|
|||
|
||||
from ...core.classtypes.objecttype import ObjectType, ObjectTypeMeta
|
||||
from ...relay.types import Connection, Node, NodeMeta
|
||||
from .utils import DJANGO_FILTER_INSTALLED
|
||||
from .converter import convert_django_field
|
||||
from .options import DjangoOptions
|
||||
from .utils import get_reverse_fields, maybe_queryset
|
||||
|
@ -49,6 +50,15 @@ class DjangoObjectTypeMeta(ObjectTypeMeta):
|
|||
return cls
|
||||
|
||||
|
||||
class DjangoFilterObjectTypeMeta():
|
||||
|
||||
def convert_django_field(cls, field):
|
||||
from graphene.contrib.django.filter import DjangoFilterConnectionField
|
||||
field = super(DjangoFilterObjectTypeMeta, cls).convert_django_field(field)
|
||||
field.connection_field_class = DjangoFilterConnectionField
|
||||
return field
|
||||
|
||||
|
||||
class InstanceObjectType(ObjectType):
|
||||
|
||||
class Meta:
|
||||
|
@ -92,7 +102,13 @@ class DjangoConnection(Connection):
|
|||
return super(DjangoConnection, cls).from_list(iterable, *args, **kwargs)
|
||||
|
||||
|
||||
class DjangoNodeMeta(DjangoObjectTypeMeta, NodeMeta):
|
||||
django_node_meta_bases = (DjangoObjectTypeMeta, NodeMeta)
|
||||
# Only include filter functionality if available
|
||||
if DJANGO_FILTER_INSTALLED:
|
||||
django_node_meta_bases = (DjangoFilterObjectTypeMeta,) + django_node_meta_bases
|
||||
|
||||
|
||||
class DjangoNodeMeta(*django_node_meta_bases):
|
||||
pass
|
||||
|
||||
|
||||
|
|
|
@ -7,6 +7,12 @@ from graphene.utils import LazyList
|
|||
|
||||
from graphene import Argument, String
|
||||
|
||||
try:
|
||||
import django_filters # noqa
|
||||
DJANGO_FILTER_INSTALLED = True
|
||||
except ImportError:
|
||||
DJANGO_FILTER_INSTALLED = False
|
||||
|
||||
|
||||
def get_type_for_model(schema, model):
|
||||
schema = schema
|
||||
|
|
Loading…
Reference in New Issue
Block a user