Warn if fields or exclude are not defined on DjangoObjectType (#981)

This commit is contained in:
Radosław Kowalski 2020-06-11 12:09:52 +02:00 committed by GitHub
parent 17146f9b01
commit 1f752b6cad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 150 additions and 1 deletions

View File

@ -111,6 +111,7 @@ If you are using ``DjangoObjectType`` you can define a custom `get_queryset`.
class PostNode(DjangoObjectType): class PostNode(DjangoObjectType):
class Meta: class Meta:
model = Post model = Post
fields = '__all__'
@classmethod @classmethod
def get_queryset(cls, queryset, info): def get_queryset(cls, queryset, info):

View File

@ -45,6 +45,7 @@ For example:
class Meta: class Meta:
# Assume you have an Animal model defined with the following fields # Assume you have an Animal model defined with the following fields
model = Animal model = Animal
fields = '__all__'
filter_fields = ['name', 'genus', 'is_domesticated'] filter_fields = ['name', 'genus', 'is_domesticated']
interfaces = (relay.Node, ) interfaces = (relay.Node, )
@ -75,6 +76,7 @@ You can also make more complex lookup types available:
class AnimalNode(DjangoObjectType): class AnimalNode(DjangoObjectType):
class Meta: class Meta:
model = Animal model = Animal
fields = '__all__'
# Provide more complex lookup types # Provide more complex lookup types
filter_fields = { filter_fields = {
'name': ['exact', 'icontains', 'istartswith'], 'name': ['exact', 'icontains', 'istartswith'],
@ -116,6 +118,7 @@ create your own ``FilterSet``. You can pass it directly as follows:
class Meta: class Meta:
# Assume you have an Animal model defined with the following fields # Assume you have an Animal model defined with the following fields
model = Animal model = Animal
fields = '__all__'
filter_fields = ['name', 'genus', 'is_domesticated'] filter_fields = ['name', 'genus', 'is_domesticated']
interfaces = (relay.Node, ) interfaces = (relay.Node, )
@ -179,6 +182,7 @@ in unison with the ``filter_fields`` parameter:
class AnimalNode(DjangoObjectType): class AnimalNode(DjangoObjectType):
class Meta: class Meta:
model = Animal model = Animal
fields = '__all__'
filterset_class = AnimalFilter filterset_class = AnimalFilter
interfaces = (relay.Node, ) interfaces = (relay.Node, )
@ -236,6 +240,7 @@ Extend the tuple of fields if you want to order by more than one field.
class Meta: class Meta:
name = 'Group' name = 'Group'
model = GroupModel model = GroupModel
fields = '__all__'
interfaces = (relay.Node,) interfaces = (relay.Node,)
def resolve_users(self, info, **kwargs): def resolve_users(self, info, **kwargs):

View File

@ -25,6 +25,7 @@ Simple example
class QuestionType(DjangoObjectType): class QuestionType(DjangoObjectType):
class Meta: class Meta:
model = Question model = Question
fields = '__all__'
class QuestionMutation(graphene.Mutation): class QuestionMutation(graphene.Mutation):
@ -90,6 +91,7 @@ DjangoModelFormMutation
class PetType(DjangoObjectType): class PetType(DjangoObjectType):
class Meta: class Meta:
model = Pet model = Pet
fields = '__all__'
class PetMutation(DjangoModelFormMutation): class PetMutation(DjangoModelFormMutation):
pet = Field(PetType) pet = Field(PetType)

View File

@ -28,6 +28,7 @@ Full example
class QuestionType(DjangoObjectType): class QuestionType(DjangoObjectType):
class Meta: class Meta:
model = Question model = Question
fields = '__all__'
class Query: class Query:
@ -53,6 +54,9 @@ all fields that should be exposed using the fields attribute.
This will make it less likely to result in unintentionally exposing data when This will make it less likely to result in unintentionally exposing data when
your models change. your models change.
Setting neither ``fields`` nor ``exclude`` is deprecated and will raise a warning, you should at least explicitly make
``DjangoObjectType`` include all fields in the model as described below.
``fields`` ``fields``
~~~~~~~~~~ ~~~~~~~~~~
@ -127,6 +131,7 @@ For example the following ``Model`` and ``DjangoObjectType``:
class Pet(DjangoObjectType): class Pet(DjangoObjectType):
class Meta: class Meta:
model = PetModel model = PetModel
fields = '__all__'
Results in the following GraphQL schema definition: Results in the following GraphQL schema definition:
@ -151,6 +156,7 @@ You can disable this automatic conversion by setting
class Pet(DjangoObjectType): class Pet(DjangoObjectType):
class Meta: class Meta:
model = PetModel model = PetModel
fields = '__all__'
convert_choices_to_enum = False convert_choices_to_enum = False
.. code:: .. code::
@ -168,6 +174,7 @@ automatically converted into enums:
class Pet(DjangoObjectType): class Pet(DjangoObjectType):
class Meta: class Meta:
model = PetModel model = PetModel
fields = '__all__'
convert_choices_to_enum = ['kind'] convert_choices_to_enum = ['kind']
**Note:** Setting ``convert_choices_to_enum = []`` is the same as setting it to **Note:** Setting ``convert_choices_to_enum = []`` is the same as setting it to
@ -206,6 +213,7 @@ need to create the most basic class for this to work:
class CategoryType(DjangoObjectType): class CategoryType(DjangoObjectType):
class Meta: class Meta:
model = Category model = Category
fields = '__all__'
.. _django-objecttype-get-queryset: .. _django-objecttype-get-queryset:
@ -224,6 +232,7 @@ Use this to control filtering on the ObjectType level instead of the Query objec
class QuestionType(DjangoObjectType): class QuestionType(DjangoObjectType):
class Meta: class Meta:
model = Question model = Question
fields = '__all__'
@classmethod @classmethod
def get_queryset(cls, queryset, info): def get_queryset(cls, queryset, info):
@ -347,6 +356,7 @@ the core graphene pages for more information on customizing the Relay experience
class QuestionType(DjangoObjectType): class QuestionType(DjangoObjectType):
class Meta: class Meta:
model = Question model = Question
fields = '__all__'
interfaces = (relay.Node,) interfaces = (relay.Node,)

View File

@ -8,11 +8,13 @@
class CategoryType(DjangoObjectType): class CategoryType(DjangoObjectType):
class Meta: class Meta:
model = Category model = Category
fields = '__all__'
class IngredientType(DjangoObjectType): class IngredientType(DjangoObjectType):
class Meta: class Meta:
model = Ingredient model = Ingredient
fields = '__all__'
class Query(object): class Query(object):

View File

@ -157,11 +157,13 @@ Create ``cookbook/ingredients/schema.py`` and type the following:
class CategoryType(DjangoObjectType): class CategoryType(DjangoObjectType):
class Meta: class Meta:
model = Category model = Category
fields = '__all__'
class IngredientType(DjangoObjectType): class IngredientType(DjangoObjectType):
class Meta: class Meta:
model = Ingredient model = Ingredient
fields = '__all__'
class Query(object): class Query(object):

View File

@ -130,6 +130,7 @@ Create ``cookbook/ingredients/schema.py`` and type the following:
class CategoryNode(DjangoObjectType): class CategoryNode(DjangoObjectType):
class Meta: class Meta:
model = Category model = Category
fields = '__all__'
filter_fields = ['name', 'ingredients'] filter_fields = ['name', 'ingredients']
interfaces = (relay.Node, ) interfaces = (relay.Node, )
@ -137,6 +138,7 @@ Create ``cookbook/ingredients/schema.py`` and type the following:
class IngredientNode(DjangoObjectType): class IngredientNode(DjangoObjectType):
class Meta: class Meta:
model = Ingredient model = Ingredient
fields = '__all__'
# Allow for some more advanced filtering here # Allow for some more advanced filtering here
filter_fields = { filter_fields = {
'name': ['exact', 'icontains', 'istartswith'], 'name': ['exact', 'icontains', 'istartswith'],

View File

@ -7,11 +7,13 @@ from .models import Category, Ingredient
class CategoryType(DjangoObjectType): class CategoryType(DjangoObjectType):
class Meta: class Meta:
model = Category model = Category
fields = "__all__"
class IngredientType(DjangoObjectType): class IngredientType(DjangoObjectType):
class Meta: class Meta:
model = Ingredient model = Ingredient
fields = "__all__"
class Query(object): class Query(object):

View File

@ -7,11 +7,13 @@ from .models import Recipe, RecipeIngredient
class RecipeType(DjangoObjectType): class RecipeType(DjangoObjectType):
class Meta: class Meta:
model = Recipe model = Recipe
fields = "__all__"
class RecipeIngredientType(DjangoObjectType): class RecipeIngredientType(DjangoObjectType):
class Meta: class Meta:
model = RecipeIngredient model = RecipeIngredient
fields = "__all__"
class Query(object): class Query(object):

View File

@ -10,6 +10,7 @@ class CategoryNode(DjangoObjectType):
class Meta: class Meta:
model = Category model = Category
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
filter_fields = ["name", "ingredients"] filter_fields = ["name", "ingredients"]
@ -18,6 +19,7 @@ class IngredientNode(DjangoObjectType):
model = Ingredient model = Ingredient
# Allow for some more advanced filtering here # Allow for some more advanced filtering here
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
filter_fields = { filter_fields = {
"name": ["exact", "icontains", "istartswith"], "name": ["exact", "icontains", "istartswith"],
"notes": ["exact", "icontains"], "notes": ["exact", "icontains"],

View File

@ -8,6 +8,7 @@ class RecipeNode(DjangoObjectType):
class Meta: class Meta:
model = Recipe model = Recipe
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
filter_fields = ["title", "amounts"] filter_fields = ["title", "amounts"]
@ -16,6 +17,7 @@ class RecipeIngredientNode(DjangoObjectType):
model = RecipeIngredient model = RecipeIngredient
# Allow for some more advanced filtering here # Allow for some more advanced filtering here
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
filter_fields = { filter_fields = {
"ingredient__name": ["exact", "icontains", "istartswith"], "ingredient__name": ["exact", "icontains", "istartswith"],
"recipe": ["exact"], "recipe": ["exact"],

View File

@ -12,6 +12,7 @@ class Ship(DjangoObjectType):
class Meta: class Meta:
model = ShipModel model = ShipModel
interfaces = (relay.Node,) interfaces = (relay.Node,)
fields = "__all__"
@classmethod @classmethod
def get_node(cls, info, id): def get_node(cls, info, id):
@ -22,12 +23,14 @@ class Ship(DjangoObjectType):
class Character(DjangoObjectType): class Character(DjangoObjectType):
class Meta: class Meta:
model = CharacterModel model = CharacterModel
fields = "__all__"
class Faction(DjangoObjectType): class Faction(DjangoObjectType):
class Meta: class Meta:
model = FactionModel model = FactionModel
interfaces = (relay.Node,) interfaces = (relay.Node,)
fields = "__all__"
@classmethod @classmethod
def get_node(cls, info, id): def get_node(cls, info, id):

View File

@ -21,6 +21,7 @@ def test_should_query_field():
class Meta: class Meta:
model = Reporter model = Reporter
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
class Query(graphene.ObjectType): class Query(graphene.ObjectType):
reporter = graphene.Field(ReporterType) reporter = graphene.Field(ReporterType)
@ -65,6 +66,7 @@ def test_should_query_nested_field():
class Meta: class Meta:
model = Reporter model = Reporter
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
class Query(graphene.ObjectType): class Query(graphene.ObjectType):
reporter = graphene.Field(ReporterType) reporter = graphene.Field(ReporterType)
@ -130,6 +132,7 @@ def test_should_query_list():
class Meta: class Meta:
model = Reporter model = Reporter
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
class Query(graphene.ObjectType): class Query(graphene.ObjectType):
all_reporters = graphene.List(ReporterType) all_reporters = graphene.List(ReporterType)
@ -172,6 +175,7 @@ def test_should_query_connection():
class Meta: class Meta:
model = Reporter model = Reporter
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
class Query(graphene.ObjectType): class Query(graphene.ObjectType):
all_reporters = DjangoConnectionField(ReporterType) all_reporters = DjangoConnectionField(ReporterType)
@ -220,6 +224,7 @@ def test_should_query_connectionfilter():
class Meta: class Meta:
model = Reporter model = Reporter
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
class Query(graphene.ObjectType): class Query(graphene.ObjectType):
all_reporters = DjangoFilterConnectionField(ReporterType, fields=["last_name"]) all_reporters = DjangoFilterConnectionField(ReporterType, fields=["last_name"])

View File

@ -41,17 +41,20 @@ if DJANGO_FILTER_INSTALLED:
class Meta: class Meta:
model = Article model = Article
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
filter_fields = ("headline",) filter_fields = ("headline",)
class ReporterNode(DjangoObjectType): class ReporterNode(DjangoObjectType):
class Meta: class Meta:
model = Reporter model = Reporter
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
class PetNode(DjangoObjectType): class PetNode(DjangoObjectType):
class Meta: class Meta:
model = Pet model = Pet
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
def get_args(field): def get_args(field):
@ -189,6 +192,7 @@ def test_filter_filterset_information_on_meta():
class Meta: class Meta:
model = Reporter model = Reporter
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
filter_fields = ["first_name", "articles"] filter_fields = ["first_name", "articles"]
field = DjangoFilterConnectionField(ReporterFilterNode) field = DjangoFilterConnectionField(ReporterFilterNode)
@ -201,12 +205,14 @@ def test_filter_filterset_information_on_meta_related():
class Meta: class Meta:
model = Reporter model = Reporter
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
filter_fields = ["first_name", "articles"] filter_fields = ["first_name", "articles"]
class ArticleFilterNode(DjangoObjectType): class ArticleFilterNode(DjangoObjectType):
class Meta: class Meta:
model = Article model = Article
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
filter_fields = ["headline", "reporter"] filter_fields = ["headline", "reporter"]
class Query(ObjectType): class Query(ObjectType):
@ -233,6 +239,7 @@ def test_filter_filterset_class_filter_fields_exception():
class Meta: class Meta:
model = Reporter model = Reporter
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
filterset_class = ReporterFilter filterset_class = ReporterFilter
filter_fields = ["first_name", "articles"] filter_fields = ["first_name", "articles"]
@ -247,6 +254,7 @@ def test_filter_filterset_class_information_on_meta():
class Meta: class Meta:
model = Reporter model = Reporter
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
filterset_class = ReporterFilter filterset_class = ReporterFilter
field = DjangoFilterConnectionField(ReporterFilterNode) field = DjangoFilterConnectionField(ReporterFilterNode)
@ -269,12 +277,14 @@ def test_filter_filterset_class_information_on_meta_related():
class Meta: class Meta:
model = Reporter model = Reporter
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
filterset_class = ReporterFilter filterset_class = ReporterFilter
class ArticleFilterNode(DjangoObjectType): class ArticleFilterNode(DjangoObjectType):
class Meta: class Meta:
model = Article model = Article
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
filterset_class = ArticleFilter filterset_class = ArticleFilter
class Query(ObjectType): class Query(ObjectType):
@ -294,12 +304,14 @@ def test_filter_filterset_related_results():
class Meta: class Meta:
model = Reporter model = Reporter
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
filter_fields = ["first_name", "articles"] filter_fields = ["first_name", "articles"]
class ArticleFilterNode(DjangoObjectType): class ArticleFilterNode(DjangoObjectType):
class Meta: class Meta:
interfaces = (Node,) interfaces = (Node,)
model = Article model = Article
fields = "__all__"
filter_fields = ["headline", "reporter"] filter_fields = ["headline", "reporter"]
class Query(ObjectType): class Query(ObjectType):
@ -451,6 +463,7 @@ def test_filter_filterset_related_results_with_filter():
class Meta: class Meta:
model = Reporter model = Reporter
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
filter_fields = {"first_name": ["icontains"]} filter_fields = {"first_name": ["icontains"]}
class Query(ObjectType): class Query(ObjectType):
@ -496,6 +509,7 @@ def test_recursive_filter_connection():
class Meta: class Meta:
model = Reporter model = Reporter
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
class Query(ObjectType): class Query(ObjectType):
all_reporters = DjangoFilterConnectionField(ReporterFilterNode) all_reporters = DjangoFilterConnectionField(ReporterFilterNode)
@ -521,11 +535,13 @@ def test_should_query_filter_node_limit():
class Meta: class Meta:
model = Reporter model = Reporter
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
class ArticleType(DjangoObjectType): class ArticleType(DjangoObjectType):
class Meta: class Meta:
model = Article model = Article
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
filter_fields = ("lang",) filter_fields = ("lang",)
class Query(ObjectType): class Query(ObjectType):
@ -610,6 +626,7 @@ def test_order_by_is_perserved():
class Meta: class Meta:
model = Reporter model = Reporter
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
filter_fields = () filter_fields = ()
class Query(ObjectType): class Query(ObjectType):
@ -676,6 +693,7 @@ def test_annotation_is_preserved():
class Meta: class Meta:
model = Reporter model = Reporter
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
filter_fields = () filter_fields = ()
class Query(ObjectType): class Query(ObjectType):
@ -718,6 +736,7 @@ def test_annotation_with_only():
class Meta: class Meta:
model = Reporter model = Reporter
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
filter_fields = () filter_fields = ()
class Query(ObjectType): class Query(ObjectType):
@ -758,6 +777,7 @@ def test_node_get_queryset_is_called():
class Meta: class Meta:
model = Reporter model = Reporter
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
filter_fields = () filter_fields = ()
@classmethod @classmethod
@ -954,6 +974,7 @@ def test_filter_filterset_based_on_mixin():
class Meta: class Meta:
model = Reporter model = Reporter
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
class NewArticleFilterNode(DjangoObjectType): class NewArticleFilterNode(DjangoObjectType):
viewer = Field(NewReporterNode) viewer = Field(NewReporterNode)
@ -961,6 +982,7 @@ def test_filter_filterset_based_on_mixin():
class Meta: class Meta:
model = Article model = Article
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
filterset_class = NewArticleFilter filterset_class = NewArticleFilter
def resolve_viewer(self, info): def resolve_viewer(self, info):

View File

@ -27,12 +27,14 @@ class ParentType(DjangoObjectType):
class Meta: class Meta:
model = MyFakeParentModel model = MyFakeParentModel
interfaces = (graphene.relay.Node,) interfaces = (graphene.relay.Node,)
fields = "__all__"
class ChildType(DjangoObjectType): class ChildType(DjangoObjectType):
class Meta: class Meta:
model = MyFakeChildModel model = MyFakeChildModel
interfaces = (graphene.relay.Node,) interfaces = (graphene.relay.Node,)
fields = "__all__"
class MyModelChildSerializer(serializers.ModelSerializer): class MyModelChildSerializer(serializers.ModelSerializer):

View File

@ -165,6 +165,7 @@ def test_nested_model():
class MyFakeModelGrapheneType(DjangoObjectType): class MyFakeModelGrapheneType(DjangoObjectType):
class Meta: class Meta:
model = MyFakeModel model = MyFakeModel
fields = "__all__"
class MyMutation(SerializerMutation): class MyMutation(SerializerMutation):
class Meta: class Meta:

View File

@ -9,6 +9,7 @@ class Character(DjangoObjectType):
class Meta: class Meta:
model = Reporter model = Reporter
interfaces = (relay.Node,) interfaces = (relay.Node,)
fields = "__all__"
def get_node(self, info, id): def get_node(self, info, id):
pass pass
@ -20,6 +21,7 @@ class Human(DjangoObjectType):
class Meta: class Meta:
model = Article model = Article
interfaces = (relay.Node,) interfaces = (relay.Node,)
fields = "__all__"
def resolve_raises(self, info): def resolve_raises(self, info):
raise Exception("This field should raise exception") raise Exception("This field should raise exception")

View File

@ -245,6 +245,7 @@ def test_should_manytomany_convert_connectionorlist_list():
class A(DjangoObjectType): class A(DjangoObjectType):
class Meta: class Meta:
model = Reporter model = Reporter
fields = "__all__"
graphene_field = convert_django_field( graphene_field = convert_django_field(
Reporter._meta.local_many_to_many[0], A._meta.registry Reporter._meta.local_many_to_many[0], A._meta.registry
@ -265,6 +266,7 @@ def test_should_manytomany_convert_connectionorlist_connection():
class Meta: class Meta:
model = Reporter model = Reporter
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
graphene_field = convert_django_field( graphene_field = convert_django_field(
Reporter._meta.local_many_to_many[0], A._meta.registry Reporter._meta.local_many_to_many[0], A._meta.registry
@ -279,6 +281,7 @@ def test_should_manytoone_convert_connectionorlist():
class A(DjangoObjectType): class A(DjangoObjectType):
class Meta: class Meta:
model = Article model = Article
fields = "__all__"
graphene_field = convert_django_field(Reporter.articles.rel, A._meta.registry) graphene_field = convert_django_field(Reporter.articles.rel, A._meta.registry)
assert isinstance(graphene_field, graphene.Dynamic) assert isinstance(graphene_field, graphene.Dynamic)
@ -295,6 +298,7 @@ def test_should_onetoone_reverse_convert_model():
class A(DjangoObjectType): class A(DjangoObjectType):
class Meta: class Meta:
model = FilmDetails model = FilmDetails
fields = "__all__"
graphene_field = convert_django_field(Film.details.related, A._meta.registry) graphene_field = convert_django_field(Film.details.related, A._meta.registry)
assert isinstance(graphene_field, graphene.Dynamic) assert isinstance(graphene_field, graphene.Dynamic)

View File

@ -89,6 +89,7 @@ def test_should_query_well():
class ReporterType(DjangoObjectType): class ReporterType(DjangoObjectType):
class Meta: class Meta:
model = Reporter model = Reporter
fields = "__all__"
class Query(graphene.ObjectType): class Query(graphene.ObjectType):
reporter = graphene.Field(ReporterType) reporter = graphene.Field(ReporterType)
@ -130,6 +131,7 @@ def test_should_query_postgres_fields():
class EventType(DjangoObjectType): class EventType(DjangoObjectType):
class Meta: class Meta:
model = Event model = Event
fields = "__all__"
class Query(graphene.ObjectType): class Query(graphene.ObjectType):
event = graphene.Field(EventType) event = graphene.Field(EventType)
@ -171,6 +173,7 @@ def test_should_node():
class Meta: class Meta:
model = Reporter model = Reporter
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
@classmethod @classmethod
def get_node(cls, info, id): def get_node(cls, info, id):
@ -183,6 +186,7 @@ def test_should_node():
class Meta: class Meta:
model = Article model = Article
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
@classmethod @classmethod
def get_node(cls, info, id): def get_node(cls, info, id):
@ -253,11 +257,13 @@ def test_should_query_onetoone_fields():
class Meta: class Meta:
model = Film model = Film
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
class FilmDetailsNode(DjangoObjectType): class FilmDetailsNode(DjangoObjectType):
class Meta: class Meta:
model = FilmDetails model = FilmDetails
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
class Query(graphene.ObjectType): class Query(graphene.ObjectType):
film = graphene.Field(FilmNode) film = graphene.Field(FilmNode)
@ -352,6 +358,7 @@ def test_should_keep_annotations():
class Meta: class Meta:
model = Article model = Article
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
filter_fields = ("lang",) filter_fields = ("lang",)
class Query(graphene.ObjectType): class Query(graphene.ObjectType):
@ -405,11 +412,13 @@ def test_should_query_node_filtering():
class Meta: class Meta:
model = Reporter model = Reporter
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
class ArticleType(DjangoObjectType): class ArticleType(DjangoObjectType):
class Meta: class Meta:
model = Article model = Article
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
filter_fields = ("lang",) filter_fields = ("lang",)
class Query(graphene.ObjectType): class Query(graphene.ObjectType):
@ -483,6 +492,7 @@ def test_should_query_node_filtering_with_distinct_queryset():
class Meta: class Meta:
model = Film model = Film
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
filter_fields = ("genre",) filter_fields = ("genre",)
class Query(graphene.ObjectType): class Query(graphene.ObjectType):
@ -527,11 +537,13 @@ def test_should_query_node_multiple_filtering():
class Meta: class Meta:
model = Reporter model = Reporter
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
class ArticleType(DjangoObjectType): class ArticleType(DjangoObjectType):
class Meta: class Meta:
model = Article model = Article
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
filter_fields = ("lang", "headline") filter_fields = ("lang", "headline")
class Query(graphene.ObjectType): class Query(graphene.ObjectType):
@ -612,6 +624,7 @@ def test_should_enforce_first_or_last(graphene_settings):
class Meta: class Meta:
model = Reporter model = Reporter
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
class Query(graphene.ObjectType): class Query(graphene.ObjectType):
all_reporters = DjangoConnectionField(ReporterType) all_reporters = DjangoConnectionField(ReporterType)
@ -651,6 +664,7 @@ def test_should_error_if_first_is_greater_than_max(graphene_settings):
class Meta: class Meta:
model = Reporter model = Reporter
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
class Query(graphene.ObjectType): class Query(graphene.ObjectType):
all_reporters = DjangoConnectionField(ReporterType) all_reporters = DjangoConnectionField(ReporterType)
@ -692,6 +706,7 @@ def test_should_error_if_last_is_greater_than_max(graphene_settings):
class Meta: class Meta:
model = Reporter model = Reporter
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
class Query(graphene.ObjectType): class Query(graphene.ObjectType):
all_reporters = DjangoConnectionField(ReporterType) all_reporters = DjangoConnectionField(ReporterType)
@ -733,6 +748,7 @@ def test_should_query_promise_connectionfields():
class Meta: class Meta:
model = Reporter model = Reporter
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
class Query(graphene.ObjectType): class Query(graphene.ObjectType):
all_reporters = DjangoConnectionField(ReporterType) all_reporters = DjangoConnectionField(ReporterType)
@ -770,6 +786,7 @@ def test_should_query_connectionfields_with_last():
class Meta: class Meta:
model = Reporter model = Reporter
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
class Query(graphene.ObjectType): class Query(graphene.ObjectType):
all_reporters = DjangoConnectionField(ReporterType) all_reporters = DjangoConnectionField(ReporterType)
@ -811,6 +828,7 @@ def test_should_query_connectionfields_with_manager():
class Meta: class Meta:
model = Reporter model = Reporter
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
class Query(graphene.ObjectType): class Query(graphene.ObjectType):
all_reporters = DjangoConnectionField(ReporterType, on="doe_objects") all_reporters = DjangoConnectionField(ReporterType, on="doe_objects")
@ -857,12 +875,14 @@ def test_should_query_dataloader_fields():
class Meta: class Meta:
model = Article model = Article
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
class ReporterType(DjangoObjectType): class ReporterType(DjangoObjectType):
class Meta: class Meta:
model = Reporter model = Reporter
interfaces = (Node,) interfaces = (Node,)
use_connection = True use_connection = True
fields = "__all__"
articles = DjangoConnectionField(ArticleType) articles = DjangoConnectionField(ArticleType)
@ -947,10 +967,12 @@ def test_should_handle_inherited_choices():
class BaseType(DjangoObjectType): class BaseType(DjangoObjectType):
class Meta: class Meta:
model = BaseModel model = BaseModel
fields = "__all__"
class ChildType(DjangoObjectType): class ChildType(DjangoObjectType):
class Meta: class Meta:
model = ChildModel model = ChildModel
fields = "__all__"
class Query(graphene.ObjectType): class Query(graphene.ObjectType):
base = graphene.Field(BaseType) base = graphene.Field(BaseType)
@ -978,12 +1000,14 @@ def test_proxy_model_support():
model = Reporter model = Reporter
interfaces = (Node,) interfaces = (Node,)
use_connection = True use_connection = True
fields = "__all__"
class CNNReporterType(DjangoObjectType): class CNNReporterType(DjangoObjectType):
class Meta: class Meta:
model = CNNReporter model = CNNReporter
interfaces = (Node,) interfaces = (Node,)
use_connection = True use_connection = True
fields = "__all__"
reporter = Reporter.objects.create( reporter = Reporter.objects.create(
first_name="John", last_name="Doe", email="johndoe@example.com", a_choice=1 first_name="John", last_name="Doe", email="johndoe@example.com", a_choice=1
@ -1056,6 +1080,7 @@ def test_should_resolve_get_queryset_connectionfields():
class Meta: class Meta:
model = Reporter model = Reporter
interfaces = (Node,) interfaces = (Node,)
fields = "__all__"
@classmethod @classmethod
def get_queryset(cls, queryset, info): def get_queryset(cls, queryset, info):
@ -1089,6 +1114,7 @@ def test_should_preserve_prefetch_related(django_assert_num_queries):
class Meta: class Meta:
model = Reporter model = Reporter
interfaces = (graphene.relay.Node,) interfaces = (graphene.relay.Node,)
fields = "__all__"
class FilmType(DjangoObjectType): class FilmType(DjangoObjectType):
reporters = DjangoConnectionField(ReporterType) reporters = DjangoConnectionField(ReporterType)
@ -1096,6 +1122,7 @@ def test_should_preserve_prefetch_related(django_assert_num_queries):
class Meta: class Meta:
model = Film model = Film
interfaces = (graphene.relay.Node,) interfaces = (graphene.relay.Node,)
fields = "__all__"
class Query(graphene.ObjectType): class Query(graphene.ObjectType):
films = DjangoConnectionField(FilmType) films = DjangoConnectionField(FilmType)
@ -1141,6 +1168,7 @@ def test_should_preserve_annotations():
class Meta: class Meta:
model = Reporter model = Reporter
interfaces = (graphene.relay.Node,) interfaces = (graphene.relay.Node,)
fields = "__all__"
class FilmType(DjangoObjectType): class FilmType(DjangoObjectType):
reporters = DjangoConnectionField(ReporterType) reporters = DjangoConnectionField(ReporterType)
@ -1149,6 +1177,7 @@ def test_should_preserve_annotations():
class Meta: class Meta:
model = Film model = Film
interfaces = (graphene.relay.Node,) interfaces = (graphene.relay.Node,)
fields = "__all__"
class Query(graphene.ObjectType): class Query(graphene.ObjectType):
films = DjangoConnectionField(FilmType) films = DjangoConnectionField(FilmType)

View File

@ -9,7 +9,7 @@ def test_should_raise_if_no_model():
with raises(Exception) as excinfo: with raises(Exception) as excinfo:
class Character1(DjangoObjectType): class Character1(DjangoObjectType):
pass fields = "__all__"
assert "valid Django Model" in str(excinfo.value) assert "valid Django Model" in str(excinfo.value)
@ -20,6 +20,7 @@ def test_should_raise_if_model_is_invalid():
class Character2(DjangoObjectType): class Character2(DjangoObjectType):
class Meta: class Meta:
model = 1 model = 1
fields = "__all__"
assert "valid Django Model" in str(excinfo.value) assert "valid Django Model" in str(excinfo.value)
@ -29,6 +30,7 @@ def test_should_map_fields_correctly():
class Meta: class Meta:
model = Reporter model = Reporter
registry = Registry() registry = Registry()
fields = "__all__"
fields = list(ReporterType2._meta.fields.keys()) fields = list(ReporterType2._meta.fields.keys())
assert fields[:-2] == [ assert fields[:-2] == [

View File

@ -19,6 +19,7 @@ class Reporter(DjangoObjectType):
class Meta: class Meta:
model = ReporterModel model = ReporterModel
fields = "__all__"
class ArticleConnection(Connection): class ArticleConnection(Connection):
@ -40,6 +41,7 @@ class Article(DjangoObjectType):
model = ArticleModel model = ArticleModel
interfaces = (Node,) interfaces = (Node,)
connection_class = ArticleConnection connection_class = ArticleConnection
fields = "__all__"
class RootQuery(ObjectType): class RootQuery(ObjectType):
@ -106,6 +108,7 @@ def test_django_objecttype_with_custom_meta():
class Article(ArticleType): class Article(ArticleType):
class Meta: class Meta:
model = ArticleModel model = ArticleModel
fields = "__all__"
assert isinstance(Article._meta, ArticleTypeOptions) assert isinstance(Article._meta, ArticleTypeOptions)
@ -449,6 +452,37 @@ def test_django_objecttype_exclude_fields_exist_on_model():
assert len(record) == 0 assert len(record) == 0
@with_local_registry
def test_django_objecttype_neither_fields_nor_exclude():
with pytest.warns(
DeprecationWarning,
match=r"Creating a DjangoObjectType without either the `fields` "
"or the `exclude` option is deprecated.",
):
class Reporter(DjangoObjectType):
class Meta:
model = ReporterModel
with pytest.warns(None) as record:
class Reporter2(DjangoObjectType):
class Meta:
model = ReporterModel
fields = ["email"]
assert len(record) == 0
with pytest.warns(None) as record:
class Reporter3(DjangoObjectType):
class Meta:
model = ReporterModel
exclude = ["email"]
assert len(record) == 0
def custom_enum_name(field): def custom_enum_name(field):
return "CustomEnum{}".format(field.name.title()) return "CustomEnum{}".format(field.name.title())
@ -473,6 +507,7 @@ class TestDjangoObjectType:
class Meta: class Meta:
model = PetModel model = PetModel
convert_choices_to_enum = False convert_choices_to_enum = False
fields = "__all__"
class Query(ObjectType): class Query(ObjectType):
pet = Field(Pet) pet = Field(Pet)
@ -498,6 +533,7 @@ class TestDjangoObjectType:
class Meta: class Meta:
model = PetModel model = PetModel
convert_choices_to_enum = ["kind"] convert_choices_to_enum = ["kind"]
fields = "__all__"
class Query(ObjectType): class Query(ObjectType):
pet = Field(Pet) pet = Field(Pet)
@ -532,6 +568,7 @@ class TestDjangoObjectType:
class Meta: class Meta:
model = PetModel model = PetModel
convert_choices_to_enum = [] convert_choices_to_enum = []
fields = "__all__"
class Query(ObjectType): class Query(ObjectType):
pet = Field(Pet) pet = Field(Pet)

View File

@ -220,6 +220,16 @@ class DjangoObjectType(ObjectType):
% type(exclude).__name__ % type(exclude).__name__
) )
if fields is None and exclude is None:
warnings.warn(
"Creating a DjangoObjectType without either the `fields` "
"or the `exclude` option is deprecated. Add an explicit `fields "
"= '__all__'` option on DjangoObjectType {class_name} to use all "
"fields".format(class_name=cls.__name__,),
DeprecationWarning,
stacklevel=2,
)
django_fields = yank_fields_from_attrs( django_fields = yank_fields_from_attrs(
construct_fields(model, registry, fields, exclude, convert_choices_to_enum), construct_fields(model, registry, fields, exclude, convert_choices_to_enum),
_as=Field, _as=Field,