mirror of
				https://github.com/graphql-python/graphene.git
				synced 2025-10-31 16:07:27 +03:00 
			
		
		
		
	Further work on django quickstart
This commit is contained in:
		
							parent
							
								
									90f58e786a
								
							
						
					
					
						commit
						5e6f4cf302
					
				|  | @ -30,10 +30,17 @@ from django.db import models | ||||||
| class Category(models.Model): | class Category(models.Model): | ||||||
|     name = models.CharField(max_length=100) |     name = models.CharField(max_length=100) | ||||||
| 
 | 
 | ||||||
|  |     def __str__(self): | ||||||
|  |         return self.name | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| class Ingredient(models.Model): | class Ingredient(models.Model): | ||||||
|     name = models.CharField(max_length=100) |     name = models.CharField(max_length=100) | ||||||
|     category = models.ForeignKey(Category) |     notes = models.TextField() | ||||||
|  |     category = models.ForeignKey(Category, related_name='ingredients') | ||||||
|  | 
 | ||||||
|  |     def __str__(self): | ||||||
|  |         return self.name | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| ## Schema | ## Schema | ||||||
|  | @ -51,84 +58,179 @@ Create `cookbook/ingredients/schema.py` and type the following: | ||||||
| 
 | 
 | ||||||
| ```python | ```python | ||||||
| # cookbook/ingredients/schema.py | # cookbook/ingredients/schema.py | ||||||
| import graphene | from graphene import relay, ObjectType | ||||||
| from graphene.contrib.django import DjangoObjectType | from graphene.contrib.django.filter import DjangoFilterConnectionField | ||||||
|  | from graphene.contrib.django.types import DjangoNode | ||||||
|  | 
 | ||||||
|  | from cookbook.ingredients.models import Category, Ingredient | ||||||
| 
 | 
 | ||||||
| from django.contrib.auth.models import User, Group |  | ||||||
| 
 | 
 | ||||||
| # Graphene will automatically map the User model's fields onto the UserType. | # Graphene will automatically map the User model's fields onto the UserType. | ||||||
| # This is configured in the UserType's Meta class (as you can see below) | # This is configured in the UserType's Meta class (as you can see below) | ||||||
| class UserType(DjangoObjectType): | class CategoryNode(DjangoNode): | ||||||
|     class Meta: |     class Meta: | ||||||
|         model = User |         model = Category | ||||||
|         only_fields = ('username', 'email', 'groups') |         filter_fields = ['name', 'ingredients'] | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class GroupType(DjangoObjectType): | class IngredientNode(DjangoNode): | ||||||
|     class Meta: |     class Meta: | ||||||
|         model = Group |         model = Ingredient | ||||||
|         only_fields = ('name', ) |         filter_fields = ['name', 'notes', 'category'] | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Query(graphene.ObjectType): | class Query(ObjectType): | ||||||
|     get_user = graphene.Field(UserType, |     category = relay.NodeField(CategoryNode) | ||||||
|                               id=graphene.String().NonNull) |     all_categories = DjangoFilterConnectionField(CategoryNode) | ||||||
|     get_group = graphene.Field(GroupType, |  | ||||||
|                                id=graphene.String().NonNull) |  | ||||||
| 
 | 
 | ||||||
| schema = graphene.Schema(query=Query) |     ingredient = relay.NodeField(IngredientNode) | ||||||
|  |     all_ingredients = DjangoFilterConnectionField(IngredientNode) | ||||||
|  | 
 | ||||||
|  |     class Meta: | ||||||
|  |         abstract = True | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
|  | Note that the above `Query` class is marked as 'abstract'. This is because we | ||||||
|  | want will now create a project-level query which will combine all our app-level | ||||||
|  | queries. | ||||||
|  | 
 | ||||||
|  | Create the parent project-level `cookbook/schema.py`: | ||||||
|  | 
 | ||||||
