mirror of
https://github.com/graphql-python/graphene.git
synced 2024-11-26 03:23: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