Browse Source

Improved python syntax and sorts (pep8). Improved Readme

pull/4/head
Syrus Akbary 6 years ago
parent
commit
4e23c3ccf6
  1. 2
      .coveragerc
  2. 52
      README.md
  3. 4
      django_test_settings.py
  4. 2
      examples/cookbook/cookbook/ingredients/schema.py
  5. 4
      examples/cookbook/cookbook/schema.py
  6. 10
      examples/starwars/schema.py
  7. 12
      graphene_django/converter.py
  8. 3
      graphene_django/debug/middleware.py
  9. 3
      graphene_django/debug/types.py
  10. 4
      graphene_django/fields.py
  11. 1
      graphene_django/filter/fields.py
  12. 3
      graphene_django/filter/filterset.py
  13. 2
      graphene_django/filter/tests/test_fields.py
  14. 3
      graphene_django/filter/utils.py
  15. 3
      graphene_django/form_converter.py
  16. 4
      graphene_django/management/commands/graphql_schema.py
  17. 9
      graphene_django/registry.py
  18. 2
      graphene_django/tests/schema.py
  19. 13
      graphene_django/tests/test_converter.py
  20. 2
      graphene_django/tests/test_form_converter.py
  21. 3
      graphene_django/tests/test_query.py
  22. 15
      graphene_django/tests/test_schema.py
  23. 12
      graphene_django/tests/test_types.py
  24. 13
      graphene_django/types.py
  25. 7
      graphene_django/utils.py
  26. 1
      graphene_django/views.py
  27. 10
      setup.cfg

2
.coveragerc

