From a33050a543fcac6853a9a86ffe5c18adcc6dd853 Mon Sep 17 00:00:00 2001 From: Jacob Foster Date: Wed, 12 Jul 2017 16:42:59 -0500 Subject: [PATCH 1/4] Add option for including foreignkey IDs --- graphene_django/types.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/graphene_django/types.py b/graphene_django/types.py index 684863a89..de8abd40c 100644 --- a/graphene_django/types.py +++ b/graphene_django/types.py @@ -1,12 +1,13 @@ from collections import OrderedDict +from django.db.models import ForeignKey from django.utils.functional import SimpleLazyObject from graphene import Field from graphene.relay import Connection, Node from graphene.types.objecttype import ObjectType, ObjectTypeOptions from graphene.types.utils import yank_fields_from_attrs -from .converter import convert_django_field_with_choices +from .converter import convert_django_field_with_choices, convert_field_to_id from .registry import Registry, get_global_registry from .utils import (DJANGO_FILTER_INSTALLED, get_model_fields, is_valid_django_model) @@ -30,6 +31,15 @@ def construct_fields(model, registry, only_fields, exclude_fields): converted = convert_django_field_with_choices(field, registry) fields[name] = converted + attname = getattr(field, 'attname', '') + add_foreignkey_attname = all([ + isinstance(field, ForeignKey), + options.include_foreignkey_ids, + attname not in fields, + ]) + if add_foreignkey_attname: + fields[field.attname] = convert_field_to_id(field) + return fields From d753a7f33368073eabbe11de1cf93bf0f8830d75 Mon Sep 17 00:00:00 2001 From: Jacob Foster Date: Sat, 14 Oct 2017 14:50:35 -0500 Subject: [PATCH 2/4] Make INCLUDE_FOREIGNKEY_IDS a global option --- graphene_django/settings.py | 2 ++ graphene_django/types.py | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/graphene_django/settings.py b/graphene_django/settings.py index 46d70ee15..c3301cd33 100644 --- a/graphene_django/settings.py +++ b/graphene_django/settings.py @@ -35,6 +35,8 @@ 'RELAY_CONNECTION_ENFORCE_FIRST_OR_LAST': False, # Max items returned in ConnectionFields / FilterConnectionFields 'RELAY_CONNECTION_MAX_LIMIT': 100, + # Set to True if you want all models to include ForeignKey id fields + 'INCLUDE_FOREIGNKEY_IDS': False } if settings.DEBUG: diff --git a/graphene_django/types.py b/graphene_django/types.py index de8abd40c..be2a892be 100644 --- a/graphene_django/types.py +++ b/graphene_django/types.py @@ -9,6 +9,7 @@ from .converter import convert_django_field_with_choices, convert_field_to_id from .registry import Registry, get_global_registry +from .settings import graphene_settings from .utils import (DJANGO_FILTER_INSTALLED, get_model_fields, is_valid_django_model) @@ -34,7 +35,7 @@ def construct_fields(model, registry, only_fields, exclude_fields): attname = getattr(field, 'attname', '') add_foreignkey_attname = all([ isinstance(field, ForeignKey), - options.include_foreignkey_ids, + graphene_settings.INCLUDE_FOREIGNKEY_IDS, attname not in fields, ]) if add_foreignkey_attname: From 377399d3c59cf908d8366a1d6468ce7accc6060d Mon Sep 17 00:00:00 2001 From: Jacob Foster Date: Fri, 24 Nov 2017 14:31:24 -0800 Subject: [PATCH 3/4] Add tests for INCLUDE_FOREIGNKEY_IDS setting --- graphene_django/tests/test_types.py | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/graphene_django/tests/test_types.py b/graphene_django/tests/test_types.py index 83d9b4070..65ed17ef0 100644 --- a/graphene_django/tests/test_types.py +++ b/graphene_django/tests/test_types.py @@ -1,10 +1,11 @@ from mock import patch +from django.test import override_settings from graphene import Interface, ObjectType, Schema, Connection, String from graphene.relay import Node from .. import registry -from ..types import DjangoObjectType +from ..types import DjangoObjectType, construct_fields from .models import Article as ArticleModel from .models import Reporter as ReporterModel @@ -176,3 +177,26 @@ class Meta: fields = list(Reporter._meta.fields.keys()) assert 'email' not in fields + + +def test_construct_fields_ignores_fkids_by_default(): + fields = construct_fields( + ArticleModel, + registry.registry, + (), () + ) + + assert 'reporter_id' not in fields + assert 'editor_id' not in fields + + +@override_settings(GRAPHENE={'INCLUDE_FOREIGNKEY_IDS': True}) +def test_construct_fields_adds_fkids_when_setting_is_true(): + fields = construct_fields( + ArticleModel, + registry.registry, + (), () + ) + + assert 'reporter_id' in fields + assert 'editor_id' in fields From fc5655e1414559cb5d458c5062d74bb819316117 Mon Sep 17 00:00:00 2001 From: Jacob Foster Date: Fri, 24 Nov 2017 14:44:24 -0800 Subject: [PATCH 4/4] Django override_settings isn't working here, just patch the setting --- graphene_django/tests/test_types.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/graphene_django/tests/test_types.py b/graphene_django/tests/test_types.py index 65ed17ef0..4b2bb076e 100644 --- a/graphene_django/tests/test_types.py +++ b/graphene_django/tests/test_types.py @@ -1,10 +1,10 @@ from mock import patch -from django.test import override_settings from graphene import Interface, ObjectType, Schema, Connection, String from graphene.relay import Node from .. import registry +from ..settings import graphene_settings from ..types import DjangoObjectType, construct_fields from .models import Article as ArticleModel from .models import Reporter as ReporterModel @@ -190,13 +190,14 @@ def test_construct_fields_ignores_fkids_by_default(): assert 'editor_id' not in fields -@override_settings(GRAPHENE={'INCLUDE_FOREIGNKEY_IDS': True}) def test_construct_fields_adds_fkids_when_setting_is_true(): + graphene_settings.INCLUDE_FOREIGNKEY_IDS = True fields = construct_fields( ArticleModel, registry.registry, (), () ) + graphene_settings.INCLUDE_FOREIGNKEY_IDS = False assert 'reporter_id' in fields assert 'editor_id' in fields