-
Notifications
You must be signed in to change notification settings - Fork 35
/
schema.py
144 lines (105 loc) · 4.43 KB
/
schema.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# source: https://github.com/graphql-python/graphene-django/
# https://facebook.github.io/relay/graphql/mutations.htm
# https://facebook.github.io/relay/graphql/mutations.htm
# http://docs.graphene-python.org/projects/django/en/latest/tutorial-plain/
import graphene
from graphene import relay, ObjectType, InputObjectType
from graphene_django import DjangoObjectType
from graphene_django.filter import DjangoFilterConnectionField
from django.core.exceptions import ValidationError
from django.contrib.auth.models import User
from bookmeapi.models import Book, Issue
from bookmeapi.helpers import get_object, get_errors, update_create_instance
class UserCreateInput(InputObjectType):
username = graphene.String(required=True)
first_name = graphene.String(required=False)
last_name = graphene.String(required=False)
email = graphene.String(required=True)
is_staff = graphene.Boolean(required=False)
is_active = graphene.Boolean(required=False)
password = graphene.String(required=True)
class BookCreateInput(InputObjectType):
"""
Class created to accept input data
from the interactive graphql console.
"""
title = graphene.String(required=False)
isbn = graphene.String(required=False)
category = graphene.String(required=False)
class UserNode(DjangoObjectType):
class Meta:
model = User
# Allow for some more advanced filtering here
filter_fields = {
'first_name': ['exact', 'icontains', 'istartswith'],
'last_name': ['exact', 'icontains', 'istartswith'],
'username': ['exact'],
}
interfaces = (relay.Node, )
class BookNode(DjangoObjectType):
class Meta:
model = Book
filter_fields = {
'title': ['exact','istartswith'],
'isbn':['exact'],
'category':['exact', 'icontains','istartswith'],
}
interfaces = (relay.Node, )
class CreateUser(relay.ClientIDMutation):
class Input:
user = graphene.Argument(UserCreateInput)
new_user = graphene.Field(UserNode)
@classmethod
def mutate_and_get_payload(cls, args, context, info):
user_data = args.get('user')
# unpack the dict item into the model instance
new_user = User.objects.create(**user_data)
new_user.set_password(user_data.get('password'))
new_user.save()
return cls(new_user=new_user)
class CreateBook(relay.ClientIDMutation):
class Input:
# BookCreateInput class used as argument here.
book = graphene.Argument(BookCreateInput)
new_book = graphene.Field(BookNode)
@classmethod
def mutate_and_get_payload(cls, args, context, info):
book_data = args.get('book') # get the book input from the args
book = Book() # get an instance of the book model here
new_book = update_create_instance(book, book_data) # use custom function to create book
return cls(new_book=new_book) # newly created book instance returned.
class UpdateBook(relay.ClientIDMutation):
class Input:
book = graphene.Argument(BookCreateInput) # get the book input from the args
id = graphene.String(required=True) # get the book id
errors = graphene.List(graphene.String)
updated_book = graphene.Field(BookNode)
@classmethod
def mutate_and_get_payload(cls, args, context, info):
try:
book_instance = get_object(Book, args['id']) # get book by id
if book_instance:
# modify and update book model instance
book_data = args.get('book')
updated_book = update_create_instance(book_instance, book_data)
return cls(updated_book=updated_book)
except ValidationError as e:
# return an error if something wrong happens
return cls(updated_book=None, errors=get_errors(e))
class Query(ObjectType):
users = relay.Node.Field(UserNode) # get user by id or by field name
all_users = DjangoFilterConnectionField(UserNode) # get all users
books = relay.Node.Field(BookNode)
all_books = DjangoFilterConnectionField(BookNode)
def resolve_users(self):
return User.objects.all()
def resolve_books(self):
return Book.objects.all()
class Mutation(ObjectType):
create_user = CreateUser.Field()
create_book = CreateBook.Field()
update_book = UpdateBook.Field()
schema = graphene.Schema(
query=Query,
mutation=Mutation,
)