diff --git a/evgenApp/__pycache__/schema.cpython-36.pyc b/evgenApp/__pycache__/schema.cpython-36.pyc index 6ef9f53..2b49971 100644 Binary files a/evgenApp/__pycache__/schema.cpython-36.pyc and b/evgenApp/__pycache__/schema.cpython-36.pyc differ diff --git a/evgenApp/__pycache__/settings.cpython-36.pyc b/evgenApp/__pycache__/settings.cpython-36.pyc index 0ffb747..285217a 100644 Binary files a/evgenApp/__pycache__/settings.cpython-36.pyc and b/evgenApp/__pycache__/settings.cpython-36.pyc differ diff --git a/evgenApp/schema.py b/evgenApp/schema.py index d674c23..67e2ae2 100644 --- a/evgenApp/schema.py +++ b/evgenApp/schema.py @@ -1,8 +1,12 @@ import graphene import users.schema +import organisations.schema -class Query(users.schema.Query, graphene.ObjectType): +class Query(users.schema.Query, organisations.schema.Query, graphene.ObjectType): + pass + +class Mutation(users.schema.Mutation, organisations.schema.Mutation, graphene.ObjectType): pass -schema = graphene.Schema(query=Query) \ No newline at end of file +schema = graphene.Schema(query=Query, mutation=Mutation) \ No newline at end of file diff --git a/evgenApp/settings.py b/evgenApp/settings.py index 74b20c7..e32828a 100644 --- a/evgenApp/settings.py +++ b/evgenApp/settings.py @@ -39,9 +39,15 @@ INSTALLED_APPS = [ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', + 'users', + 'organisations', + 'lessons' ] GRAPHENE = { - 'SCHEMA': 'evgenApp.schema.schema' + 'SCHEMA': 'evgenApp.schema.schema', + 'MIDDLEWARE': [ + 'graphql_jwt.middleware.JSONWebTokenMiddleware', + ], } CORS_ORIGIN_ALLOW_ALL = False @@ -53,6 +59,7 @@ CORS_ORIGIN_WHITELIST = ( MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', @@ -118,6 +125,16 @@ AUTH_PASSWORD_VALIDATORS = [ }, ] +AUTHENTICATION_BACKENDS = [ + 'graphql_jwt.backends.JSONWebTokenBackend', + 'django.contrib.auth.backends.AllowAllUsersModelBackend', +] + +GRAPHQL_JWT = { + 'JWT_ALLOW_ARGUMENT': True, +} +JWT_ARGUMENT_NAME = "token" + # Internationalization # https://docs.djangoproject.com/en/2.0/topics/i18n/ diff --git a/lessons/__init__.py b/lessons/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/lessons/__pycache__/__init__.cpython-36.pyc b/lessons/__pycache__/__init__.cpython-36.pyc new file mode 100644 index 0000000..1102dd7 Binary files /dev/null and b/lessons/__pycache__/__init__.cpython-36.pyc differ diff --git a/lessons/__pycache__/admin.cpython-36.pyc b/lessons/__pycache__/admin.cpython-36.pyc new file mode 100644 index 0000000..5386067 Binary files /dev/null and b/lessons/__pycache__/admin.cpython-36.pyc differ diff --git a/lessons/__pycache__/models.cpython-36.pyc b/lessons/__pycache__/models.cpython-36.pyc new file mode 100644 index 0000000..7c50a97 Binary files /dev/null and b/lessons/__pycache__/models.cpython-36.pyc differ diff --git a/lessons/admin.py b/lessons/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/lessons/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/lessons/apps.py b/lessons/apps.py new file mode 100644 index 0000000..4d07a9e --- /dev/null +++ b/lessons/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class LessonsConfig(AppConfig): + name = 'lessons' diff --git a/lessons/db_functions.py b/lessons/db_functions.py new file mode 100644 index 0000000..16c97d0 --- /dev/null +++ b/lessons/db_functions.py @@ -0,0 +1,21 @@ +from .models import Subject, SubjectClassLocal +from organisations.models import Organisation + + +def extendOrganisationSubject(org, sub_name): + Subject.objects.create(name=sub_name, organisation=org) + + +def addSubjectToGroup(group, subName, subject): + SubjectClassLocal.objects.create(name=subName, subject=subject, group=group) + + +def addClassToTeacher(classLocal, teacher): + classLocal.teachers.add(teacher) + + +def removeTeacherFromClass(classLocal, teacher): + classLocal.teachers.remove(teacher) + +def addLessonToClass(classLocal): + Lesson \ No newline at end of file diff --git a/lessons/migrations/0001_initial.py b/lessons/migrations/0001_initial.py new file mode 100644 index 0000000..7f712da --- /dev/null +++ b/lessons/migrations/0001_initial.py @@ -0,0 +1,35 @@ +# Generated by Django 3.1.5 on 2021-01-08 20:17 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('organisations', '0004_auto_20210108_2013'), + ] + + operations = [ + migrations.CreateModel( + name='Subject', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=100)), + ('organisation', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='organisations.organisation')), + ('teachers_give', models.ManyToManyField(to='organisations.Teacher')), + ], + ), + migrations.CreateModel( + name='SubjectClassLocal', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=100)), + ('group', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='organisations.group')), + ('subject', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='lessons.subject')), + ('teachers', models.ManyToManyField(to='organisations.Teacher')), + ], + ), + ] diff --git a/lessons/migrations/0002_auto_20210109_1220.py b/lessons/migrations/0002_auto_20210109_1220.py new file mode 100644 index 0000000..566d0ec --- /dev/null +++ b/lessons/migrations/0002_auto_20210109_1220.py @@ -0,0 +1,91 @@ +# Generated by Django 3.1.5 on 2021-01-09 12:20 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('organisations', '0004_auto_20210108_2013'), + ('lessons', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Lesson', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('type_lesson', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='lessons.subjectclasslocal')), + ], + ), + migrations.CreateModel( + name='Materials', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('link', models.URLField()), + ('name', models.CharField(blank=True, max_length=100)), + ], + ), + migrations.CreateModel( + name='Task', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('theory', models.TextField()), + ('practise', models.TextField()), + ('number', models.IntegerField()), + ], + ), + migrations.CreateModel( + name='Type', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.TextField(max_length=150)), + ], + ), + migrations.CreateModel( + name='Theme', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=150)), + ('tasks', models.ManyToManyField(to='lessons.Task')), + ], + ), + migrations.CreateModel( + name='Tests', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=150)), + ('deadline', models.DateTimeField()), + ('lesson', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='lessons.lesson')), + ], + ), + migrations.AddField( + model_name='task', + name='test', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='lessons.tests'), + ), + migrations.AddField( + model_name='task', + name='type', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='lessons.type'), + ), + migrations.CreateModel( + name='AnswerSheet', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('completed', models.BooleanField(default=False)), + ('child', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='organisations.child')), + ('test', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='lessons.tests')), + ], + ), + migrations.CreateModel( + name='Answer', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('content', models.TextField()), + ('number', models.IntegerField()), + ('sheet', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='lessons.answersheet')), + ], + ), + ] diff --git a/lessons/migrations/__init__.py b/lessons/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/lessons/migrations/__pycache__/0001_initial.cpython-36.pyc b/lessons/migrations/__pycache__/0001_initial.cpython-36.pyc new file mode 100644 index 0000000..caf0e16 Binary files /dev/null and b/lessons/migrations/__pycache__/0001_initial.cpython-36.pyc differ diff --git a/lessons/migrations/__pycache__/0002_auto_20210109_1220.cpython-36.pyc b/lessons/migrations/__pycache__/0002_auto_20210109_1220.cpython-36.pyc new file mode 100644 index 0000000..2918d86 Binary files /dev/null and b/lessons/migrations/__pycache__/0002_auto_20210109_1220.cpython-36.pyc differ diff --git a/lessons/migrations/__pycache__/__init__.cpython-36.pyc b/lessons/migrations/__pycache__/__init__.cpython-36.pyc new file mode 100644 index 0000000..62c0def Binary files /dev/null and b/lessons/migrations/__pycache__/__init__.cpython-36.pyc differ diff --git a/lessons/models.py b/lessons/models.py new file mode 100644 index 0000000..cdde3d3 --- /dev/null +++ b/lessons/models.py @@ -0,0 +1,74 @@ +from django.db import models +from organisations.models import Organisation, Teacher, Group, Child + +from django.dispatch import receiver +from django.db.models.signals import post_save + + +class Subject(models.Model): + name = models.CharField(max_length=100) + organisation = models.ForeignKey(Organisation, on_delete=models.CASCADE) + teachers_give = models.ManyToManyField(Teacher) + +class SubjectClassLocal(models.Model): + subject = models.ForeignKey(Subject, on_delete=models.CASCADE) + teachers = models.ManyToManyField(Teacher) + group = models.ForeignKey(Group, on_delete=models.CASCADE) + name = models.CharField(max_length=100, unique=False) + + def __str__(self): + return self.name + + +class Lesson(models.Model): + type_lesson = models.ForeignKey(SubjectClassLocal, on_delete=models.CASCADE) + + +class Materials(models.Model): + link = models.URLField() + name = models.CharField(max_length=100, blank=True) + + +class Tests(models.Model): + name = models.CharField(max_length=150) + deadline = models.DateTimeField() + lesson = models.ForeignKey(Lesson, on_delete=models.CASCADE) + +class Type(models.Model): + name = models.TextField(max_length=150) + +class Task(models.Model): + theory = models.TextField() + practise = models.TextField() + test = models.ForeignKey(Tests, on_delete=models.CASCADE) + type = models.ForeignKey(Type, on_delete=models.PROTECT) + number = models.IntegerField() + + + +class Theme(models.Model): + tasks = models.ManyToManyField(Task) + name = models.CharField(max_length=150) + +class AnswerSheet(models.Model): + child = models.ForeignKey(Child, on_delete=models.CASCADE) + completed = models.BooleanField(default=False) + test = models.ForeignKey(Tests, on_delete=models.CASCADE) + +class Answer(models.Model): + sheet = models.ForeignKey(AnswerSheet, on_delete=models.CASCADE) + content = models.TextField() + number = models.IntegerField() + + +@receiver(post_save, sender=Tests) +def _post_save_receiver(sender, instance, created, **kwargs): + if created: + for child in instance.lesson.type_lesson.group.child_set.all(): + AnswerSheet.objects.create(child=child, completed=False, test=instance) + +@receiver(post_save, sender=Task) +def _post_save_receiver(sender, instance, created, **kwargs): + if created: + for child in instance.test.lesson.type_lesson.group.child_set.all(): + Answer.objects.create(number=instance.number, sheet=child.answer_sheet_set.all().filter(test=instance.test)[0], content="") \ No newline at end of file diff --git a/lessons/tests.py b/lessons/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/lessons/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/lessons/views.py b/lessons/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/lessons/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/organisations/__init__.py b/organisations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/organisations/__pycache__/__init__.cpython-36.pyc b/organisations/__pycache__/__init__.cpython-36.pyc new file mode 100644 index 0000000..3fa8778 Binary files /dev/null and b/organisations/__pycache__/__init__.cpython-36.pyc differ diff --git a/organisations/__pycache__/admin.cpython-36.pyc b/organisations/__pycache__/admin.cpython-36.pyc new file mode 100644 index 0000000..83a62ee Binary files /dev/null and b/organisations/__pycache__/admin.cpython-36.pyc differ diff --git a/organisations/__pycache__/gqlTypes.cpython-36.pyc b/organisations/__pycache__/gqlTypes.cpython-36.pyc new file mode 100644 index 0000000..865fe61 Binary files /dev/null and b/organisations/__pycache__/gqlTypes.cpython-36.pyc differ diff --git a/organisations/__pycache__/models.cpython-36.pyc b/organisations/__pycache__/models.cpython-36.pyc new file mode 100644 index 0000000..802ce1a Binary files /dev/null and b/organisations/__pycache__/models.cpython-36.pyc differ diff --git a/organisations/__pycache__/mutation.cpython-36.pyc b/organisations/__pycache__/mutation.cpython-36.pyc new file mode 100644 index 0000000..d657a24 Binary files /dev/null and b/organisations/__pycache__/mutation.cpython-36.pyc differ diff --git a/organisations/__pycache__/query.cpython-36.pyc b/organisations/__pycache__/query.cpython-36.pyc new file mode 100644 index 0000000..4607a87 Binary files /dev/null and b/organisations/__pycache__/query.cpython-36.pyc differ diff --git a/organisations/__pycache__/schema.cpython-36.pyc b/organisations/__pycache__/schema.cpython-36.pyc new file mode 100644 index 0000000..eabc0ba Binary files /dev/null and b/organisations/__pycache__/schema.cpython-36.pyc differ diff --git a/organisations/admin.py b/organisations/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/organisations/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/organisations/apps.py b/organisations/apps.py new file mode 100644 index 0000000..9542581 --- /dev/null +++ b/organisations/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class OrganisationsConfig(AppConfig): + name = 'organisations' diff --git a/organisations/gqlTypes.py b/organisations/gqlTypes.py new file mode 100644 index 0000000..bf88052 --- /dev/null +++ b/organisations/gqlTypes.py @@ -0,0 +1,27 @@ +import graphene_django +from .models import Organisation, Role, Group, Teacher, Child + +print(Teacher, Child) + +class OrganisationType(graphene_django.DjangoObjectType): + class Meta: + model = Organisation + +class RoleType(graphene_django.DjangoObjectType): + class Meta: + model = Role + + +class GroupType(graphene_django.DjangoObjectType): + class Meta: + model = Group + + +class TeacherType(graphene_django.DjangoObjectType): + class Meta: + model = Teacher + + +class ChildType(graphene_django.DjangoObjectType): + class Meta: + model = Child \ No newline at end of file diff --git a/organisations/migrations/0001_initial.py b/organisations/migrations/0001_initial.py new file mode 100644 index 0000000..992949d --- /dev/null +++ b/organisations/migrations/0001_initial.py @@ -0,0 +1,75 @@ +# Generated by Django 3.1.5 on 2021-01-07 21:23 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('users', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Group', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=20)), + ], + ), + migrations.CreateModel( + name='Organisation', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.TextField()), + ], + ), + migrations.CreateModel( + name='Role', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=50)), + ], + ), + migrations.CreateModel( + name='Subject', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=100)), + ('org', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='organisations.organisation')), + ], + ), + migrations.CreateModel( + name='Teacher', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(blank=True, max_length=150)), + ('surname', models.CharField(blank=True, max_length=150)), + ('midname', models.CharField(blank=True, max_length=150)), + ('groups', models.ManyToManyField(to='organisations.Group')), + ('org', models.ForeignKey(blank=True, on_delete=django.db.models.deletion.CASCADE, to='organisations.organisation')), + ('profile', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='users.profile')), + ('subject_area', models.ManyToManyField(to='organisations.Subject')), + ], + ), + migrations.AddField( + model_name='group', + name='org', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='organisations.organisation'), + ), + migrations.CreateModel( + name='Child', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(blank=True, max_length=150)), + ('surname', models.CharField(blank=True, max_length=150)), + ('midname', models.CharField(blank=True, max_length=150)), + ('groups', models.ManyToManyField(to='organisations.Group')), + ('org', models.ForeignKey(blank=True, on_delete=django.db.models.deletion.CASCADE, to='organisations.organisation')), + ('profile', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='users.profile')), + ], + ), + ] diff --git a/organisations/migrations/0002_auto_20210107_2139.py b/organisations/migrations/0002_auto_20210107_2139.py new file mode 100644 index 0000000..9a5a53f --- /dev/null +++ b/organisations/migrations/0002_auto_20210107_2139.py @@ -0,0 +1,20 @@ +# Generated by Django 3.1.5 on 2021-01-07 21:39 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0001_initial'), + ('organisations', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='teacher', + name='profile', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='users.profile'), + ), + ] diff --git a/organisations/migrations/0003_auto_20210107_2142.py b/organisations/migrations/0003_auto_20210107_2142.py new file mode 100644 index 0000000..7b1c044 --- /dev/null +++ b/organisations/migrations/0003_auto_20210107_2142.py @@ -0,0 +1,20 @@ +# Generated by Django 3.1.5 on 2021-01-07 21:42 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0001_initial'), + ('organisations', '0002_auto_20210107_2139'), + ] + + operations = [ + migrations.AlterField( + model_name='child', + name='profile', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='users.profile'), + ), + ] diff --git a/organisations/migrations/0004_auto_20210108_2013.py b/organisations/migrations/0004_auto_20210108_2013.py new file mode 100644 index 0000000..94bc6cd --- /dev/null +++ b/organisations/migrations/0004_auto_20210108_2013.py @@ -0,0 +1,20 @@ +# Generated by Django 3.1.5 on 2021-01-08 20:13 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('organisations', '0003_auto_20210107_2142'), + ] + + operations = [ + migrations.RemoveField( + model_name='teacher', + name='subject_area', + ), + migrations.DeleteModel( + name='Subject', + ), + ] diff --git a/organisations/migrations/__init__.py b/organisations/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/organisations/migrations/__pycache__/0001_initial.cpython-36.pyc b/organisations/migrations/__pycache__/0001_initial.cpython-36.pyc new file mode 100644 index 0000000..ab179e2 Binary files /dev/null and b/organisations/migrations/__pycache__/0001_initial.cpython-36.pyc differ diff --git a/organisations/migrations/__pycache__/0002_auto_20210107_2139.cpython-36.pyc b/organisations/migrations/__pycache__/0002_auto_20210107_2139.cpython-36.pyc new file mode 100644 index 0000000..aacb3e7 Binary files /dev/null and b/organisations/migrations/__pycache__/0002_auto_20210107_2139.cpython-36.pyc differ diff --git a/organisations/migrations/__pycache__/0003_auto_20210107_2142.cpython-36.pyc b/organisations/migrations/__pycache__/0003_auto_20210107_2142.cpython-36.pyc new file mode 100644 index 0000000..c46587b Binary files /dev/null and b/organisations/migrations/__pycache__/0003_auto_20210107_2142.cpython-36.pyc differ diff --git a/organisations/migrations/__pycache__/0004_auto_20210108_2013.cpython-36.pyc b/organisations/migrations/__pycache__/0004_auto_20210108_2013.cpython-36.pyc new file mode 100644 index 0000000..24c7b51 Binary files /dev/null and b/organisations/migrations/__pycache__/0004_auto_20210108_2013.cpython-36.pyc differ diff --git a/organisations/migrations/__pycache__/__init__.cpython-36.pyc b/organisations/migrations/__pycache__/__init__.cpython-36.pyc new file mode 100644 index 0000000..99ddce3 Binary files /dev/null and b/organisations/migrations/__pycache__/__init__.cpython-36.pyc differ diff --git a/organisations/models.py b/organisations/models.py new file mode 100644 index 0000000..ab3a051 --- /dev/null +++ b/organisations/models.py @@ -0,0 +1,43 @@ +from django.db import models + + +from django.db.models.signals import post_save +from django.dispatch import receiver + +from users.models import Profile + +class Role(models.Model): + name = models.CharField(max_length=50) + + + +class Organisation(models.Model): + name = models.TextField() + + def __str__(self): + return self.name + + +class Group(models.Model): + name = models.CharField(max_length=20) + org = models.ForeignKey(Organisation, models.CASCADE, unique=False) + + def __str__(self): + return self.name + + +class Teacher(models.Model): + org = models.ForeignKey(Organisation, models.CASCADE, blank=True) + profile = models.ForeignKey(Profile, models.CASCADE) + groups = models.ManyToManyField(Group) + name = models.CharField(max_length=150, blank=True) + surname = models.CharField(max_length=150, blank=True) + midname = models.CharField(max_length=150, blank=True) + +class Child(models.Model): + profile = models.ForeignKey(Profile, models.CASCADE) + org = models.ForeignKey(Organisation, models.CASCADE, blank=True) + groups = models.ManyToManyField(Group) + name = models.CharField(max_length=150, blank=True) + surname = models.CharField(max_length=150, blank=True) + midname = models.CharField(max_length=150, blank=True) \ No newline at end of file diff --git a/organisations/mutation.py b/organisations/mutation.py new file mode 100644 index 0000000..7f9602c --- /dev/null +++ b/organisations/mutation.py @@ -0,0 +1,111 @@ +import graphene + +from .gqlTypes import OrganisationType, RoleType, GroupType +from .models import Organisation, Role, Group, Teacher, Child + +from users.schema import UserType + +class CreateGroup(graphene.Mutation): + class Arguments: + org_name = graphene.String() + groupName = graphene.String() + + group = graphene.Field(GroupType) + + def mutate(self, info, org_name, groupName, **kwargs): + return CreateGroup(group=Group.objects.create(name=groupName, org=Organisation.objects.get(name=org_name))) + + +class CreateOrg(graphene.Mutation): + class Arguments: + name = graphene.String() + + Org = graphene.Field(OrganisationType) + + def mutate(self, info, name, **kwargs): + return CreateOrg(Org=Organisation.objects.create(name=name)) + +class RegUserOrg(graphene.Mutation): + class Arguments: + token = graphene.String() + orgName = graphene.String() + isTeacher = graphene.Boolean() + name = graphene.String(required=False) + surname = graphene.String(required=False) + midname = graphene.String(required=False) + + ok = graphene.Boolean() + + def mutate(self, info, token, orgName, isTeacher, **kwargs): + org = Organisation.objects.get(name=orgName) + if isTeacher: + t = Teacher.objects.create(profile=info.context.user.profile, org=org) + else: + t = Child.objects.create(profile=info.context.user.profile, org=org) + return RegUserOrg(ok=True) + + + +class AddGroupToOrg(graphene.Mutation): + class Arguments: + orgName = graphene.String() + groupName = graphene.String() + + group = graphene.Field(GroupType) + def mutate(self, info, orgName, groupName): + group = Group.objects.create(name=groupName, org=Organisation.objects.get(name=orgName)) + return AddGroupToOrg(group=group) + + +class RegUserGroup(graphene.Mutation): + class Arguments: + token = graphene.String() + orgName = graphene.String() + groupName = graphene.String() + is_teacher = graphene.Boolean() + user = graphene.Field(UserType) + def mutate(self, info, token, orgName, groupName, is_teacher, **kwargs): + group = Organisation.objects.get(name=orgName).group_set.all().filter(name=groupName)[0] + if is_teacher: + info.context.user.profile.teacher_set.all().filter(org__name=orgName)[0].groups.add(group) + else: + info.context.user.profile.child_set.all().filter(org__name=orgName)[0].groups.add(group) + return RegUserGroup(info.context.user) + +class DeleteGroup(graphene.Mutation): + class Arguments: + orgName = graphene.String() + groupName = graphene.String() + ok = graphene.Boolean() + def mutate(self, info, orgName, groupName, **kwargs): + Organisation.objects.find(name=orgName).objects.groups.all().filter(name=groupName)[0].delete() + +class DeleteUserFromGroup(graphene.Mutation): + class Arguments: + orgName = graphene.String() + groupName = graphene.String() + token = graphene.String() + is_teacher = graphene.Boolean() + user = graphene.Field(UserType) + def mutate(self, info, orgName, groupName, token, is_teacher, **kwargs): + if is_teacher: + group = info.context.user.profile.teacher_set.all().filter(org__name=orgName)[0].groups.all().filter(name=groupName)[0] + org = info.context.user.profile.teacher_set.all().filter(org__name=orgName)[0] + print(group, org) + org.groups.remove(group) + return DeleteuserFromGroup(info.context.user) + else: + group = info.context.user.profile.child_set.all().filter(org__name=orgName)[0].groups.all().filter(name=groupName)[0] + org = info.context.user.profile.child_set.all().filter(org__name=orgName)[0] + print(group, org) + org.groups.remove(group) + + +class Mutation(graphene.ObjectType): + create_org = CreateOrg.Field() + reg_user_org = RegUserOrg.Field() + create_group = CreateGroup.Field() + reg_user_to_group = RegUserGroup.Field() + add_group_to_org = AddGroupToOrg.Field() + delete_group = DeleteGroup.Field() + delete_user_from_group = DeleteUserFromGroup.Field() \ No newline at end of file diff --git a/organisations/query.py b/organisations/query.py new file mode 100644 index 0000000..41736e2 --- /dev/null +++ b/organisations/query.py @@ -0,0 +1,15 @@ +import graphene + +from .gqlTypes import OrganisationType, RoleType +from .models import Organisation, Role + + +class Query(graphene.ObjectType): + organisations = graphene.Field(graphene.List(OrganisationType)) + roles = graphene.Field(graphene.List(RoleType)) + + def resolve_organisations(self, info, **kwargs): + return Organisation.objects.all() + + def resolve_roles(self, info, **kwargs): + return Role.objects.all() \ No newline at end of file diff --git a/organisations/schema.py b/organisations/schema.py new file mode 100644 index 0000000..fbdb59c --- /dev/null +++ b/organisations/schema.py @@ -0,0 +1,9 @@ +import graphene_django +import graphene + + +from .mutation import Mutation + +from .query import Query + +schema = graphene.Schema(query=Query, mutation=Mutation) \ No newline at end of file diff --git a/organisations/tests.py b/organisations/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/organisations/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/organisations/views.py b/organisations/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/organisations/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/users/__pycache__/admin.cpython-36.pyc b/users/__pycache__/admin.cpython-36.pyc new file mode 100644 index 0000000..87ddc04 Binary files /dev/null and b/users/__pycache__/admin.cpython-36.pyc differ diff --git a/users/__pycache__/models.cpython-36.pyc b/users/__pycache__/models.cpython-36.pyc new file mode 100644 index 0000000..5644b04 Binary files /dev/null and b/users/__pycache__/models.cpython-36.pyc differ diff --git a/users/__pycache__/schema.cpython-36.pyc b/users/__pycache__/schema.cpython-36.pyc index 557282e..fc05df6 100644 Binary files a/users/__pycache__/schema.cpython-36.pyc and b/users/__pycache__/schema.cpython-36.pyc differ diff --git a/users/migrations/0001_initial.py b/users/migrations/0001_initial.py new file mode 100644 index 0000000..2a13751 --- /dev/null +++ b/users/migrations/0001_initial.py @@ -0,0 +1,24 @@ +# Generated by Django 3.1.5 on 2021-01-07 21:23 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Profile', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/users/migrations/__pycache__/0001_initial.cpython-36.pyc b/users/migrations/__pycache__/0001_initial.cpython-36.pyc new file mode 100644 index 0000000..4e3c3a8 Binary files /dev/null and b/users/migrations/__pycache__/0001_initial.cpython-36.pyc differ diff --git a/users/migrations/__pycache__/__init__.cpython-36.pyc b/users/migrations/__pycache__/__init__.cpython-36.pyc new file mode 100644 index 0000000..8e8997d Binary files /dev/null and b/users/migrations/__pycache__/__init__.cpython-36.pyc differ diff --git a/users/models.py b/users/models.py index 71a8362..f65540d 100644 --- a/users/models.py +++ b/users/models.py @@ -1,3 +1,13 @@ from django.db import models +from django.contrib.auth.models import User +from django.db.models.signals import post_save +from django.dispatch import receiver -# Create your models here. + +class Profile(models.Model): + user = models.OneToOneField(User, on_delete=models.CASCADE) + +@receiver(post_save, sender=User) +def create_profile(sender, instance, created, **kwargs): + if created: + Profile.objects.create(user=instance) \ No newline at end of file diff --git a/users/schema.py b/users/schema.py index d7dfaa5..e57530e 100644 --- a/users/schema.py +++ b/users/schema.py @@ -1,9 +1,51 @@ import graphene +import graphql_jwt + +import graphene_django + +from django.contrib.auth.models import User + +from .models import Profile + +class UserType(graphene_django.DjangoObjectType): + class Meta: + model = User + +class ProfileType(graphene_django.DjangoObjectType): + class Meta: + model = Profile + +class RegisterUserInput(graphene.InputObjectType): + username = graphene.String() + password = graphene.String() + +class RegisterUser(graphene.Mutation): + class Arguments: + input = RegisterUserInput(required=True) + user = graphene.Field(UserType) + + def mutate(self, info, input=None): + return RegisterUser(User.objects.create_user(username=input.username, password=input.password)) + +class Mutation(graphene.ObjectType): + token_auth = graphql_jwt.ObtainJSONWebToken.Field() + verify_token = graphql_jwt.Verify.Field() + refresh_token = graphql_jwt.Refresh.Field() + register_user = RegisterUser.Field() class Query(graphene.ObjectType): - hello = graphene.Field(graphene.String) + hello = graphene.Field(graphene.String, token=graphene.String(required=True)) + user_info = graphene.Field(UserType, token=graphene.String(required=True)) + user_profile = graphene.Field(ProfileType, token=graphene.String(required=True)) - def resolve_hello(self, info): + def resolve_hello(self, info, **kwargs): + print(info.context.user.id) return "hello" -schema = graphene.Schema(query=Query) \ No newline at end of file + def resolve_user_info(self, info, **kwargs): + return info.context.user + + def resolve_user_profile(self, info, **kwargs): + return info.context.user.profile + +schema = graphene.Schema(query=Query, mutation=Mutation) \ No newline at end of file