mirror of
				https://github.com/graphql-python/graphene.git
				synced 2025-10-31 16:07:27 +03:00 
			
		
		
		
	Merge branch 'master' into django-choices-grouping
# Conflicts: # graphene/contrib/django/tests/test_converter.py
This commit is contained in:
		
						commit
						4636f9290a
					
				|  | @ -362,6 +362,12 @@ $title | |||
| .docs | ||||
|   @extend $wrapper | ||||
| 
 | ||||
| .homepage-intro | ||||
|   col(1/2) | ||||
| 
 | ||||
| .homepage-schema | ||||
|   col(1/2) | ||||
| 
 | ||||
| .docs-aside | ||||
|   col(1/4) | ||||
|   margin-top 60px | ||||
|  |  | |||
|  | @ -10,8 +10,8 @@ Let's build a basic GraphQL schema from scratch. | |||
| 
 | ||||
| ## Requirements | ||||
| 
 | ||||
| - Python (2.6.5+, 2.7, 3.2, 3.3, 3.4, 3.5, pypy) | ||||
| - Graphene (0.4+) | ||||
| - Python (2.7, 3.2, 3.3, 3.4, 3.5, pypy) | ||||
| - Graphene (0.10+) | ||||
| 
 | ||||
| 
 | ||||
| ## Project setup | ||||
|  |  | |||
|  | @ -3,8 +3,50 @@ path: / | |||
| --- | ||||
| <div class="starwars-example-wrapper"><a class="starwars-example" href="http://swapi.graphene-python.org/">Check our Django Starwars API example!</a></div> | ||||
| 
 | ||||
| 
 | ||||
| <div> | ||||
| <div class="homepage-intro"> | ||||
| 
 | ||||
| ## Meet Graphene | ||||
| 
 | ||||
| Graphene is a Python library for building GraphQL schemas/types fast and easily. | ||||
| Graphene is a Python library for building *GraphQL* schemas/types fast and easily. | ||||
| 
 | ||||
| **But, what is GraphQL?** A GraphQL query is a string interpreted by a server that returns data in a specified format. We believe *GraphQL* is the next big thing after peanut butter and *REST*. | ||||
| 
 | ||||
| * **Easy to use**: Graphene helps you use *GraphQL* in Python easily. | ||||
| * Graphene has **builtin support for Relay**. | ||||
| * Support for **Django**, **SQLAlchemy** and **GAE**: mapping the models automatically to *GraphQL* types. | ||||
| 
 | ||||
| </div> | ||||
| 
 | ||||
| <div class="homepage-schema"> | ||||
| 
 | ||||
| ```python | ||||
| import graphene | ||||
| 
 | ||||
| class Query(graphene.ObjectType): | ||||
|     hello = graphene.String() | ||||
| 
 | ||||
|     def resolve_hello(self, args, info): | ||||
|         return 'world' | ||||
| 
 | ||||
| schema = graphene.Schema(query=Query) | ||||
| ``` | ||||
| 
 | ||||
| 
 | ||||
| ```python | ||||
| result = schema.execute('{ hello }') | ||||
| ``` | ||||
| 
 | ||||
| </div> | ||||
| </div> | ||||
| 
 | ||||
| <div> | ||||
| 
 | ||||
| #### What is GraphQL? | ||||
| *GraphQL* is a data query language and runtime designed to request and deliver data in a performant way. | ||||
| 
 | ||||
| Advantages of using *GraphQL*: | ||||
| * Only **one API endpoint**. One roundtrip for fetch everything you need. | ||||
| * No data overfetching or underfetching. | ||||
| * Autogenerated Graphical UI and docs based in your schema. | ||||
| <div> | ||||
|  | @ -1,4 +1,5 @@ | |||
| from django.db import models | ||||
| from django.utils.encoding import force_text | ||||
| 
 | ||||
| from ...core.classtypes.enum import Enum | ||||
| from ...core.types.custom_scalars import DateTime, JSONString | ||||
|  | @ -14,13 +15,14 @@ singledispatch = import_single_dispatch() | |||
| 
 | ||||
