mirror of
https://github.com/graphql-python/graphene-django.git
synced 2025-05-16 05:43:47 +03:00
Merge branch 'master' into v3
This commit is contained in:
commit
9b41472922
1
.github/workflows/deploy.yml
vendored
1
.github/workflows/deploy.yml
vendored
|
@ -17,6 +17,7 @@ jobs:
|
||||||
python-version: 3.8
|
python-version: 3.8
|
||||||
- name: Build wheel and source tarball
|
- name: Build wheel and source tarball
|
||||||
run: |
|
run: |
|
||||||
|
pip install wheel
|
||||||
python setup.py sdist bdist_wheel
|
python setup.py sdist bdist_wheel
|
||||||
- name: Publish a Python distribution to PyPI
|
- name: Publish a Python distribution to PyPI
|
||||||
uses: pypa/gh-action-pypi-publish@v1.1.0
|
uses: pypa/gh-action-pypi-publish@v1.1.0
|
||||||
|
|
12
docs/extra-types.rst
Normal file
12
docs/extra-types.rst
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
Extra Types
|
||||||
|
===========
|
||||||
|
|
||||||
|
Here are some libraries that provide common types for Django specific fields.
|
||||||
|
|
||||||
|
|
||||||
|
GeoDjango
|
||||||
|
---------
|
||||||
|
|
||||||
|
Use the graphene-gis_ library to add GeoDjango types to your Schema.
|
||||||
|
|
||||||
|
.. _graphene-gis: https://github.com/EverWinter23/graphene-gis
|
83
docs/fields.rst
Normal file
83
docs/fields.rst
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
Fields
|
||||||
|
======
|
||||||
|
|
||||||
|
Graphene-Django provides some useful fields to help integrate Django with your GraphQL
|
||||||
|
Schema.
|
||||||
|
|
||||||
|
DjangoListField
|
||||||
|
---------------
|
||||||
|
|
||||||
|
``DjangoListField`` allows you to define a list of :ref:`DjangoObjectType<queries-objecttypes>`'s. By default it will resolve the default queryset of the Django model.
|
||||||
|
|
||||||
|
.. code:: python
|
||||||
|
|
||||||
|
from graphene import ObjectType, Schema
|
||||||
|
from graphene_django import DjangoListField
|
||||||
|
|
||||||
|
class RecipeType(DjangoObjectType):
|
||||||
|
class Meta:
|
||||||
|
model = Recipe
|
||||||
|
fields = ("title", "instructions")
|
||||||
|
|
||||||
|
class Query(ObjectType):
|
||||||
|
recipes = DjangoListField(RecipeType)
|
||||||
|
|
||||||
|
schema = Schema(query=Query)
|
||||||
|
|
||||||
|
The above code results in the following schema definition:
|
||||||
|
|
||||||
|
.. code::
|
||||||
|
|
||||||
|
schema {
|
||||||
|
query: Query
|
||||||
|
}
|
||||||
|
|
||||||
|
type Query {
|
||||||
|
recipes: [RecipeType!]
|
||||||
|
}
|
||||||
|
|
||||||
|
type RecipeType {
|
||||||
|
title: String!
|
||||||
|
instructions: String!
|
||||||
|
}
|
||||||
|
|
||||||
|
Custom resolvers
|
||||||
|
****************
|
||||||
|
|
||||||
|
If your ``DjangoObjectType`` has defined a custom
|
||||||
|
:ref:`get_queryset<django-objecttype-get-queryset>` method, when resolving a
|
||||||
|
``DjangoListField`` it will be called with either the return of the field
|
||||||
|
resolver (if one is defined) or the default queryeset from the Django model.
|
||||||
|
|
||||||
|
For example the following schema will only resolve recipes which have been
|
||||||
|
published and have a title:
|
||||||
|
|
||||||
|
.. code:: python
|
||||||
|
|
||||||
|
from graphene import ObjectType, Schema
|
||||||
|
from graphene_django import DjangoListField
|
||||||
|
|
||||||
|
class RecipeType(DjangoObjectType):
|
||||||
|
class Meta:
|
||||||
|
model = Recipe
|
||||||
|
fields = ("title", "instructions")
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_queryset(cls, queryset, info):
|
||||||
|
# Filter out recipes that have no title
|
||||||
|
return queryset.exclude(title__exact="")
|
||||||
|
|
||||||
|
class Query(ObjectType):
|
||||||
|
recipes = DjangoListField(RecipeType)
|
||||||
|
|
||||||
|
def resolve_recipes(parent, info):
|
||||||
|
# Only get recipes that have been published
|
||||||
|
return Recipe.objects.filter(published=True)
|
||||||
|
|
||||||
|
schema = Schema(query=Query)
|
||||||
|
|
||||||
|
|
||||||
|
DjangoConnectionField
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
*TODO*
|
|
@ -25,6 +25,8 @@ For more advanced use, check out the Relay tutorial.
|
||||||
tutorial-relay
|
tutorial-relay
|
||||||
schema
|
schema
|
||||||
queries
|
queries
|
||||||
|
fields
|
||||||
|
extra-types
|
||||||
mutations
|
mutations
|
||||||
filtering
|
filtering
|
||||||
authorization
|
authorization
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
.. _queries-objecttypes:
|
||||||
|
|
||||||
Queries & ObjectTypes
|
Queries & ObjectTypes
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
|
@ -205,6 +207,8 @@ need to create the most basic class for this to work:
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Category
|
model = Category
|
||||||
|
|
||||||
|
.. _django-objecttype-get-queryset:
|
||||||
|
|
||||||
Default QuerySet
|
Default QuerySet
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
|
from .fields import DjangoConnectionField, DjangoListField
|
||||||
from .types import DjangoObjectType
|
from .types import DjangoObjectType
|
||||||
from .fields import DjangoConnectionField
|
|
||||||
|
|
||||||
__version__ = "2.9.1"
|
__version__ = "2.10.0"
|
||||||
|
|
||||||
__all__ = ["__version__", "DjangoObjectType", "DjangoConnectionField"]
|
__all__ = [
|
||||||
|
"__version__",
|
||||||
|
"DjangoObjectType",
|
||||||
|
"DjangoListField",
|
||||||
|
"DjangoConnectionField",
|
||||||
|
]
|
||||||
|
|
|
@ -154,13 +154,9 @@ def convert_field_to_int(field, registry=None):
|
||||||
return Int(description=field.help_text, required=not field.null)
|
return Int(description=field.help_text, required=not field.null)
|
||||||
|
|
||||||
|
|
||||||
|
@convert_django_field.register(models.NullBooleanField)
|
||||||
@convert_django_field.register(models.BooleanField)
|
@convert_django_field.register(models.BooleanField)
|
||||||
def convert_field_to_boolean(field, registry=None):
|
def convert_field_to_boolean(field, registry=None):
|
||||||
return NonNull(Boolean, description=field.help_text)
|
|
||||||
|
|
||||||
|
|
||||||
@convert_django_field.register(models.NullBooleanField)
|
|
||||||
def convert_field_to_nullboolean(field, registry=None):
|
|
||||||
return Boolean(description=field.help_text, required=not field.null)
|
return Boolean(description=field.help_text, required=not field.null)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -38,16 +38,21 @@ class DjangoListField(Field):
|
||||||
def model(self):
|
def model(self):
|
||||||
return self._underlying_type._meta.model
|
return self._underlying_type._meta.model
|
||||||
|
|
||||||
|
def get_default_queryset(self):
|
||||||
|
return self.model._default_manager.get_queryset()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def list_resolver(django_object_type, resolver, root, info, **args):
|
def list_resolver(
|
||||||
|
django_object_type, resolver, default_queryset, root, info, **args
|
||||||
|
):
|
||||||
queryset = maybe_queryset(resolver(root, info, **args))
|
queryset = maybe_queryset(resolver(root, info, **args))
|
||||||
if queryset is None:
|
if queryset is None:
|
||||||
# Default to Django Model queryset
|
queryset = default_queryset
|
||||||
# N.B. This happens if DjangoListField is used in the top level Query object
|
|
||||||
model_manager = django_object_type._meta.model.objects
|
if isinstance(queryset, QuerySet):
|
||||||
queryset = maybe_queryset(
|
# Pass queryset to the DjangoObjectType get_queryset method
|
||||||
django_object_type.get_queryset(model_manager, info)
|
queryset = maybe_queryset(django_object_type.get_queryset(queryset, info))
|
||||||
)
|
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
def get_resolver(self, parent_resolver):
|
def get_resolver(self, parent_resolver):
|
||||||
|
@ -55,7 +60,12 @@ class DjangoListField(Field):
|
||||||
if isinstance(_type, NonNull):
|
if isinstance(_type, NonNull):
|
||||||
_type = _type.of_type
|
_type = _type.of_type
|
||||||
django_object_type = _type.of_type.of_type
|
django_object_type = _type.of_type.of_type
|
||||||
return partial(self.list_resolver, django_object_type, parent_resolver)
|
return partial(
|
||||||
|
self.list_resolver,
|
||||||
|
django_object_type,
|
||||||
|
parent_resolver,
|
||||||
|
self.get_default_queryset(),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class DjangoConnectionField(ConnectionField):
|
class DjangoConnectionField(ConnectionField):
|
||||||
|
|
|
@ -25,12 +25,19 @@ from .models import Article, Film, FilmDetails, Reporter
|
||||||
|
|
||||||
|
|
||||||
def assert_conversion(django_field, graphene_field, *args, **kwargs):
|
def assert_conversion(django_field, graphene_field, *args, **kwargs):
|
||||||
field = django_field(help_text="Custom Help Text", null=True, *args, **kwargs)
|
_kwargs = kwargs.copy()
|
||||||
|
if "null" not in kwargs:
|
||||||
|
_kwargs["null"] = True
|
||||||
|
field = django_field(help_text="Custom Help Text", *args, **_kwargs)
|
||||||
graphene_type = convert_django_field(field)
|
graphene_type = convert_django_field(field)
|
||||||
assert isinstance(graphene_type, graphene_field)
|
assert isinstance(graphene_type, graphene_field)
|
||||||
field = graphene_type.Field()
|
field = graphene_type.Field()
|
||||||
assert field.description == "Custom Help Text"
|
assert field.description == "Custom Help Text"
|
||||||
nonnull_field = django_field(null=False, *args, **kwargs)
|
|
||||||
|
_kwargs = kwargs.copy()
|
||||||
|
if "null" not in kwargs:
|
||||||
|
_kwargs["null"] = False
|
||||||
|
nonnull_field = django_field(*args, **_kwargs)
|
||||||
if not nonnull_field.null:
|
if not nonnull_field.null:
|
||||||
nonnull_graphene_type = convert_django_field(nonnull_field)
|
nonnull_graphene_type = convert_django_field(nonnull_field)
|
||||||
nonnull_field = nonnull_graphene_type.Field()
|
nonnull_field = nonnull_graphene_type.Field()
|
||||||
|
@ -126,7 +133,12 @@ def test_should_integer_convert_int():
|
||||||
|
|
||||||
|
|
||||||
def test_should_boolean_convert_boolean():
|
def test_should_boolean_convert_boolean():
|
||||||
field = assert_conversion(models.BooleanField, graphene.NonNull)
|
assert_conversion(models.BooleanField, graphene.Boolean, null=True)
|
||||||
|
|
||||||
|
|
||||||
|
def test_should_boolean_convert_non_null_boolean():
|
||||||
|
field = assert_conversion(models.BooleanField, graphene.Boolean, null=False)
|
||||||
|
assert isinstance(field.type, graphene.NonNull)
|
||||||
assert field.type.of_type == graphene.Boolean
|
assert field.type.of_type == graphene.Boolean
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import datetime
|
import datetime
|
||||||
|
from django.db.models import Count
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
@ -141,13 +142,26 @@ class TestDjangoListField:
|
||||||
pub_date_time=datetime.datetime.now(),
|
pub_date_time=datetime.datetime.now(),
|
||||||
editor=r1,
|
editor=r1,
|
||||||
)
|
)
|
||||||
|
ArticleModel.objects.create(
|
||||||
|
headline="Not so good news",
|
||||||
|
reporter=r1,
|
||||||
|
pub_date=datetime.date.today(),
|
||||||
|
pub_date_time=datetime.datetime.now(),
|
||||||
|
editor=r1,
|
||||||
|
)
|
||||||
|
|
||||||
result = schema.execute(query)
|
result = schema.execute(query)
|
||||||
|
|
||||||
assert not result.errors
|
assert not result.errors
|
||||||
assert result.data == {
|
assert result.data == {
|
||||||
"reporters": [
|
"reporters": [
|
||||||
{"firstName": "Tara", "articles": [{"headline": "Amazing news"}]},
|
{
|
||||||
|
"firstName": "Tara",
|
||||||
|
"articles": [
|
||||||
|
{"headline": "Amazing news"},
|
||||||
|
{"headline": "Not so good news"},
|
||||||
|
],
|
||||||
|
},
|
||||||
{"firstName": "Debra", "articles": []},
|
{"firstName": "Debra", "articles": []},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -163,8 +177,8 @@ class TestDjangoListField:
|
||||||
model = ReporterModel
|
model = ReporterModel
|
||||||
fields = ("first_name", "articles")
|
fields = ("first_name", "articles")
|
||||||
|
|
||||||
def resolve_reporters(reporter, info):
|
def resolve_articles(reporter, info):
|
||||||
return reporter.articles.all()
|
return reporter.articles.filter(headline__contains="Amazing")
|
||||||
|
|
||||||
class Query(ObjectType):
|
class Query(ObjectType):
|
||||||
reporters = DjangoListField(Reporter)
|
reporters = DjangoListField(Reporter)
|
||||||
|
@ -192,6 +206,13 @@ class TestDjangoListField:
|
||||||
pub_date_time=datetime.datetime.now(),
|
pub_date_time=datetime.datetime.now(),
|
||||||
editor=r1,
|
editor=r1,
|
||||||
)
|
)
|
||||||
|
ArticleModel.objects.create(
|
||||||
|
headline="Not so good news",
|
||||||
|
reporter=r1,
|
||||||
|
pub_date=datetime.date.today(),
|
||||||
|
pub_date_time=datetime.datetime.now(),
|
||||||
|
editor=r1,
|
||||||
|
)
|
||||||
|
|
||||||
result = schema.execute(query)
|
result = schema.execute(query)
|
||||||
|
|
||||||
|
@ -202,3 +223,155 @@ class TestDjangoListField:
|
||||||
{"firstName": "Debra", "articles": []},
|
{"firstName": "Debra", "articles": []},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def test_get_queryset_filter(self):
|
||||||
|
class Reporter(DjangoObjectType):
|
||||||
|
class Meta:
|
||||||
|
model = ReporterModel
|
||||||
|
fields = ("first_name", "articles")
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_queryset(cls, queryset, info):
|
||||||
|
# Only get reporters with at least 1 article
|
||||||
|
return queryset.annotate(article_count=Count("articles")).filter(
|
||||||
|
article_count__gt=0
|
||||||
|
)
|
||||||
|
|
||||||
|
class Query(ObjectType):
|
||||||
|
reporters = DjangoListField(Reporter)
|
||||||
|
|
||||||
|
def resolve_reporters(_, info):
|
||||||
|
return ReporterModel.objects.all()
|
||||||
|
|
||||||
|
schema = Schema(query=Query)
|
||||||
|
|
||||||
|
query = """
|
||||||
|
query {
|
||||||
|
reporters {
|
||||||
|
firstName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
r1 = ReporterModel.objects.create(first_name="Tara", last_name="West")
|
||||||
|
ReporterModel.objects.create(first_name="Debra", last_name="Payne")
|
||||||
|
|
||||||
|
ArticleModel.objects.create(
|
||||||
|
headline="Amazing news",
|
||||||
|
reporter=r1,
|
||||||
|
pub_date=datetime.date.today(),
|
||||||
|
pub_date_time=datetime.datetime.now(),
|
||||||
|
editor=r1,
|
||||||
|
)
|
||||||
|
|
||||||
|
result = schema.execute(query)
|
||||||
|
|
||||||
|
assert not result.errors
|
||||||
|
assert result.data == {"reporters": [{"firstName": "Tara"},]}
|
||||||
|
|
||||||
|
def test_resolve_list(self):
|
||||||
|
"""Resolving a plain list should work (and not call get_queryset)"""
|
||||||
|
|
||||||
|
class Reporter(DjangoObjectType):
|
||||||
|
class Meta:
|
||||||
|
model = ReporterModel
|
||||||
|
fields = ("first_name", "articles")
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_queryset(cls, queryset, info):
|
||||||
|
# Only get reporters with at least 1 article
|
||||||
|
return queryset.annotate(article_count=Count("articles")).filter(
|
||||||
|
article_count__gt=0
|
||||||
|
)
|
||||||
|
|
||||||
|
class Query(ObjectType):
|
||||||
|
reporters = DjangoListField(Reporter)
|
||||||
|
|
||||||
|
def resolve_reporters(_, info):
|
||||||
|
return [ReporterModel.objects.get(first_name="Debra")]
|
||||||
|
|
||||||
|
schema = Schema(query=Query)
|
||||||
|
|
||||||
|
query = """
|
||||||
|
query {
|
||||||
|
reporters {
|
||||||
|
firstName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
r1 = ReporterModel.objects.create(first_name="Tara", last_name="West")
|
||||||
|
ReporterModel.objects.create(first_name="Debra", last_name="Payne")
|
||||||
|
|
||||||
|
ArticleModel.objects.create(
|
||||||
|
headline="Amazing news",
|
||||||
|
reporter=r1,
|
||||||
|
pub_date=datetime.date.today(),
|
||||||
|
pub_date_time=datetime.datetime.now(),
|
||||||
|
editor=r1,
|
||||||
|
)
|
||||||
|
|
||||||
|
result = schema.execute(query)
|
||||||
|
|
||||||
|
assert not result.errors
|
||||||
|
assert result.data == {"reporters": [{"firstName": "Debra"},]}
|
||||||
|
|
||||||
|
def test_get_queryset_foreign_key(self):
|
||||||
|
class Article(DjangoObjectType):
|
||||||
|
class Meta:
|
||||||
|
model = ArticleModel
|
||||||
|
fields = ("headline",)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_queryset(cls, queryset, info):
|
||||||
|
# Rose tinted glasses
|
||||||
|
return queryset.exclude(headline__contains="Not so good")
|
||||||
|
|
||||||
|
class Reporter(DjangoObjectType):
|
||||||
|
class Meta:
|
||||||
|
model = ReporterModel
|
||||||
|
fields = ("first_name", "articles")
|
||||||
|
|
||||||
|
class Query(ObjectType):
|
||||||
|
reporters = DjangoListField(Reporter)
|
||||||
|
|
||||||
|
schema = Schema(query=Query)
|
||||||
|
|
||||||
|
query = """
|
||||||
|
query {
|
||||||
|
reporters {
|
||||||
|
firstName
|
||||||
|
articles {
|
||||||
|
headline
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
r1 = ReporterModel.objects.create(first_name="Tara", last_name="West")
|
||||||
|
ReporterModel.objects.create(first_name="Debra", last_name="Payne")
|
||||||
|
|
||||||
|
ArticleModel.objects.create(
|
||||||
|
headline="Amazing news",
|
||||||
|
reporter=r1,
|
||||||
|
pub_date=datetime.date.today(),
|
||||||
|
pub_date_time=datetime.datetime.now(),
|
||||||
|
editor=r1,
|
||||||
|
)
|
||||||
|
ArticleModel.objects.create(
|
||||||
|
headline="Not so good news",
|
||||||
|
reporter=r1,
|
||||||
|
pub_date=datetime.date.today(),
|
||||||
|
pub_date_time=datetime.datetime.now(),
|
||||||
|
editor=r1,
|
||||||
|
)
|
||||||
|
|
||||||
|
result = schema.execute(query)
|
||||||
|
|
||||||
|
assert not result.errors
|
||||||
|
assert result.data == {
|
||||||
|
"reporters": [
|
||||||
|
{"firstName": "Tara", "articles": [{"headline": "Amazing news"},],},
|
||||||
|
{"firstName": "Debra", "articles": []},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
|
@ -312,6 +312,17 @@ def test_django_objecttype_fields():
|
||||||
assert fields == ["id", "email", "films"]
|
assert fields == ["id", "email", "films"]
|
||||||
|
|
||||||
|
|
||||||
|
@with_local_registry
|
||||||
|
def test_django_objecttype_fields_empty():
|
||||||
|
class Reporter(DjangoObjectType):
|
||||||
|
class Meta:
|
||||||
|
model = ReporterModel
|
||||||
|
fields = ()
|
||||||
|
|
||||||
|
fields = list(Reporter._meta.fields.keys())
|
||||||
|
assert fields == []
|
||||||
|
|
||||||
|
|
||||||
@with_local_registry
|
@with_local_registry
|
||||||
def test_django_objecttype_only_fields_and_fields():
|
def test_django_objecttype_only_fields_and_fields():
|
||||||
with pytest.raises(Exception):
|
with pytest.raises(Exception):
|
||||||
|
|
|
@ -32,9 +32,15 @@ def construct_fields(
|
||||||
|
|
||||||
fields = OrderedDict()
|
fields = OrderedDict()
|
||||||
for name, field in _model_fields:
|
for name, field in _model_fields:
|
||||||
is_not_in_only = only_fields and name not in only_fields
|
is_not_in_only = (
|
||||||
|
only_fields is not None
|
||||||
|
and only_fields != ALL_FIELDS
|
||||||
|
and name not in only_fields
|
||||||
|
)
|
||||||
# is_already_created = name in options.fields
|
# is_already_created = name in options.fields
|
||||||
is_excluded = name in exclude_fields # or is_already_created
|
is_excluded = (
|
||||||
|
exclude_fields is not None and name in exclude_fields
|
||||||
|
) # or is_already_created
|
||||||
# https://docs.djangoproject.com/en/1.10/ref/models/fields/#django.db.models.ForeignKey.related_query_name
|
# https://docs.djangoproject.com/en/1.10/ref/models/fields/#django.db.models.ForeignKey.related_query_name
|
||||||
is_no_backref = str(name).endswith("+")
|
is_no_backref = str(name).endswith("+")
|
||||||
if is_not_in_only or is_excluded or is_no_backref:
|
if is_not_in_only or is_excluded or is_no_backref:
|
||||||
|
@ -62,6 +68,7 @@ def construct_fields(
|
||||||
def validate_fields(type_, model, fields, only_fields, exclude_fields):
|
def validate_fields(type_, model, fields, only_fields, exclude_fields):
|
||||||
# Validate the given fields against the model's fields and custom fields
|
# Validate the given fields against the model's fields and custom fields
|
||||||
all_field_names = set(fields.keys())
|
all_field_names = set(fields.keys())
|
||||||
|
only_fields = only_fields if only_fields is not ALL_FIELDS else ()
|
||||||
for name in only_fields or ():
|
for name in only_fields or ():
|
||||||
if name in all_field_names:
|
if name in all_field_names:
|
||||||
continue
|
continue
|
||||||
|
@ -139,10 +146,10 @@ class DjangoObjectType(ObjectType):
|
||||||
model=None,
|
model=None,
|
||||||
registry=None,
|
registry=None,
|
||||||
skip_registry=False,
|
skip_registry=False,
|
||||||
only_fields=(), # deprecated in favour of `fields`
|
only_fields=None, # deprecated in favour of `fields`
|
||||||
fields=(),
|
fields=None,
|
||||||
exclude_fields=(), # deprecated in favour of `exclude`
|
exclude_fields=None, # deprecated in favour of `exclude`
|
||||||
exclude=(),
|
exclude=None,
|
||||||
filter_fields=None,
|
filter_fields=None,
|
||||||
filterset_class=None,
|
filterset_class=None,
|
||||||
connection=None,
|
connection=None,
|
||||||
|
@ -197,9 +204,6 @@ class DjangoObjectType(ObjectType):
|
||||||
"Got %s." % type(fields).__name__
|
"Got %s." % type(fields).__name__
|
||||||
)
|
)
|
||||||
|
|
||||||
if fields == ALL_FIELDS:
|
|
||||||
fields = None
|
|
||||||
|
|
||||||
# Alias exclude_fields -> exclude
|
# Alias exclude_fields -> exclude
|
||||||
if exclude_fields and exclude:
|
if exclude_fields and exclude:
|
||||||
raise Exception("Can't set both exclude_fields and exclude")
|
raise Exception("Can't set both exclude_fields and exclude")
|
||||||
|
|
|
@ -14,6 +14,7 @@ from graphql.error import format_error as format_graphql_error
|
||||||
from graphql.execution import ExecutionResult
|
from graphql.execution import ExecutionResult
|
||||||
|
|
||||||
from graphene import Schema
|
from graphene import Schema
|
||||||
|
from graphql.execution.middleware import MiddlewareManager
|
||||||
|
|
||||||
from .settings import graphene_settings
|
from .settings import graphene_settings
|
||||||
|
|
||||||
|
@ -78,6 +79,9 @@ class GraphQLView(View):
|
||||||
|
|
||||||
self.schema = self.schema or schema
|
self.schema = self.schema or schema
|
||||||
if middleware is not None:
|
if middleware is not None:
|
||||||
|
if isinstance(middleware, MiddlewareManager):
|
||||||
|
self.middleware = middleware
|
||||||
|
else:
|
||||||
self.middleware = list(instantiate_middleware(middleware))
|
self.middleware = list(instantiate_middleware(middleware))
|
||||||
self.root_value = root_value
|
self.root_value = root_value
|
||||||
self.pretty = self.pretty or pretty
|
self.pretty = self.pretty or pretty
|
||||||
|
|
Loading…
Reference in New Issue
Block a user