mirror of
				https://github.com/graphql-python/graphene.git
				synced 2025-10-30 23:47:55 +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): | ||||
|     name = models.CharField(max_length=100) | ||||
| 
 | ||||
|     def __str__(self): | ||||
|         return self.name | ||||
| 
 | ||||
| 
 | ||||
| class Ingredient(models.Model): | ||||
|     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 | ||||
|  | @ -51,84 +58,179 @@ Create `cookbook/ingredients/schema.py` and type the following: | |||
| 
 | ||||
| ```python | ||||
| # cookbook/ingredients/schema.py | ||||
| import graphene | ||||
| from graphene.contrib.django import DjangoObjectType | ||||
| from graphene import relay, ObjectType | ||||
| 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. | ||||
| # This is configured in the UserType's Meta class (as you can see below) | ||||
| class UserType(DjangoObjectType): | ||||
| class CategoryNode(DjangoNode): | ||||
|     class Meta: | ||||
|         model = User | ||||
|         only_fields = ('username', 'email', 'groups') | ||||
|         model = Category | ||||
|         filter_fields = ['name', 'ingredients'] | ||||
| 
 | ||||
| 
 | ||||
| class GroupType(DjangoObjectType): | ||||
| class IngredientNode(DjangoNode): | ||||
|     class Meta: | ||||
|         model = Group | ||||
|         only_fields = ('name', ) | ||||
|         model = Ingredient | ||||
|         filter_fields = ['name', 'notes', 'category'] | ||||
| 
 | ||||
| 
 | ||||
| class Query(graphene.ObjectType): | ||||
|     get_user = graphene.Field(UserType, | ||||
|                               id=graphene.String().NonNull) | ||||
|     get_group = graphene.Field(GroupType, | ||||
|                                id=graphene.String().NonNull) | ||||
| class Query(ObjectType): | ||||
|     category = relay.NodeField(CategoryNode) | ||||
|     all_categories = DjangoFilterConnectionField(CategoryNode) | ||||
| 
 | ||||
| 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 | ||||
| 
 | ||||
| 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 | ||||
| INSTALLED_APPS = [ | ||||
|     # The other installed apps | ||||
|     ... | ||||
|     'django_graphiql', | ||||
| ] | ||||
| ``` | ||||
| 
 | ||||
| ## 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. | ||||
| 
 | ||||
| Additionally, an interface for navigating this API will be very useful. Graphene | ||||
| includes the [graphiql](https://github.com/graphql/graphiql) in-browser IDE | ||||
| which assists in exploring and querying your new API. We’ll add a URL for this too. | ||||
| Additionally, we'll add a URL for aforementioned GraphiQL, and for the Django admin | ||||
| interface (the latter can be useful for creating test data). | ||||
| 
 | ||||
| ```python | ||||
| from django.conf.urls import url, include | ||||
| from django.contrib import admin | ||||
| from django.views.decorators.csrf import csrf_exempt | ||||
| 
 | ||||
| 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 = [ | ||||
|     url(r'^admin/', admin.site.urls), | ||||
|     url(r'^graphql', csrf_exempt(GraphQLView.as_view(schema=schema))), | ||||
|     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 | ||||
| 
 | ||||
| We're now ready to test the API we've built. Let's fire up the server from the command line. | ||||
| 
 | ||||
| ```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 | ||||
| myQuery { | ||||
|     getUser(id:"1") { | ||||
|         username | ||||
| query { | ||||
|   allIngredients { | ||||
|     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