diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
index 139c6f683..5d5ae2724 100644
--- a/.github/workflows/deploy.yml
+++ b/.github/workflows/deploy.yml
@@ -20,7 +20,7 @@ jobs:
pip install wheel
python setup.py sdist bdist_wheel
- name: Publish a Python distribution to PyPI
- uses: pypa/gh-action-pypi-publish@v1.8.6
+ uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.pypi_password }}
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 2c5b7550c..dfc5194ae 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -8,13 +8,15 @@ jobs:
strategy:
max-parallel: 4
matrix:
- django: ["3.2", "4.0", "4.1"]
+ django: ["3.2", "4.1", "4.2"]
python-version: ["3.8", "3.9", "3.10"]
include:
- django: "3.2"
python-version: "3.7"
- django: "4.1"
python-version: "3.11"
+ - django: "4.2"
+ python-version: "3.11"
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
diff --git a/.gitignore b/.gitignore
index ff6bd968c..5cfaf0064 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,6 +11,8 @@ __pycache__/
# Distribution / packaging
.Python
env/
+venv/
+.venv/
build/
develop-eggs/
dist/
diff --git a/examples/cookbook-plain/README.md b/examples/cookbook-plain/README.md
index dcd242087..b120b7895 100644
--- a/examples/cookbook-plain/README.md
+++ b/examples/cookbook-plain/README.md
@@ -62,3 +62,12 @@ Now head on over to
and run some queries!
(See the [Graphene-Django Tutorial](http://docs.graphene-python.org/projects/django/en/latest/tutorial-plain/#testing-our-graphql-schema)
for some example queries)
+
+Testing local graphene-django changes
+-------------------------------------
+
+In `requirements.txt`, replace the entire `graphene-django=...` line with the following (so that we install the local version instead of the one from PyPI):
+
+```
+../../ # graphene-django
+```
diff --git a/examples/cookbook-plain/cookbook/settings.py b/examples/cookbook-plain/cookbook/settings.py
index 7eb9d5690..f07f6f6d4 100644
--- a/examples/cookbook-plain/cookbook/settings.py
+++ b/examples/cookbook-plain/cookbook/settings.py
@@ -5,10 +5,10 @@
Generated by 'django-admin startproject' using Django 1.9.
For more information on this file, see
-https://docs.djangoproject.com/en/1.9/topics/settings/
+https://docs.djangoproject.com/en/3.2/topics/settings/
For the full list of settings and their values, see
-https://docs.djangoproject.com/en/1.9/ref/settings/
+https://docs.djangoproject.com/en/3.2/ref/settings/
"""
import os
@@ -18,7 +18,7 @@
# Quick-start development settings - unsuitable for production
-# See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/
+# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = "_$=$%eqxk$8ss4n7mtgarw^5$8^d5+c83!vwatr@i_81myb=e4"
@@ -81,7 +81,7 @@
# Database
-# https://docs.djangoproject.com/en/1.9/ref/settings/#databases
+# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
DATABASES = {
"default": {
@@ -90,9 +90,11 @@
}
}
+# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
+DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
# Password validation
-# https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators
+# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
@@ -105,7 +107,7 @@
# Internationalization
-# https://docs.djangoproject.com/en/1.9/topics/i18n/
+# https://docs.djangoproject.com/en/3.2/topics/i18n/
LANGUAGE_CODE = "en-us"
@@ -119,6 +121,6 @@
# Static files (CSS, JavaScript, Images)
-# https://docs.djangoproject.com/en/1.9/howto/static-files/
+# https://docs.djangoproject.com/en/3.2/howto/static-files/
STATIC_URL = "/static/"
diff --git a/examples/cookbook-plain/requirements.txt b/examples/cookbook-plain/requirements.txt
index 85a896390..6e02745de 100644
--- a/examples/cookbook-plain/requirements.txt
+++ b/examples/cookbook-plain/requirements.txt
@@ -1,4 +1,3 @@
-graphene>=2.1,<3
-graphene-django>=2.1,<3
-graphql-core>=2.1,<3
-django==3.1.14
+django~=3.2
+graphene
+graphene-django>=3.1
diff --git a/graphene_django/__init__.py b/graphene_django/__init__.py
index d4ef76dd7..dab70cec2 100644
--- a/graphene_django/__init__.py
+++ b/graphene_django/__init__.py
@@ -1,7 +1,7 @@
from .fields import DjangoConnectionField, DjangoListField
from .types import DjangoObjectType
-__version__ = "3.1.1"
+__version__ = "3.1.2"
__all__ = [
"__version__",
diff --git a/graphene_django/compat.py b/graphene_django/compat.py
index b0e475357..2fcecf6f7 100644
--- a/graphene_django/compat.py
+++ b/graphene_django/compat.py
@@ -10,16 +10,7 @@ def __init__(self, *args, **kwargs):
IntegerRangeField,
ArrayField,
HStoreField,
- JSONField as PGJSONField,
RangeField,
)
except ImportError:
- IntegerRangeField, ArrayField, HStoreField, PGJSONField, RangeField = (
- MissingType,
- ) * 5
-
-try:
- # JSONField is only available from Django 3.1
- from django.db.models import JSONField
-except ImportError:
- JSONField = MissingType
+ IntegerRangeField, ArrayField, HStoreField, RangeField = (MissingType,) * 4
diff --git a/graphene_django/converter.py b/graphene_django/converter.py
index 375d68312..a43cff76a 100644
--- a/graphene_django/converter.py
+++ b/graphene_django/converter.py
@@ -35,7 +35,7 @@
from graphql import assert_valid_name as assert_name
from graphql.pyutils import register_description
-from .compat import ArrayField, HStoreField, JSONField, PGJSONField, RangeField
+from .compat import ArrayField, HStoreField, RangeField
from .fields import DjangoListField, DjangoConnectionField
from .settings import graphene_settings
from .utils.str_converters import to_const
@@ -346,9 +346,8 @@ def convert_postgres_array_to_list(field, registry=None):
@convert_django_field.register(HStoreField)
-@convert_django_field.register(PGJSONField)
-@convert_django_field.register(JSONField)
-def convert_pg_and_json_field_to_string(field, registry=None):
+@convert_django_field.register(models.JSONField)
+def convert_json_field_to_string(field, registry=None):
return JSONString(
description=get_django_field_description(field), required=not field.null
)
diff --git a/graphene_django/rest_framework/mutation.py b/graphene_django/rest_framework/mutation.py
index 4062a4423..b7393dad0 100644
--- a/graphene_django/rest_framework/mutation.py
+++ b/graphene_django/rest_framework/mutation.py
@@ -39,6 +39,9 @@ def fields_for_serializer(
field.read_only
and is_input
and lookup_field != name, # don't show read_only fields in Input
+ isinstance(
+ field, serializers.HiddenField
+ ), # don't show hidden fields in Input
]
)
diff --git a/graphene_django/rest_framework/tests/test_mutation.py b/graphene_django/rest_framework/tests/test_mutation.py
index 5de823773..91d99f02c 100644
--- a/graphene_django/rest_framework/tests/test_mutation.py
+++ b/graphene_django/rest_framework/tests/test_mutation.py
@@ -164,6 +164,21 @@ class Meta:
), "'cool_name' is read_only field and shouldn't be on arguments"
+def test_hidden_fields():
+ class SerializerWithHiddenField(serializers.Serializer):
+ cool_name = serializers.CharField()
+ user = serializers.HiddenField(default=serializers.CurrentUserDefault())
+
+ class MyMutation(SerializerMutation):
+ class Meta:
+ serializer_class = SerializerWithHiddenField
+
+ assert "cool_name" in MyMutation.Input._meta.fields
+ assert (
+ "user" not in MyMutation.Input._meta.fields
+ ), "'user' is hidden field and shouldn't be on arguments"
+
+
def test_nested_model():
class MyFakeModelGrapheneType(DjangoObjectType):
class Meta:
diff --git a/graphene_django/templates/graphene/graphiql.html b/graphene_django/templates/graphene/graphiql.html
index ddff8fc8e..52421e868 100644
--- a/graphene_django/templates/graphene/graphiql.html
+++ b/graphene_django/templates/graphene/graphiql.html
@@ -21,6 +21,10 @@
integrity="{{graphiql_css_sri}}"
rel="stylesheet"
crossorigin="anonymous" />
+
diff --git a/graphene_django/tests/test_command.py b/graphene_django/tests/test_command.py
index a281abbd2..f7325d569 100644
--- a/graphene_django/tests/test_command.py
+++ b/graphene_django/tests/test_command.py
@@ -46,7 +46,7 @@ class Query(ObjectType):
open_mock.assert_called_once()
handle = open_mock()
- assert handle.write.called_once()
+ handle.write.assert_called_once()
schema_output = handle.write.call_args[0][0]
assert schema_output == dedent(
diff --git a/graphene_django/tests/test_converter.py b/graphene_django/tests/test_converter.py
index 4996505a9..7f4e350ca 100644
--- a/graphene_django/tests/test_converter.py
+++ b/graphene_django/tests/test_converter.py
@@ -15,8 +15,6 @@
from ..compat import (
ArrayField,
HStoreField,
- JSONField,
- PGJSONField,
MissingType,
RangeField,
)
@@ -372,16 +370,6 @@ def test_should_postgres_hstore_convert_string():
assert_conversion(HStoreField, JSONString)
-@pytest.mark.skipif(PGJSONField is MissingType, reason="PGJSONField should exist")
-def test_should_postgres_json_convert_string():
- assert_conversion(PGJSONField, JSONString)
-
-
-@pytest.mark.skipif(JSONField is MissingType, reason="JSONField should exist")
-def test_should_json_convert_string():
- assert_conversion(JSONField, JSONString)
-
-
@pytest.mark.skipif(RangeField is MissingType, reason="RangeField should exist")
def test_should_postgres_range_convert_list():
from django.contrib.postgres.fields import IntegerRangeField
diff --git a/graphene_django/tests/test_query.py b/graphene_django/tests/test_query.py
index 383ff2e33..68bdc7d94 100644
--- a/graphene_django/tests/test_query.py
+++ b/graphene_django/tests/test_query.py
@@ -119,13 +119,12 @@ def test_should_query_postgres_fields():
from django.contrib.postgres.fields import (
IntegerRangeField,
ArrayField,
- JSONField,
HStoreField,
)
class Event(models.Model):
ages = IntegerRangeField(help_text="The age ranges")
- data = JSONField(help_text="Data")
+ data = models.JSONField(help_text="Data")
store = HStoreField()
tags = ArrayField(models.CharField(max_length=50))
diff --git a/graphene_django/views.py b/graphene_django/views.py
index 377b75d99..3fb87d410 100644
--- a/graphene_django/views.py
+++ b/graphene_django/views.py
@@ -66,18 +66,21 @@ class GraphQLView(View):
react_dom_sri = "sha256-nbMykgB6tsOFJ7OdVmPpdqMFVk4ZsqWocT6issAPUF0="
# The GraphiQL React app.
- graphiql_version = "2.4.1" # "1.0.3"
- graphiql_sri = "sha256-s+f7CFAPSUIygFnRC2nfoiEKd3liCUy+snSdYFAoLUc=" # "sha256-VR4buIDY9ZXSyCNFHFNik6uSe0MhigCzgN4u7moCOTk="
- graphiql_css_sri = "sha256-88yn8FJMyGboGs4Bj+Pbb3kWOWXo7jmb+XCRHE+282k=" # "sha256-LwqxjyZgqXDYbpxQJ5zLQeNcf7WVNSJ+r8yp2rnWE/E="
+ graphiql_version = "2.4.7"
+ graphiql_sri = "sha256-n/LKaELupC1H/PU6joz+ybeRJHT2xCdekEt6OYMOOZU="
+ graphiql_css_sri = "sha256-OsbM+LQHcnFHi0iH7AUKueZvDcEBoy/z4hJ7jx1cpsM="
# The websocket transport library for subscriptions.
- subscriptions_transport_ws_version = "5.12.1"
+ subscriptions_transport_ws_version = "5.13.1"
subscriptions_transport_ws_sri = (
"sha256-EZhvg6ANJrBsgLvLAa0uuHNLepLJVCFYS+xlb5U/bqw="
)
graphiql_plugin_explorer_version = "0.1.15"
graphiql_plugin_explorer_sri = "sha256-3hUuhBXdXlfCj6RTeEkJFtEh/kUG+TCDASFpFPLrzvE="
+ graphiql_plugin_explorer_css_sri = (
+ "sha256-fA0LPUlukMNR6L4SPSeFqDTYav8QdWjQ2nr559Zln1U="
+ )
schema = None
graphiql = False
diff --git a/setup.py b/setup.py
index abf605991..87842bb5e 100644
--- a/setup.py
+++ b/setup.py
@@ -38,7 +38,7 @@
version=version,
description="Graphene Django integration",
long_description=open("README.md").read(),
- long_description_content_type='text/markdown',
+ long_description_content_type="text/markdown",
url="https://github.com/graphql-python/graphene-django",
author="Syrus Akbary",
author_email="me@syrusakbary.com",
@@ -56,8 +56,8 @@
"Programming Language :: Python :: Implementation :: PyPy",
"Framework :: Django",
"Framework :: Django :: 3.2",
- "Framework :: Django :: 4.0",
"Framework :: Django :: 4.1",
+ "Framework :: Django :: 4.2",
],
keywords="api graphql protocol rest relay graphene",
packages=find_packages(exclude=["tests", "examples", "examples.*"]),
diff --git a/tox.ini b/tox.ini
index e186f30ef..9739b1c16 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,8 +1,8 @@
[tox]
envlist =
py{37,38,39,310}-django32,
- py{38,39,310}-django{40,41,main},
- py311-django{41,main}
+ py{38,39,310}-django{41,42,main},
+ py311-django{41,42,main}
pre-commit
[gh-actions]
@@ -16,8 +16,8 @@ python =
[gh-actions:env]
DJANGO =
3.2: django32
- 4.0: django40
4.1: django41
+ 4.2: django42
main: djangomain
[testenv]
@@ -30,8 +30,8 @@ deps =
-e.[test]
psycopg2-binary
django32: Django>=3.2,<4.0
- django40: Django>=4.0,<4.1
django41: Django>=4.1,<4.2
+ django42: Django>=4.2,<4.3
djangomain: https://github.com/django/django/archive/main.zip
commands = {posargs:py.test --cov=graphene_django graphene_django examples}