Skip to content

Commit 6572080

Browse files
committed
Merge branch 'master' into v3
2 parents dd0d6ef + fba6de4 commit 6572080

File tree

6 files changed

+77
-28
lines changed

6 files changed

+77
-28
lines changed

README.md

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
Please read [UPGRADE-v2.0.md](https://github.com/graphql-python/graphene/blob/master/UPGRADE-v2.0.md) to learn how to upgrade to Graphene `2.0`.
2-
3-
---
4-
51
# ![Graphene Logo](http://graphene-python.org/favicon.png) Graphene-Django
62

73

@@ -12,15 +8,17 @@ A [Django](https://www.djangoproject.com/) integration for [Graphene](http://gra
128
[![Anaconda-Server Badge][conda-image]][conda-url]
139
[![coveralls][coveralls-image]][coveralls-url]
1410

15-
[travis-image]: https://travis-ci.org/graphql-python/graphene-django.svg?style=flat
11+
[travis-image]: https://travis-ci.org/graphql-python/graphene-django.svg?branch=master&style=flat
1612
[travis-url]: https://travis-ci.org/graphql-python/graphene-django
1713
[pypi-image]: https://img.shields.io/pypi/v/graphene-django.svg?style=flat
1814
[pypi-url]: https://pypi.org/project/graphene-django/
19-
[coveralls-image]: https://coveralls.io/repos/graphql-python/graphene-django/badge.svg?branch=master&service=github
15+
[coveralls-image]: https://coveralls.io/repos/github/graphql-python/graphene-django/badge.svg?branch=master
2016
[coveralls-url]: https://coveralls.io/github/graphql-python/graphene-django?branch=master
2117
[conda-image]: https://img.shields.io/conda/vn/conda-forge/graphene-django.svg
2218
[conda-url]: https://anaconda.org/conda-forge/graphene-django
2319

20+
[💬 Join the community on Slack](https://join.slack.com/t/graphenetools/shared_invite/enQtOTE2MDQ1NTg4MDM1LTA4Nzk0MGU0NGEwNzUxZGNjNDQ4ZjAwNDJjMjY0OGE1ZDgxZTg4YjM2ZTc4MjE2ZTAzZjE2ZThhZTQzZTkyMmM)
21+
2422
## Documentation
2523

2624
[Visit the documentation to get started!](https://docs.graphene-python.org/projects/django/en/latest/)
@@ -92,7 +90,7 @@ class Query(graphene.ObjectType):
9290
schema = graphene.Schema(query=Query)
9391
```
9492

95-
Then you can simply query the schema:
93+
Then you can query the schema:
9694

9795
```python
9896
query = '''

docs/filtering.rst

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,17 @@ You will need to install it manually, which can be done as follows:
1313

1414
.. code:: bash
1515
16-
# You'll need to django-filter
16+
# You'll need to install django-filter
1717
pip install django-filter>=2
18+
19+
After installing ``django-filter`` you'll need to add the application in the ``settings.py`` file:
20+
21+
.. code:: python
22+
23+
INSTALLED_APPS = [
24+
# ...
25+
"django_filters",
26+
]
1827
1928
Note: The techniques below are demoed in the `cookbook example
2029
app <https://github.com/graphql-python/graphene-django/tree/master/examples/cookbook>`__.

graphene_django/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from .types import DjangoObjectType
22
from .fields import DjangoConnectionField
33

4-
__version__ = "2.9.0"
4+
__version__ = "2.9.1"
55

66
__all__ = ["__version__", "DjangoObjectType", "DjangoConnectionField"]

graphene_django/forms/mutation.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,17 @@ def __init_subclass_with_meta__(
162162
_meta=_meta, input_fields=input_fields, **options
163163
)
164164

165+
@classmethod
166+
def mutate_and_get_payload(cls, root, info, **input):
167+
form = cls.get_form(root, info, **input)
168+
169+
if form.is_valid():
170+
return cls.perform_mutate(form, info)
171+
else:
172+
errors = ErrorType.from_errors(form.errors)
173+
174+
return cls(errors=errors)
175+
165176
@classmethod
166177
def perform_mutate(cls, form, info):
167178
obj = form.save()

graphene_django/forms/tests/test_mutation.py

Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
from graphene import ObjectType, Schema, String, Field
77
from graphene_django import DjangoObjectType
8-
from graphene_django.tests.models import Film, FilmDetails, Pet
8+
from graphene_django.tests.models import Film, Pet
99

1010
from ...settings import graphene_settings
1111
from ..mutation import DjangoFormMutation, DjangoModelFormMutation
@@ -29,6 +29,12 @@ class Meta:
2929
model = Pet
3030
fields = "__all__"
3131

32+
def clean_age(self):
33+
age = self.cleaned_data["age"]
34+
if age >= 99:
35+
raise ValidationError("Too old")
36+
return age
37+
3238

3339
class PetType(DjangoObjectType):
3440
class Meta:
@@ -42,12 +48,6 @@ class Meta:
4248
fields = "__all__"
4349

4450

45-
class FilmDetailsType(DjangoObjectType):
46-
class Meta:
47-
model = FilmDetails
48-
fields = "__all__"
49-
50-
5151
def test_needs_form_class():
5252
with raises(Exception) as exc:
5353

@@ -185,23 +185,14 @@ class Meta:
185185
self.assertIn("client_mutation_id", PetMutation.Input._meta.fields)
186186
self.assertNotIn("id", PetMutation.Input._meta.fields)
187187

188-
def test_return_field_name_is_camelcased(self):
189-
class PetMutation(DjangoModelFormMutation):
190-
class Meta:
191-
form_class = PetForm
192-
model = FilmDetails
193-
194-
self.assertEqual(PetMutation._meta.model, FilmDetails)
195-
self.assertEqual(PetMutation._meta.return_field_name, "filmDetails")
196-
197188
def test_custom_return_field_name(self):
198189
class PetMutation(DjangoModelFormMutation):
199190
class Meta:
200191
form_class = PetForm
201-
model = Film
192+
model = Pet
202193
return_field_name = "animal"
203194

204-
self.assertEqual(PetMutation._meta.model, Film)
195+
self.assertEqual(PetMutation._meta.model, Pet)
205196
self.assertEqual(PetMutation._meta.return_field_name, "animal")
206197
self.assertIn("animal", PetMutation._meta.fields)
207198

@@ -258,6 +249,10 @@ class Mutation(ObjectType):
258249
name
259250
age
260251
}
252+
errors {
253+
field
254+
messages
255+
}
261256
}
262257
}
263258
"""
@@ -270,6 +265,42 @@ class Mutation(ObjectType):
270265
self.assertEqual(pet.name, "Mia")
271266
self.assertEqual(pet.age, 10)
272267

268+
def test_model_form_mutation_invalid_input(self):
269+
class PetMutation(DjangoModelFormMutation):
270+
pet = Field(PetType)
271+
272+
class Meta:
273+
form_class = PetForm
274+
275+
class Mutation(ObjectType):
276+
pet_mutation = PetMutation.Field()
277+
278+
schema = Schema(query=MockQuery, mutation=Mutation)
279+
280+
result = schema.execute(
281+
""" mutation PetMutation {
282+
petMutation(input: { name: "Mia", age: 99 }) {
283+
pet {
284+
name
285+
age
286+
}
287+
errors {
288+
field
289+
messages
290+
}
291+
}
292+
}
293+
"""
294+
)
295+
self.assertIs(result.errors, None)
296+
self.assertEqual(result.data["petMutation"]["pet"], None)
297+
self.assertEqual(
298+
result.data["petMutation"]["errors"],
299+
[{"field": "age", "messages": ["Too old"],}],
300+
)
301+
302+
self.assertEqual(Pet.objects.count(), 0)
303+
273304
def test_model_form_mutation_mutate_invalid_form(self):
274305
class PetMutation(DjangoModelFormMutation):
275306
class Meta:

tox.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tox]
22
envlist =
3-
py{36,37,38}-django{111,django22,django30,master},
3+
py{36,37,38}-django{111,22,30,master},
44
black,flake8
55

66
[travis:env]

0 commit comments

Comments
 (0)