Add portfolio backend

This commit is contained in:
Ramon Wenger 2019-03-07 10:49:52 +01:00
parent 25c282a194
commit 485a6ca4eb
13 changed files with 156 additions and 11 deletions

View File

@ -13,20 +13,22 @@ from books.schema.queries import BookQuery
from core.schema.mutations.main import CoreMutations
from objectives.mutations import ObjectiveMutations
from objectives.schema import ObjectivesQuery
from portfolio.mutations import PortfolioMutations
from portfolio.schema import PortfolioQuery
from rooms.mutations import RoomMutations
from rooms.schema import RoomsQuery
from users.schema import UsersQuery
class Query(UsersQuery, RoomsQuery, ObjectivesQuery, BookQuery, AssignmentsQuery, StudentSubmissionQuery,
BasicKnowledgeQuery, graphene.ObjectType):
BasicKnowledgeQuery, PortfolioQuery, graphene.ObjectType):
node = relay.Node.Field()
if settings.DEBUG:
debug = graphene.Field(DjangoDebug, name='__debug')
class Mutation(BookMutations, RoomMutations, AssignmentMutations, ObjectiveMutations, CoreMutations,
class Mutation(BookMutations, RoomMutations, AssignmentMutations, ObjectiveMutations, CoreMutations, PortfolioMutations,
graphene.ObjectType):
if settings.DEBUG:
debug = graphene.Field(DjangoDebug, name='__debug')

View File

@ -1,6 +1,7 @@
import io
import os
from django.apps import apps
from graphene_django.filter import DjangoFilterConnectionField
from graphql_relay.node.node import from_global_id
@ -53,3 +54,14 @@ def get_graphql_mutation(filename):
mutation = f.read()
return mutation
def get_by_id_or_slug(model, **kwargs):
slug = kwargs.get('slug')
id = kwargs.get('id')
if id is not None:
return get_object(model, id)
if slug is not None:
return model.objects.get(slug=slug)
return None

View File

@ -51,6 +51,7 @@ INSTALLED_APPS = [
'rooms',
'assignments',
'basicknowledge',
'portfolio',
'statistics',
'wagtail.contrib.forms',

View File

View File

@ -0,0 +1,17 @@
import graphene
from graphene import InputObjectType
class ProjectInput(InputObjectType):
title = graphene.String()
description = graphene.String()
objectives = graphene.String()
appearance = graphene.String()
class AddProjectArgument(ProjectInput):
pass
class UpdateProjectArgument(ProjectInput):
id = graphene.ID(required=True)

View File

@ -0,0 +1,29 @@
# Generated by Django 2.0.6 on 2019-03-06 14:47
from django.db import migrations, models
import django_extensions.db.fields
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Project',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=255, verbose_name='title')),
('description', models.TextField(blank=True, null=True, verbose_name='description')),
('slug', django_extensions.db.fields.AutoSlugField(blank=True, editable=False, populate_from='title', verbose_name='slug')),
('objectives', models.TextField(blank=True)),
('appearance', models.CharField(blank=True, max_length=255)),
],
options={
'abstract': False,
},
),
]

View File

View File

@ -0,0 +1,10 @@
from django.db import models
from django_extensions.db.models import TitleSlugDescriptionModel
class Project(TitleSlugDescriptionModel):
objectives = models.TextField(blank=True)
appearance = models.CharField(blank=True, null=False, max_length=255)
def __str__(self):
return self.title

View File

@ -0,0 +1,40 @@
import graphene
from graphene import relay
from api.utils import get_object
from portfolio.inputs import AddProjectArgument, UpdateProjectArgument
from portfolio.models import Project
from portfolio.schema import ProjectNode
from portfolio.serializers import ProjectSerializer
class MutateProject(relay.ClientIDMutation):
errors = graphene.List(graphene.String)
project = graphene.Field(ProjectNode)
@classmethod
def mutate_and_get_payload(cls, *args, **kwargs):
project_data = kwargs.get('project')
if project_data.get('id') is not None:
project = get_object(Project, project_data['id'])
serializer = ProjectSerializer(project, data=project_data)
else:
serializer = ProjectSerializer(data=project_data)
if serializer.is_valid():
serializer.save()
return cls(project=serializer.instance, errors=None)
return cls(project=None, errors=['{}: {}'.format(key, value) for key, value in serializer.errors.items()])
class AddProject(MutateProject):
class Input:
project = graphene.Argument(AddProjectArgument) # NB: can't be named AddProjectInput, otherwise graphene complains
class UpdateProject(MutateProject):
class Input:
project = graphene.Argument(UpdateProjectArgument)
class PortfolioMutations:
add_project = AddProject.Field()
update_project = UpdateProject.Field()

View File

@ -0,0 +1,31 @@
import graphene
from graphene import relay
from graphene_django import DjangoObjectType
from graphene_django.filter import DjangoFilterConnectionField
from api.utils import get_by_id_or_slug
from portfolio.models import Project
class ProjectNode(DjangoObjectType):
pk = graphene.Int()
class Meta:
model = Project
filter_fields = ['slug', 'appearance']
interfaces = (relay.Node,)
def resolve_pk(self, *args, **kwargs):
return self.id
class PortfolioQuery(object):
project = graphene.Field(ProjectNode, id=graphene.ID(), slug=graphene.String())
projects = DjangoFilterConnectionField(ProjectNode)
def resolve_projects(self, info, **kwargs):
return Project.objects.all()
def resolve_project(self, info, **kwargs):
return get_by_id_or_slug(Project, **kwargs)

View File

@ -0,0 +1,10 @@
from rest_framework import serializers
from portfolio.models import Project
class ProjectSerializer(serializers.ModelSerializer):
class Meta:
model = Project
fields = ('id', 'title', 'description', 'objectives', 'slug', 'appearance',)
read_only_fields = ('id', 'slug',)

View File

@ -5,7 +5,7 @@ from graphene import relay
from graphene_django import DjangoObjectType
from graphene_django.filter import DjangoFilterConnectionField
from api.utils import get_object
from api.utils import get_object, get_by_id_or_slug
from rooms.models import Room, RoomEntry
from users.schema import UserNode
@ -55,14 +55,7 @@ class RoomsQuery(object):
return Room.objects.filter(school_class__in=user.school_classes.all())
def resolve_room(self, info, **kwargs):
slug = kwargs.get('slug')
room_id = kwargs.get('id')
if room_id is not None:
return get_object(Room, room_id)
if slug is not None:
return Room.objects.get(slug=slug)
return None
return get_by_id_or_slug(Room, **kwargs)
def resolve_room_entry(self, info, **kwargs):
slug = kwargs.get('slug')