mirror of
https://github.com/graphql-python/graphene.git
synced 2024-11-22 09:36:44 +03:00
Big improvements in docs pages
This commit is contained in:
parent
0cf6cd65c7
commit
65c9cc7ce8
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -61,3 +61,7 @@ target/
|
|||
|
||||
|
||||
/tests/django.sqlite
|
||||
|
||||
/graphene/index.json
|
||||
|
||||
/graphene/meta.json
|
||||
|
|
15
.travis.yml
15
.travis.yml
|
@ -6,22 +6,25 @@ python:
|
|||
- 3.4
|
||||
- 3.5
|
||||
- pypy
|
||||
node_js:
|
||||
- 4.1
|
||||
cache:
|
||||
- pip
|
||||
- directories:
|
||||
directories:
|
||||
- .cache/pip/
|
||||
- docs/node_modules
|
||||
- $HOME/.cache/pip
|
||||
- docs/node_modules/
|
||||
- $HOME/docs/node_modules
|
||||
install:
|
||||
- pip install --download-cache .cache/pip/ pytest pytest-cov coveralls flake8 six
|
||||
- pip install --download-cache $HOME/.cache/pip/ pytest pytest-cov coveralls flake8 six
|
||||
blinker pytest-django
|
||||
- pip install --download-cache .cache/pip/ -e .[django]
|
||||
- pip install --download-cache $HOME/.cache/pip/ -e .[django]
|
||||
- python setup.py develop
|
||||
script:
|
||||
- py.test --cov=graphene
|
||||
- flake8
|
||||
after_success:
|
||||
- coveralls
|
||||
- cd docs && npm run deploy
|
||||
- nvm install 4.1 && cd docs && npm run deploy
|
||||
|
||||
env:
|
||||
matrix:
|
||||
|
|
BIN
docs/assets/edit.png
Normal file
BIN
docs/assets/edit.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 372 B |
BIN
docs/assets/edit@2x.png
Normal file
BIN
docs/assets/edit@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 688 B |
|
@ -1 +1,17 @@
|
|||
siteTitle="Graphene"
|
||||
siteTitle = "Graphene"
|
||||
|
||||
[docs.quickstart]
|
||||
name = "Quickstart"
|
||||
pages = [
|
||||
"/docs/quickstart/",
|
||||
"/docs/quickstart-django/",
|
||||
]
|
||||
|
||||
[docs.walkthrough]
|
||||
name = "Walkthrough"
|
||||
pages = [
|
||||
"/docs/interfaces/",
|
||||
"/docs/objecttypes/",
|
||||
"/docs/mutations/",
|
||||
"/docs/basic-types/",
|
||||
]
|
||||
|
|
70
docs/css/hljs.css
Normal file
70
docs/css/hljs.css
Normal file
|
@ -0,0 +1,70 @@
|
|||
/**
|
||||
* GitHub Gist Theme
|
||||
* Author : Louis Barranqueiro - https://github.com/LouisBarranqueiro
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
background: white;
|
||||
padding: 0.5em;
|
||||
color: #333333;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-meta {
|
||||
color: #969896;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-strong,
|
||||
.hljs-emphasis,
|
||||
.hljs-quote {
|
||||
color: #df5000;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-type {
|
||||
color: #a71d5d;
|
||||
}
|
||||
|
||||
.hljs-literal,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-attribute {
|
||||
color: #0086b3;
|
||||
}
|
||||
|
||||
.hljs-section,
|
||||
.hljs-name {
|
||||
color: #63a35c;
|
||||
}
|
||||
|
||||
.hljs-tag {
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-attr,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class,
|
||||
.hljs-selector-attr {
|
||||
color: #795da3;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
color: #55a532;
|
||||
background-color: #eaffea;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
color: #bd2c00;
|
||||
background-color: #ffecec;
|
||||
}
|
||||
|
||||
.hljs-link {
|
||||
text-decoration: underline;
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
@import 'nib'
|
||||
@import 'jeet'
|
||||
|
||||
@import 'hljs.css'
|
||||
@import 'https://fonts.googleapis.com/css?family=Raleway:400,500,600,200,100&.css'
|
||||
|
||||
normalize-css()
|
||||
|
@ -15,6 +16,9 @@ $wrapper
|
|||
a, a:hover
|
||||
text-decoration none
|
||||
|
||||
a
|
||||
color rgb(42,93,173)
|
||||
|
||||
html, body
|
||||
font-family "Helvetica Neue", Helvetica, Arial, sans-serif
|
||||
font-weight 300
|
||||
|
@ -85,7 +89,19 @@ html, body
|
|||
text-transform uppercase
|
||||
font-weight 600
|
||||
line-height 15px
|
||||
|
||||
position relative
|
||||
&.active:before
|
||||
content: ''
|
||||
width 5px
|
||||
height 5px
|
||||
border-radius 100%
|
||||
display block
|
||||
position absolute
|
||||
background white
|
||||
left 50%
|
||||
margin-left -3px
|
||||
bottom -24px
|
||||
|
||||
.header-logo
|
||||
font-family 'Raleway'
|
||||
font-size 22px
|
||||
|
@ -168,45 +184,183 @@ html, body
|
|||
border-radius: 100px
|
||||
font-size 13px
|
||||
padding 17px 17px 17px 71px
|
||||
width 226px
|
||||
width 236px
|
||||
box-sizing border-box
|
||||
color white
|
||||
font-family 'Raleway'
|
||||
font-weight 500
|
||||
transition all .2s ease-in-out
|
||||
&:before
|
||||
content: ''
|
||||
display block
|
||||
position absolute
|
||||
left 0
|
||||
top 0
|
||||
left 20px
|
||||
top 20px
|
||||
height 32px
|
||||
width 32px
|
||||
image '../assets/starwars-icon.png'
|
||||
image '~!file-loader!../assets/starwars-icon.png' 32px 32px
|
||||
|
||||
&:hover
|
||||
transform translateY(-3px)
|
||||
box-shadow 0px 4px 8px 0px rgba(0,0,0,0.32)
|
||||
|
||||
.improve-document-link
|
||||
@extend $wrapper
|
||||
position fixed
|
||||
right 0
|
||||
bottom 70px
|
||||
transform-origin 100% 100%
|
||||
background: #999;
|
||||
border: 1px solid #919191;
|
||||
border-radius: 3px 3px 0 0;
|
||||
border-bottom 0
|
||||
padding 9px 12px 12px 34px
|
||||
transform: rotate(270deg) translateX(100%) translateY(3px);
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
text-transform uppercase
|
||||
color: #FFFFFF;
|
||||
letter-spacing: 0.3px;
|
||||
line-height: 11px;
|
||||
transition all .2s ease-in-out
|
||||
&:before
|
||||
content: ''
|
||||
display block
|
||||
position absolute
|
||||
left 10px
|
||||
top 8px
|
||||
height 16px
|
||||
width 16px
|
||||
image '~!file-loader!../assets/edit.png' 16px 16px
|
||||
&:hover
|
||||
transform: rotate(270deg) translateX(100%)
|
||||
background #666
|
||||
border-color #555
|
||||
+below(600px)
|
||||
display none
|
||||
|
||||
$title
|
||||
display block
|
||||
font-family: 'Raleway';
|
||||
font-weight 500
|
||||
line-height 1.2em
|
||||
padding-top .3em
|
||||
margin-bottom .5em
|
||||
padding-bottom .5em
|
||||
color #4A4A4A
|
||||
|
||||
.markdown
|
||||
.wrapper
|
||||
margin-top 60px
|
||||
|
||||
h1, h2, h3, h4, h5, h6
|
||||
font-family: 'Raleway';
|
||||
font-weight 600
|
||||
color #4A4A4A
|
||||
strong
|
||||
font-weight 500
|
||||
|
||||
h1, h2, h3, h4, h5, h6
|
||||
@extend $title
|
||||
|
||||
h1
|
||||
font-size 32px
|
||||
h2
|
||||
font-size 26px
|
||||
h3
|
||||
font-size 24px
|
||||
h4
|
||||
font-size 21px
|
||||
h5
|
||||
font-size 18px
|
||||
h6
|
||||
font-size 16px
|
||||
strong
|
||||
font-weight 500
|
||||
pre
|
||||
line-height 20px
|
||||
background #FAFAFA
|
||||
padding 20px
|
||||
white-space: pre
|
||||
display: block;
|
||||
color: #333333;
|
||||
overflow-x: auto;
|
||||
p code, ul code
|
||||
background #FAFAFA
|
||||
padding 2px 4px
|
||||
border-radius 2px
|
||||
border 1px solid #CCC
|
||||
color #000
|
||||
code
|
||||
font-size 14px
|
||||
line-height 20px
|
||||
overflow-x: auto;
|
||||
margin-bottom 40px
|
||||
|
||||
.markdown h1:first-child
|
||||
margin-top 0
|
||||
padding-top 0
|
||||
|
||||
.title
|
||||
background: #F9F9F9;
|
||||
padding 30px 0
|
||||
padding 54px 0
|
||||
|
||||
h1
|
||||
margin 0 auto
|
||||
@extend $wrapper
|
||||
font-family: 'Raleway';
|
||||
font-size: 42px;
|
||||
font-weight 200
|
||||
color: #585858;
|
||||
line-height: 49px;
|
||||
|
||||
.docs
|
||||
@extend $wrapper
|
||||
|
||||
.docs-aside
|
||||
col(1/4)
|
||||
margin-top 60px
|
||||
+below(600px)
|
||||
padding 20px
|
||||
width 100%
|
||||
box-sizing content-box
|
||||
margin 0 -20px
|
||||
margin-bottom 30px
|
||||
background #F9F9F9
|
||||
|
||||
.docs-aside-group
|
||||
display block
|
||||
margin-bottom 40px
|
||||
h3
|
||||
font-family: 'Raleway';
|
||||
font-weight 500
|
||||
font-size 12px
|
||||
text-transform uppercase
|
||||
line-height 1.2em
|
||||
margin-bottom 1em
|
||||
color #AAA
|
||||
a
|
||||
display block
|
||||
font-size 15px
|
||||
font-weight 400
|
||||
line-height 22px
|
||||
height 28px
|
||||
padding 3px 0
|
||||
color #4A4A4A
|
||||
&.active
|
||||
font-weight 500
|
||||
line-height 21px
|
||||
color #E05B49
|
||||
|
||||
+below(600px)
|
||||
display none
|
||||
|
||||
.docs-aside-navselect
|
||||
display none
|
||||
width 100%
|
||||
+below(600px)
|
||||
display block
|
||||
|
||||
.docs-content
|
||||
col(3/4)
|
||||
margin-top 60px
|
||||
+below(600px)
|
||||
margin-top 10px
|
||||
col(1)
|
||||
|
||||
>h1
|
||||
margin 0
|
||||
@extend $title
|
||||
font-size 32px
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
var nib = require("nib");
|
||||
var jeet = require("jeet");
|
||||
var rupture = require("rupture");
|
||||
var ExtractTextPlugin = require("extract-text-webpack-plugin");
|
||||
|
||||
module.exports = function(config, env) {
|
||||
var IS_STATIC = env === 'static';
|
||||
config.merge({
|
||||
stylus: {
|
||||
use: [nib(), jeet()]
|
||||
use: [nib(), jeet(), rupture()]
|
||||
}
|
||||
});
|
||||
if (IS_STATIC) {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"main": "n/a",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"build": "npm install -g gatsby && npm install",
|
||||
"build": "npm install -g gatsby && npm install && gatsby build",
|
||||
"deploy": "npm run build"
|
||||
},
|
||||
"keywords": [
|
||||
|
|
|
@ -1,6 +1,13 @@
|
|||
var IN_BROWSER = typeof window != 'undefined';
|
||||
import React from 'react';
|
||||
var browser_supported;
|
||||
if (IN_BROWSER) {
|
||||
var isSafari = navigator.vendor && navigator.vendor.indexOf('Apple') > -1 &&
|
||||
navigator.userAgent && !navigator.userAgent.match('CriOS');
|
||||
var browser_supported = !isSafari;
|
||||
}
|
||||
console.log(browser_supported);
|
||||
if (IN_BROWSER && browser_supported) {
|
||||
var glfx = require('../vendor/glfx.optim')
|
||||
var particlesJS = require('../vendor/particles.js')
|
||||
}
|
||||
|
@ -23,12 +30,12 @@ class Header extends React.Component {
|
|||
this.mounted = false;
|
||||
}
|
||||
componentDidMount() {
|
||||
if (!IN_BROWSER) return;
|
||||
if (!(IN_BROWSER && browser_supported)) return;
|
||||
this.mounted = true;
|
||||
new particlesJS('header-background', {
|
||||
"particles": {
|
||||
"number": {
|
||||
"value": 36,
|
||||
"value": 40,
|
||||
"density": {
|
||||
"enable": true,
|
||||
"value_area": 800
|
||||
|
|
|
@ -19,10 +19,10 @@ class Template extends React.Component {
|
|||
Graphene
|
||||
</Link>
|
||||
<nav className="header-nav">
|
||||
<Link to="/docs/quickstart/">Get started</Link>
|
||||
<Link to="/">Playground</Link>
|
||||
<Link to="/">Docs</Link>
|
||||
<Link to="/try/">Try it out</Link>
|
||||
<Link to="/docs/quickstart/" className={path.indexOf('/docs')==0?"active":null}>Docs</Link>
|
||||
<Link to="/community/">Community</Link>
|
||||
<a href="https://github.com/graphql-python/graphene/">Github</a>
|
||||
</nav>
|
||||
</div>
|
||||
{isIndex?
|
||||
|
|
|
@ -17,9 +17,17 @@ If you think working with Graphene is fun, there are many ways you can contribut
|
|||
- **GraphQL Relay**: [Source Code][1] - [PyPI package][2]
|
||||
- **Graphene**: [Source Code][3] - [PyPI package][4]
|
||||
|
||||
Django integration:
|
||||
- **graphql-django-view**: [Source Code][5] - [PyPI package][6]
|
||||
- **django-graphiql**: [Source Code][7] - [PyPI package][8]
|
||||
|
||||
[Source Code]: https://github.com/graphql-python/graphql-core
|
||||
[PyPI package]: https://pypi.python.org/pypi/graphql-core
|
||||
[1]: https://github.com/graphql-python/graphql-relay
|
||||
[2]: https://pypi.python.org/pypi/graphql-relay
|
||||
[3]: https://github.com/graphql-python/graphene
|
||||
[4]: https://pypi.python.org/pypi/graphene
|
||||
[5]: https://github.com/graphql-python/graphql-django-view
|
||||
[6]: https://pypi.python.org/pypi/graphql-django-view
|
||||
[7]: https://github.com/graphql-python/django-graphiql
|
||||
[8]: https://pypi.python.org/pypi/django-graphiql
|
||||
|
|
48
docs/pages/docs/_template.js
Normal file
48
docs/pages/docs/_template.js
Normal file
|
@ -0,0 +1,48 @@
|
|||
import React from 'react';
|
||||
import { RouteHandler, Link, State } from 'react-router';
|
||||
import _ from 'lodash';
|
||||
|
||||
class Template extends React.Component {
|
||||
goToPage(event) {
|
||||
var page = event.target.value;
|
||||
this.context.router.transitionTo(page);
|
||||
}
|
||||
render() {
|
||||
var docs = this.props.config.docs;
|
||||
var docs_index = _.indexBy(this.props.pages, 'path');
|
||||
return (
|
||||
<div className="docs">
|
||||
<aside className="docs-aside">
|
||||
{Object.keys(docs).map((key) => {
|
||||
let group = docs[key];
|
||||
return <div className="docs-aside-group" key={key}>
|
||||
<h3>{group.name}</h3>
|
||||
{group.pages.map((page) => {
|
||||
return <Link key={page} to={page}>{docs_index[page].data.title}</Link>
|
||||
})}
|
||||
</div>;
|
||||
})}
|
||||
<select className="docs-aside-navselect" onChange={this.goToPage.bind(this)}>
|
||||
{Object.keys(docs).map((key) => {
|
||||
let group = docs[key];
|
||||
return <optgroup key={key} label={group.name}>
|
||||
{group.pages.map((page) => {
|
||||
return <option key={page} value={page}>{docs_index[page].data.title}</option>
|
||||
})}
|
||||
</optgroup>;
|
||||
})}
|
||||
</select>
|
||||
</aside>
|
||||
<div className="docs-content">
|
||||
<RouteHandler {...this.props} docs={true}/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Template.contextTypes = {
|
||||
router: React.PropTypes.func
|
||||
};
|
||||
|
||||
module.exports = Template;
|
52
docs/pages/docs/basic-types.md
Normal file
52
docs/pages/docs/basic-types.md
Normal file
|
@ -0,0 +1,52 @@
|
|||
---
|
||||
title: Basic Types
|
||||
description: Walkthrough Basic Types
|
||||
---
|
||||
|
||||
# Basic Types
|
||||
|
||||
Graphene define the following base Types:
|
||||
- `graphene.String`
|
||||
- `graphene.Int`
|
||||
- `graphene.Float`
|
||||
- `graphene.Boolean`
|
||||
- `graphene.ID`
|
||||
|
||||
Also, define:
|
||||
- `graphene.List`
|
||||
- `graphene.NonNull`
|
||||
|
||||
## Mounting in ClassTypes
|
||||
|
||||
This types if are mounted in a `ObjectType`, `Interface` or `Mutation`,
|
||||
would act as `Field`s.
|
||||
So, the following examples will behave exactly the same:
|
||||
|
||||
```python
|
||||
class Person(graphene.ObjectType):
|
||||
name = graphene.String()
|
||||
```
|
||||
and
|
||||
|
||||
```python
|
||||
class Person(graphene.ObjectType):
|
||||
name = graphene.Field(graphene.String())
|
||||
```
|
||||
|
||||
## Mounting in Fields
|
||||
|
||||
If this types are mounted in a `Field`, would act as `Argument`s.
|
||||
So, the following examples will behave exactly the same:
|
||||
|
||||
```python
|
||||
class Person(graphene.ObjectType):
|
||||
say_hello = graphene.Field(graphene.String(),
|
||||
to=graphene.String())
|
||||
```
|
||||
and
|
||||
|
||||
```python
|
||||
class Person(graphene.ObjectType):
|
||||
say_hello = graphene.Field(graphene.String(),
|
||||
to=graphene.Argument(graphene.String()))
|
||||
```
|
|
@ -1,9 +1,13 @@
|
|||
---
|
||||
title: Interfaces
|
||||
description: Walkthrough Interfaces
|
||||
---
|
||||
|
||||
# Interfaces
|
||||
|
||||
An Interface contains the essential fields that will be shared among multiple ObjectTypes.
|
||||
|
||||
The basics:
|
||||
|
||||
- Each Interface is a Python class that inherits from graphene.Interface.
|
||||
- Each attribute of the Interface represents a GraphQL field.
|
||||
|
||||
|
@ -16,19 +20,19 @@ import graphene
|
|||
|
||||
# Character is an Interface
|
||||
class Character(graphene.Interface):
|
||||
name = graphene.String()
|
||||
name = graphene.String()
|
||||
|
||||
# Human is an ObjectType, as inherits an interface
|
||||
class Human(Character):
|
||||
born_in = graphene.String()
|
||||
born_in = graphene.String()
|
||||
|
||||
# Droid is an ObjectType, as inherits an interface
|
||||
class Droid(Character):
|
||||
function = graphene.String()
|
||||
function = graphene.String()
|
||||
|
||||
```
|
||||
|
||||
**name** is a field in the `Character` interface that will be in both `Human` and `Droid` ObjectTypes (as those inherit from Character). Each ObjectType also define extra fields at the same time.
|
||||
**name** is a field in the `Character` interface that will be in both `Human` and `Droid` ObjectTypes (as those inherit from `Character`). Each ObjectType also define extra fields at the same time.
|
||||
|
||||
The above types would have the following representation in a schema:
|
||||
|
75
docs/pages/docs/mutations.md
Normal file
75
docs/pages/docs/mutations.md
Normal file
|
@ -0,0 +1,75 @@
|
|||
---
|
||||
title: Mutations
|
||||
description: Walkthrough Mutations
|
||||
---
|
||||
|
||||
# Mutations
|
||||
|
||||
A Mutation is a special ObjectType that define also an Input.
|
||||
|
||||
## Quick example
|
||||
|
||||
This example defines a Mutation:
|
||||
|
||||
```python
|
||||
import graphene
|
||||
|
||||
class CreatePerson(graphene.Mutation):
|
||||
class Input:
|
||||
name = graphene.String()
|
||||
|
||||
ok = graphene.String()
|
||||
person = graphene.Field('Person')
|
||||
|
||||
@classmethod
|
||||
def mutate(cls, args, info):
|
||||
person = Person(name=args.get('name'))
|
||||
ok = True
|
||||
return CreatePerson(person=person, ok=ok)
|
||||
```
|
||||
|
||||
**person** and **ok** are the output fields of the Mutation when is resolved.
|
||||
|
||||
**Input** attributes are the arguments that the Mutation `CreatePerson` needs for resolving, in this case **name** will be the only argument for the mutation.
|
||||
|
||||
**mutate** is the function that will be applied once the mutation is called.
|
||||
|
||||
So, we can finish our schema like this:
|
||||
|
||||
```python
|
||||
# ... the Mutation Class
|
||||
|
||||
class Person(graphene.ObjectType):
|
||||
name = graphene.String()
|
||||
|
||||
class MyMutations(graphene.ObjectType):
|
||||
create_person = graphene.Field(CreatePerson)
|
||||
|
||||
schema = graphene.Schema(mutation=MyMutations)
|
||||
```
|
||||
|
||||
## Executing the Mutation
|
||||
|
||||
Then, if we query (`schema.execute(query_str)`) the following:
|
||||
```graphql
|
||||
mutation myFirstMutation {
|
||||
createPerson(name:"Peter") {
|
||||
person {
|
||||
name
|
||||
}
|
||||
ok
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
We should receive:
|
||||
|
||||
```json
|
||||
{
|
||||
"createPerson": {
|
||||
"person" : {
|
||||
name: "Peter"
|
||||
},
|
||||
"ok": true
|
||||
}
|
||||
}
|
|
@ -1,10 +1,14 @@
|
|||
---
|
||||
title: ObjectTypes
|
||||
description: Walkthrough ObjectTypes
|
||||
---
|
||||
|
||||
# ObjectTypes
|
||||
|
||||
An ObjectType is the single, definitive source of information about your data. It contains the essential fields and behaviors of the data you’re querying.
|
||||
|
||||
The basics:
|
||||
|
||||
- Each ObjectType is a Python class that inherits graphene.ObjectType or inherits an implemented [interface](/docs/interface).
|
||||
- Each ObjectType is a Python class that inherits graphene.ObjectType or inherits an implemented [interfaces](/docs/interfaces/).
|
||||
- Each attribute of the ObjectType represents a GraphQL field.
|
||||
|
||||
## Quick example
|
||||
|
@ -20,7 +24,7 @@ class Person(graphene.ObjectType):
|
|||
full_name = graphene.String()
|
||||
|
||||
def resolve_full_name(self, args, info):
|
||||
return '{} {}'.format(self.first_name, self.last_name)
|
||||
return '{} {}'.format(self.first_name, self.last_name)
|
||||
```
|
||||
|
||||
**first_name** and **last_name** are fields of the ObjectType. Each field is specified as a class attribute, and each attribute maps to a GraphQL field.
|
|
@ -1,13 +1,10 @@
|
|||
---
|
||||
title: Django Quickstart Guide
|
||||
active_tab: quickstart
|
||||
title: Guide to Django
|
||||
description: A Quick guide to Graphene in Django
|
||||
---
|
||||
|
||||
## Django Quickstart
|
||||
|
||||
In our previous quickstart page we created a very simple schema.
|
||||
Now we will adapt the schema for our Django models.
|
||||
Now we will adapt the schema to map automatically some Django models.
|
||||
|
||||
## Project setup
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
---
|
||||
title: Quickstart Guide
|
||||
active_tab: quickstart
|
||||
title: Getting started
|
||||
description: A Quick guide to Graphene
|
||||
---
|
||||
|
||||
Graphene is a powerful framework for creating GraphQL schemas easily in Python.
|
||||
Let's build a basic GraphQL schema from scratch.
|
||||
|
||||
|
||||
## Requirements
|
||||
|
||||
|
@ -23,6 +23,7 @@ cd tutorial
|
|||
virtualenv env
|
||||
source env/bin/activate # On Windows use `env\Scripts\activate`
|
||||
|
||||
# Install Graphene
|
||||
pip install graphene
|
||||
```
|
||||
|
||||
|
@ -30,7 +31,7 @@ pip install graphene
|
|||
|
||||
A GraphQL schema describes your data model, and provides a GraphQL server with an associated set of resolve methods that know how to fetch data.
|
||||
|
||||
We are going to create a very simple schema, with a `Query` with only one field: `hello`. And when we query it should return 'World'.
|
||||
We are going to create a very simple schema, with a `Query` with only one field: `hello`. And when we query it should return `"World"`.
|
||||
|
||||
|
||||
```python
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
# Mutations
|
||||
|
||||
A Mutation is a special ObjectType that define also an Input.
|
||||
|
||||
## Quick example
|
||||
|
||||
This example model defines a Mutation:
|
||||
|
||||
```python
|
||||
import graphene
|
||||
|
||||
class CreatePerson(graphene.Mutation):
|
||||
class Input:
|
||||
name = graphene.String()
|
||||
|
||||
ok = graphene.String()
|
||||
person = graphene.Field('Person')
|
||||
|
||||
@classmethod
|
||||
def mutate(cls, args, info):
|
||||
person = Person(name=args.get('name'))
|
||||
ok = True
|
||||
return CreatePerson(person=person, ok=ok)
|
||||
```
|
||||
|
||||
**person** and **ok** are the output fields of the Mutation when is resolved.
|
||||
**Input** attributes are the arguments that the Mutation needs for resolving. **mutate** is the function that will be applied once the mutation is called.
|
||||
|
||||
So, we can finish our schema like this:
|
||||
|
||||
```python
|
||||
# ... the Mutation Class
|
||||
|
||||
class Person(graphene.ObjectType):
|
||||
name = graphene.String()
|
||||
|
||||
class MyMutations(graphene.ObjectType):
|
||||
create_person = graphene.Field(CreatePerson)
|
||||
|
||||
schema = graphene.Schema(mutation=MyMutations)
|
||||
```
|
||||
|
||||
## Executing the Mutation
|
||||
|
||||
Then, if we query (`schema.execute(query_str)`) the following:
|
||||
```graphql
|
||||
mutation myFirstMutation {
|
||||
createPerson(name:"Peter") {
|
||||
person {
|
||||
name
|
||||
}
|
||||
ok
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
We should receive:
|
||||
|
||||
```json
|
||||
{
|
||||
"createPerson": {
|
||||
"person" : {
|
||||
name: "Peter"
|
||||
},
|
||||
"ok": true
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
path: /
|
||||
---
|
||||
<a class="starwars-example" href="http://swapi.graphene-python.org/">Check our starwars API example!</a>
|
||||
<div><a class="starwars-example" href="http://swapi.graphene-python.org/">Check our Django Starwars API example!</a></div>
|
||||
|
||||
## About Graphene
|
||||
|
||||
|
|
|
@ -9,15 +9,15 @@ class Markdown extends React.Component {
|
|||
var post = this.props.page.data;
|
||||
var pagePath = this.props.page.requirePath;
|
||||
var documentUrl = `${DOCS_BASEURL}${pagePath}`;
|
||||
|
||||
var showTitle = post.title && !this.props.docs;
|
||||
return (
|
||||
<DocumentTitle title={`${post.title?post.title+' - ':''}${this.props.config.siteTitle}`}>
|
||||
<div className="markdown">
|
||||
{post.title?<div className="title">
|
||||
{showTitle?<div className="title">
|
||||
<h1>{post.title}</h1>
|
||||
</div>:null}
|
||||
<div className="wrapper" dangerouslySetInnerHTML={{__html: post.body}}/>
|
||||
<a href={documentUrl} className="improve-document-link">Improve this document!</a>
|
||||
<div className={!this.props.docs?"wrapper":null} dangerouslySetInnerHTML={{__html: post.body}}/>
|
||||
<a href={documentUrl} className="improve-document-link">Edit page</a>
|
||||
</div>
|
||||
</DocumentTitle>
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue
Block a user