| def convert_choices(choices): | ||||
|     for value, name in choices: | ||||
|         yield to_const(name), value | ||||
|         yield to_const(force_text(name)), value | ||||
| 
 | ||||
| 
 | ||||
| def convert_django_field_with_choices(field): | ||||
|     choices = getattr(field, 'choices', None) | ||||
|     if choices: | ||||
|         meta = field.model._meta | ||||
|     model = getattr(field, 'model', None) | ||||
|     if choices and model: | ||||
|         meta = model._meta | ||||
|         name = '{}_{}_{}'.format(meta.app_label, meta.object_name, field.name) | ||||
|         return Enum(name.upper(), list(convert_choices(choices)), description=field.help_text) | ||||
|     return convert_django_field(field) | ||||
|  |  | |||
|  | @ -1,6 +1,12 @@ | |||
| from __future__ import absolute_import | ||||
| 
 | ||||
| from django.db import models | ||||
| from django.utils.translation import ugettext_lazy as _ | ||||
| 
 | ||||
| CHOICES = ( | ||||
|     (1, 'this'), | ||||
|     (2, _('that')) | ||||
| ) | ||||
| 
 | ||||
| 
 | ||||
| class Pet(models.Model): | ||||
|  | @ -22,6 +28,7 @@ class Reporter(models.Model): | |||
|     last_name = models.CharField(max_length=30) | ||||
|     email = models.EmailField() | ||||
|     pets = models.ManyToManyField('self') | ||||
|     a_choice = models.CharField(max_length=30, choices=CHOICES) | ||||
| 
 | ||||
|     def __str__(self):              # __unicode__ on Python 2 | ||||
|         return "%s %s" % (self.first_name, self.last_name) | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| import pytest | ||||
| from django.db import models | ||||
| from django.utils.translation import ugettext_lazy as _ | ||||
| from py.test import raises | ||||
| 
 | ||||
| import graphene | ||||
|  | @ -125,7 +126,22 @@ def test_field_with_grouped_choices(): | |||
|         )), | ||||
|     )) | ||||
| 
 | ||||
|     class TranslatedModel(models.Model): | ||||
|     class GroupedChoicesModel(models.Model): | ||||
|         language = field | ||||
| 
 | ||||
|         class Meta: | ||||
|             app_label = 'test' | ||||
| 
 | ||||
|     convert_django_field_with_choices(field) | ||||
| 
 | ||||
| 
 | ||||
| def test_field_with_choices_gettext(): | ||||
|     field = models.CharField(help_text='Language', choices=( | ||||
|         ('es', _('Spanish')), | ||||
|         ('en', _('English')) | ||||
|     )) | ||||
| 
 | ||||
|     class TranslatedChoicesModel(models.Model): | ||||
|         language = field | ||||
| 
 | ||||
|         class Meta: | ||||
|  |  | |||
|  | @ -77,6 +77,7 @@ class Schema(object): | |||
|             self, | ||||
|             query=self.T(self.query), | ||||
|             mutation=self.T(self.mutation), | ||||
|             types=[self.T(_type) for _type in list(self._types_names.values())], | ||||
|             subscription=self.T(self.subscription)) | ||||
| 
 | ||||
|     def register(self, object_type, force=False): | ||||
|  |  | |||
|  | @ -132,6 +132,21 @@ def test_schema_register(): | |||
|     assert schema.get_type('MyType') == MyType | ||||
| 
 | ||||
| 
 | ||||
| def test_schema_register_interfaces(): | ||||
|     class Query(ObjectType): | ||||
|         f = Field(Character) | ||||
| 
 | ||||
|         def resolve_f(self, args, info): | ||||
|             return Human() | ||||
| 
 | ||||
|     schema = Schema(query=Query) | ||||
| 
 | ||||
|     schema.register(Human) | ||||
| 
 | ||||
|     result = schema.execute('{ f { name } }') | ||||
|     assert not result.errors | ||||
| 
 | ||||
| 
 | ||||
| def test_schema_register_no_query_type(): | ||||
|     schema = Schema(name='My own schema') | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user