@ -0,0 +1,2 @@
[run]
omit = */tests/*,graphene_django/debug/sql/*

52
README.md

@ -3,20 +3,10 @@ Please read [UPGRADE-v1.0.md](https://github.com/graphql-python/graphene/blob/ma
---
# ![Graphene Logo](http://graphene-python.org/favicon.png) [Graphene-Django](http://graphene-python.org) [![Build Status](https://travis-ci.org/graphql-python/graphene-django.svg?branch=master)](https://travis-ci.org/graphql-python/graphene-django) [![PyPI version](https://badge.fury.io/py/graphene-django.svg)](https://badge.fury.io/py/graphene-django) [![Coverage Status](https://coveralls.io/repos/graphql-python/graphene-django/badge.svg?branch=master&service=github)](https://coveralls.io/github/graphql-python/graphene-django?branch=master)
# ![Graphene Logo](http://graphene-python.org/favicon.png) Graphene-Django [![Build Status](https://travis-ci.org/graphql-python/graphene-django.svg?branch=master)](https://travis-ci.org/graphql-python/graphene-django) [![PyPI version](https://badge.fury.io/py/graphene-django.svg)](https://badge.fury.io/py/graphene-django) [![Coverage Status](https://coveralls.io/repos/graphql-python/graphene-django/badge.svg?branch=master&service=github)](https://coveralls.io/github/graphql-python/graphene-django?branch=master)
[Graphene](http://graphene-python.org) is a Python library for building GraphQL schemas/types fast and easily.
- **Easy to use:** Graphene helps you use GraphQL in Python without effort.
- **Relay:** Graphene has builtin support for Relay
- **Django:** Automatic *Django model* mapping to Graphene Types. Check a fully working [Django](http://github.com/graphql-python/swapi-graphene) implementation
Graphene also supports *SQLAlchemy*!
*What is supported in this Python version?* **Everything**: Interfaces, ObjectTypes, Scalars, Unions and Relay (Nodes, Connections), in addition to queries, mutations and subscriptions.
**NEW**!: [Try graphene online](http://graphene-python.org/playground/)
A [Django](https://www.djangoproject.com/) integration for [Graphene](http://graphene-python.org/).
## Installation
@ -28,30 +18,50 @@ pip install "graphene-django>=1.0.dev"
## Examples
Here is one example for get you started:
Here is a simple Django model:
```python
from django.db import models
from graphene_django import DjangoObjectType
class UserModel(models.Model):
name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
```
To create a GraphQL schema for it you simply have to write the following:
```python
from graphene_django import DjangoObjectType
class User(DjangoObjectType):
class Meta:
# This type will transform all the UserModel fields
# into Graphene fields automatically
model = UserModel
# An extra field in the User Type
full_name = graphene.String()
class Query(graphene.ObjectType):
users = graphene.List(User)
def resolve_full_name(self, args, context, info):
return "{} {}".format(self.name, self.last_name)
@graphene.resolve_only_args
def resolve_users(self):
return UserModel.objects.all()
schema = graphene.Schema(query=QueryRoot)
```
Then you can simply query the schema:
```python
query = '''
query {
users {
name,
lastName
}
}
'''
result = schema.execute(query)
```
If you want to learn even more, you can also check the following [examples](examples/):
To learn more check out the following [examples](examples/):
* **Schema with Filtering**: [Cookbook example](examples/cookbook)
* **Relay Schema**: [Starwars Relay example](examples/starwars)

4
django_test_settings.py

@ -1,4 +1,6 @@
import sys, os
import sys
import os
ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, ROOT_PATH + '/examples/')

2
examples/cookbook/cookbook/ingredients/schema.py

@ -1,5 +1,5 @@
from cookbook.ingredients.models import Category, Ingredient
from graphene import ObjectType, Field, AbstractType, Node
from graphene import AbstractType, Field, Node
from graphene_django.filter import DjangoFilterConnectionField
from graphene_django.types import DjangoObjectType

4
examples/cookbook/cookbook/schema.py

@ -1,8 +1,10 @@
import graphene
import cookbook.ingredients.schema
import graphene
# print cookbook.ingredients.schema.Query._meta.graphql_type.get_fields()['allIngredients'].args
class Query(cookbook.ingredients.schema.Query, graphene.ObjectType):
pass

10
examples/starwars/schema.py

@ -1,14 +1,12 @@
import graphene
from graphene import relay, resolve_only_args, Schema
from graphene import Schema, relay, resolve_only_args
from graphene_django import DjangoObjectType
from .data import (create_ship, get_empire, get_faction, get_rebels, get_ship,
get_ships)
from .models import (
Character as CharacterModel,
Faction as FactionModel,
Ship as ShipModel
)
from .models import Character as CharacterModel
from .models import Faction as FactionModel
from .models import Ship as ShipModel
class Ship(DjangoObjectType):

12
graphene_django/converter.py

@ -1,16 +1,17 @@
from django.db import models
from django.utils.encoding import force_text
from graphene import Enum, List, ID, Boolean, Float, Int, String, Field, NonNull, Field, Dynamic
from graphene.types.json import JSONString
from graphene import (ID, Boolean, Dynamic, Enum, Field, Float, Int, List,
NonNull, String)
from graphene.relay import is_node
from graphene.types.datetime import DateTime
from graphene.types.json import JSONString
from graphene.utils.str_converters import to_const
from graphene.relay import is_node
from .compat import (ArrayField, HStoreField, JSONField, RangeField,
RelatedObject, UUIDField)
from .utils import get_related_model, import_single_dispatch
from .fields import get_connection_field
from .utils import get_related_model, import_single_dispatch
singledispatch = import_single_dispatch()
@ -37,9 +38,10 @@ def convert_django_field_with_choices(field, registry=None):
name = '{}{}'.format(meta.object_name, field.name.capitalize())
choices = list(get_choices(choices))
named_choices = [(c[0], c[1]) for c in choices]
named_choices_descriptions = {c[0]:c[2] for c in choices}
named_choices_descriptions = {c[0]: c[2] for c in choices}
class EnumWithDescriptionsType(object):
@property
def description(self):
return named_choices_descriptions[self.name]

3
graphene_django/debug/middleware.py

@ -1,6 +1,7 @@
from promise import Promise
from django.db import connections
from promise import Promise
from .sql.tracking import unwrap_cursor, wrap_cursor
from .types import DjangoDebug

3
graphene_django/debug/types.py

@ -1,4 +1,5 @@
from graphene import ObjectType, List
from graphene import List, ObjectType
from .sql.types import DjangoDebugSQL

4
graphene_django/fields.py

@ -1,9 +1,11 @@
from functools import partial
from django.db.models.query import QuerySet
from graphene.relay import ConnectionField, PageInfo
from graphql_relay.connection.arrayconnection import connection_from_list_slice
from .utils import maybe_queryset, DJANGO_FILTER_INSTALLED
from .utils import DJANGO_FILTER_INSTALLED, maybe_queryset
class DjangoConnectionField(ConnectionField):

1
graphene_django/filter/fields.py

@ -1,4 +1,5 @@
from functools import partial
from ..fields import DjangoConnectionField
from .utils import get_filtering_args_from_filterset, get_filterset_class

3
graphene_django/filter/filterset.py

@ -5,9 +5,10 @@ from django.utils.text import capfirst
from django_filters import Filter, MultipleChoiceFilter
from django_filters.filterset import FilterSet, FilterSetMetaclass
from ..forms import GlobalIDFormField, GlobalIDMultipleChoiceField
from graphql_relay.node.node import from_global_id
from ..forms import GlobalIDFormField, GlobalIDMultipleChoiceField
class GlobalIDFilter(Filter):
field_class = GlobalIDFormField

2
graphene_django/filter/tests/test_fields.py

@ -2,7 +2,7 @@ from datetime import datetime
import pytest
from graphene import ObjectType, Schema, Field
from graphene import Field, ObjectType, Schema
from graphene.relay import Node
from graphene_django import DjangoObjectType
from graphene_django.forms import (GlobalIDFormField,

3
graphene_django/filter/utils.py

@ -1,6 +1,7 @@
import six
from graphene import Argument, String
from graphene import String
from .filterset import custom_filterset_factory, setup_filterset

3
graphene_django/form_converter.py

@ -1,7 +1,8 @@
from django import forms
from django.forms.fields import BaseTemporalField
from graphene import ID, Boolean, Float, Int, String, List
from graphene import ID, Boolean, Float, Int, List, String
from .forms import GlobalIDFormField, GlobalIDMultipleChoiceField
from .utils import import_single_dispatch

4
graphene_django/management/commands/graphql_schema.py

@ -67,6 +67,6 @@ class Command(CommandArguments):
self.save_file(out, schema_dict)
style = getattr(self, 'style', None)
SUCCESS = getattr(style, 'SUCCESS', lambda x: x)
success = getattr(style, 'SUCCESS', lambda x: x)
self.stdout.write(SUCCESS('Successfully dumped GraphQL schema to %s' % out))
self.stdout.write(success('Successfully dumped GraphQL schema to %s' % out))

9
graphene_django/registry.py

@ -1,13 +1,18 @@
class Registry(object):
def __init__(self):
self._registry = {}
self._registry_models = {}
def register(self, cls):
from .types import DjangoObjectType
assert issubclass(cls, DjangoObjectType), 'Only DjangoObjectTypes can be registered, received "{}"'.format(cls.__name__)
assert issubclass(
cls, DjangoObjectType), 'Only DjangoObjectTypes can be registered, received "{}"'.format(
cls.__name__)
assert cls._meta.registry == self, 'Registry for a Model have to match.'
# assert self.get_type_for_model(cls._meta.model) == cls, 'Multiple DjangoObjectTypes registered for "{}"'.format(cls._meta.model)
# assert self.get_type_for_model(cls._meta.model) == cls, (
# 'Multiple DjangoObjectTypes registered for "{}"'.format(cls._meta.model)
# )
self._registry[cls._meta.model] = cls
def get_type_for_model(self, model):

2
graphene_django/tests/schema.py

@ -1,7 +1,7 @@
import graphene
from graphene import Schema, relay
from ..types import DjangoObjectType
from ..types import DjangoObjectType
from .models import Article, Reporter

13
graphene_django/tests/test_converter.py

@ -4,17 +4,20 @@ from django.utils.translation import ugettext_lazy as _
from py.test import raises
import graphene
from graphene.relay import Node, ConnectionField
from graphene.relay import ConnectionField, Node
from graphene.types.datetime import DateTime
from graphene.types.json import JSONString
# from graphene.core.types.custom_scalars import DateTime, JSONString
from ..compat import (ArrayField, HStoreField, JSONField, MissingType,
RangeField)
from ..converter import convert_django_field, convert_django_field_with_choices
from ..registry import Registry
from .models import Article, Reporter, Film, FilmDetails, Pet
from ..types import DjangoObjectType
from .models import Article, Film, FilmDetails, Reporter
# from graphene.core.types.custom_scalars import DateTime, JSONString
def assert_conversion(django_field, graphene_field, *args, **kwargs):
@ -166,6 +169,7 @@ def test_should_manytomany_convert_connectionorlist():
def test_should_manytomany_convert_connectionorlist_list():
class A(DjangoObjectType):
class Meta:
model = Reporter
@ -179,6 +183,7 @@ def test_should_manytomany_convert_connectionorlist_list():
def test_should_manytomany_convert_connectionorlist_connection():
class A(DjangoObjectType):
class Meta:
model = Reporter
interfaces = (Node, )
@ -196,6 +201,7 @@ def test_should_manytoone_convert_connectionorlist():
getattr(Reporter.articles, 'related')
class A(DjangoObjectType):
class Meta:
model = Article
@ -213,6 +219,7 @@ def test_should_onetoone_reverse_convert_model():
getattr(Film.details, 'related')
class A(DjangoObjectType):
class Meta:
model = FilmDetails

2
graphene_django/tests/test_form_converter.py

@ -2,9 +2,9 @@ from django import forms
from py.test import raises
import graphene
from ..form_converter import convert_form_field
from graphene import ID, List, NonNull
from ..form_converter import convert_form_field
from .models import Reporter

3
graphene_django/tests/test_query.py

@ -8,9 +8,8 @@ import graphene
from graphene.relay import Node
from ..compat import MissingType, RangeField
from ..types import DjangoObjectType
from ..fields import DjangoConnectionField
from ..registry import reset_global_registry, get_global_registry
from ..types import DjangoObjectType
from .models import Article, Reporter
pytestmark = pytest.mark.django_db

15
graphene_django/tests/test_schema.py

@ -1,8 +1,7 @@
from py.test import raises
from ..types import DjangoObjectType
from ..registry import Registry
from ..types import DjangoObjectType
from .models import Reporter
@ -24,10 +23,20 @@ def test_should_raise_if_model_is_invalid():
def test_should_map_fields_correctly():
class ReporterType2(DjangoObjectType):
class Meta:
model = Reporter
registry = Registry()
assert list(ReporterType2._meta.fields.keys()) == ['id', 'first_name', 'last_name', 'email', 'pets', 'a_choice', 'articles', 'films']
assert list(
ReporterType2._meta.fields.keys()) == [
'id',
'first_name',
'last_name',
'email',
'pets',
'a_choice',
'articles',
'films']
def test_should_map_only_few_fields():

12
graphene_django/tests/test_types.py

@ -1,12 +1,12 @@
from graphql.type import GraphQLObjectType
from mock import patch
from graphene import ObjectType, Field, Int, ID, Schema, Interface
from graphene.relay import Node, ConnectionField
from ..types import DjangoObjectType
from graphene import Interface, ObjectType, Schema
from graphene.relay import Node
from .models import Article as ArticleModel, Reporter as ReporterModel
from ..registry import reset_global_registry, Registry
from ..registry import reset_global_registry
from ..types import DjangoObjectType
from .models import Article as ArticleModel
from .models import Reporter as ReporterModel
reset_global_registry()

13
graphene_django/types.py

@ -2,14 +2,16 @@ from collections import OrderedDict
import six
from graphene import ObjectType, Field
from graphene import Field, ObjectType
from graphene.types.objecttype import ObjectTypeMeta
from .converter import convert_django_field_with_choices
from graphene.types.options import Options
from .utils import get_model_fields, is_valid_django_model, DJANGO_FILTER_INSTALLED
from .registry import Registry, get_global_registry
from graphene.types.utils import merge, yank_fields_from_attrs
from graphene.utils.is_base_type import is_base_type
from graphene.types.utils import yank_fields_from_attrs, merge
from .converter import convert_django_field_with_choices
from .registry import Registry, get_global_registry
from .utils import (DJANGO_FILTER_INSTALLED, get_model_fields,
is_valid_django_model)
def construct_fields(options):
@ -95,6 +97,7 @@ class DjangoObjectTypeMeta(ObjectTypeMeta):
class DjangoObjectType(six.with_metaclass(DjangoObjectTypeMeta, ObjectType)):
@classmethod
def is_type_of(cls, root, context, info):
if isinstance(root, cls):

7
graphene_django/utils.py

@ -1,12 +1,17 @@
import inspect
from django.db import models
from django.db.models.manager import Manager
from .compat import RelatedObject
# from graphene.utils import LazyList
class LazyList(object):
pass
from .compat import RelatedObject
try:
import django_filters # noqa

1
graphene_django/views.py

@ -2,6 +2,7 @@ from graphql_django_view import GraphQLView as BaseGraphQLView
class GraphQLView(BaseGraphQLView):
def __init__(self, schema, **kwargs):
super(GraphQLView, self).__init__(
schema=schema,

10
setup.cfg

@ -1,2 +1,12 @@
[tool:pytest]
DJANGO_SETTINGS_MODULE = django_test_settings
[flake8]
exclude = setup.py,docs/*,examples/*,tests,graphene_django/debug/sql/*
max-line-length = 120
[coverage:run]
omit = */tests/*
[isort]
known_first_party=graphene,graphene_django

Loading…
Cancel
Save