|  | ```python | ||||||
|  | import graphene | ||||||
|  | 
 | ||||||
|  | import cookbook.ingredients.schema | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Query(cookbook.ingredients.schema.Query): | ||||||
|  |     # This class will inherit from multiple Queries | ||||||
|  |     # as we begin to add more apps to our project | ||||||
|  |     pass | ||||||
|  | 
 | ||||||
|  | schema = graphene.Schema(name='Cookbook Schema') | ||||||
|  | schema.query = Query | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | You can think of this as being something like your top-level `urls.py` | ||||||
|  | file (although it currently lacks any namespacing). | ||||||
| 
 | 
 | ||||||
| ## Adding GraphiQL | ## Adding GraphiQL | ||||||
| 
 | 
 | ||||||
| For having the GraphiQL static assets we need to append `django_graphiql` in `INSTALLED_APPS` in `tutorial/settings.py`: | GraphiQL is a web-based integrated development environment to assist in the | ||||||
|  | writing and executing of GraphQL queries. It will provide us with a simple | ||||||
|  | and easy way of testing our cookbook project. | ||||||
|  | 
 | ||||||
|  | Add `django_graphiql` to `INSTALLED_APPS` in `cookbook/settings.py`: | ||||||
| 
 | 
 | ||||||
| ```python | ```python | ||||||
| INSTALLED_APPS = [ | INSTALLED_APPS = [ | ||||||
|     # The other installed apps |     ... | ||||||
|     'django_graphiql', |     'django_graphiql', | ||||||
| ] | ] | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| ## Creating GraphQL and GraphiQL views | ## Creating GraphQL and GraphiQL views | ||||||
| 
 | 
 | ||||||
| Unlike a RESTful API, there is only a single URL from which a GraphQL is accessed. | Unlike a RESTful API, there is only a single URL from which GraphQL is accessed. | ||||||
| Requests to this URL are handled by Graphene's `GraphQLView` view. | Requests to this URL are handled by Graphene's `GraphQLView` view. | ||||||
| 
 | 
 | ||||||
| Additionally, an interface for navigating this API will be very useful. Graphene | Additionally, we'll add a URL for aforementioned GraphiQL, and for the Django admin | ||||||
| includes the [graphiql](https://github.com/graphql/graphiql) in-browser IDE | interface (the latter can be useful for creating test data). | ||||||
| which assists in exploring and querying your new API. We’ll add a URL for this too. |  | ||||||
| 
 | 
 | ||||||
| ```python | ```python | ||||||
| from django.conf.urls import url, include | from django.conf.urls import url, include | ||||||
|  | from django.contrib import admin | ||||||
| from django.views.decorators.csrf import csrf_exempt | from django.views.decorators.csrf import csrf_exempt | ||||||
|  | 
 | ||||||
| from graphene.contrib.django.views import GraphQLView | from graphene.contrib.django.views import GraphQLView | ||||||
| from quickstart.schema import schema |  | ||||||
| 
 | 
 | ||||||
|  | from cookbook.schema import schema | ||||||
| 
 | 
 | ||||||
| # Wire up our GraphQL schema to /graphql. |  | ||||||
| # Additionally, we include GraphiQL view for querying easily our schema. |  | ||||||
| urlpatterns = [ | urlpatterns = [ | ||||||
|  |     url(r'^admin/', admin.site.urls), | ||||||
|     url(r'^graphql', csrf_exempt(GraphQLView.as_view(schema=schema))), |     url(r'^graphql', csrf_exempt(GraphQLView.as_view(schema=schema))), | ||||||
|     url(r'^graphiql', include('django_graphiql.urls')), |     url(r'^graphiql', include('django_graphiql.urls')), | ||||||
| ] | ] | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
|  | ## Load some test data | ||||||
|  | 
 | ||||||
|  | **TODO:** Insert link to fixture | ||||||
|  | 
 | ||||||
|  | Now is a good time to load up some test data. The easiest option will be to download | ||||||
|  | the ingredients.json fixture and place it in | ||||||
|  | `cookbook/ingredients/fixtures/ingredients.json`. You can then run the following: | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | $ python ./manage.py loaddata ingredients | ||||||
|  | 
 | ||||||
|  | Installed 6 object(s) from 1 fixture(s) | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Alternatively you can use the Django admin interface to create some data youself. | ||||||
|  | You'll need to run the development server (see below), and probably create a login | ||||||
|  | for yourself too (`./manage.py createsuperuser`). | ||||||
|  | 
 | ||||||
| ## Testing our GraphQL schema | ## Testing our GraphQL schema | ||||||
| 
 | 
 | ||||||
| We're now ready to test the API we've built. Let's fire up the server from the command line. | We're now ready to test the API we've built. Let's fire up the server from the command line. | ||||||
| 
 | 
 | ||||||
| ```bash | ```bash | ||||||
| python ./manage.py runserver | $ python ./manage.py runserver | ||||||
|  | 
 | ||||||
|  | Performing system checks... | ||||||
|  | Django version 1.9, using settings 'cookbook.settings' | ||||||
|  | Starting development server at http://127.0.0.1:8000/ | ||||||
|  | Quit the server with CONTROL-C. | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| Go to [localhost:8080/graphiql](http://localhost:8080/graphiql) and type your first query! | Go to [localhost:8000/graphiql](http://localhost:8000/graphiql) and type your first query! | ||||||
| 
 | 
 | ||||||
| ```graphql | ```graphql | ||||||
| myQuery { | query { | ||||||
|     getUser(id:"1") { |   allIngredients { | ||||||
|         username |     edges { | ||||||
|  |       node { | ||||||
|  |         id, | ||||||
|  |         name | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | The above will return the names & IDs for all ingredients. But perhaps you want | ||||||
|  | a specific ingredient: | ||||||
|  | 
 | ||||||
|  | ```graphql | ||||||
|  | query { | ||||||
|  |   # Graphene creates globally unique IDs for all objects. | ||||||
|  |   # You may need to copy this value from the results of the first query | ||||||
|  |   ingredient(id: "SW5ncmVkaWVudE5vZGU6MQ==") { | ||||||
|  |     name | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | You can also get each ingredient for each category: | ||||||
|  | 
 | ||||||
|  | ```graphql | ||||||
|  | query { | ||||||
|  |   allCategories { | ||||||
|  |     edges { | ||||||
|  |       node { | ||||||
|  |         name, | ||||||
|  | 
 | ||||||
|  |         ingredients { | ||||||
|  |           edges { | ||||||
|  |             node { | ||||||
|  |               name | ||||||
|  |             } | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
| } | } | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user