Skip to content
Snippets Groups Projects
Verified Commit f5907470 authored by Jan Maximilian Michal's avatar Jan Maximilian Michal
Browse files

Added some type annotations.

parent e7d1a09e
Branches
Tags
1 merge request!16Backend tests
Pipeline #
......@@ -7,6 +7,7 @@ __pycache__
MANIFEST
.coverage
cache/
.mypy_cache/
# Django specific
dist/
......
......@@ -2,6 +2,8 @@
# Generated by Django 1.11.7 on 2017-11-04 19:10
from __future__ import unicode_literals
from typing import List, Text
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
......@@ -13,8 +15,7 @@ class Migration(migrations.Migration):
initial = True
dependencies = [
]
dependencies: List[Text] = []
operations = [
migrations.CreateModel(
......
......@@ -6,6 +6,8 @@ See docstring of the individual models for information on the setup of the
database.
'''
from typing import Union, Dict
from collections import OrderedDict
from random import randrange, sample
from string import ascii_lowercase
......@@ -15,7 +17,7 @@ from django.contrib.auth.models import AbstractUser
from django.db import models
from django.db.models import Value as V
from django.db.models import (BooleanField, Case, Count, F, IntegerField, Q,
Sum, When)
QuerySet, Sum, When)
from django.db.models.functions import Coalesce
......@@ -28,7 +30,7 @@ def random_matrikel_no() -> str:
return str(10_000_000 + randrange(90_000_000))
def get_annotated_tutor_list():
def get_annotated_tutor_list() -> QuerySet:
"""All tutor accounts are annotate with a field that includes the number of
feedback that tutor has collaborated in.
......@@ -105,7 +107,7 @@ class SubmissionType(models.Model):
verbose_name_plural = "SubmissionType Set"
@classmethod
def get_annotated_feedback_count(cls):
def get_annotated_feedback_count(cls) -> QuerySet:
""" Annotates submission lists with counts
The following fields are annotated:
......@@ -146,7 +148,7 @@ class UserAccount(AbstractUser):
fullname = models.CharField('full name', max_length=70, blank=True)
is_admin = models.BooleanField(default=False)
def get_associated_user(self):
def get_associated_user(self) -> models.Model:
""" Returns the user type that is associated with this user obj """
return \
(hasattr(self, 'student') and self.student) or \
......@@ -162,6 +164,7 @@ class Tutor(models.Model):
def get_feedback_count(self) -> int:
return self.feedback_list.count()
class Reviewer(models.Model):
user = models.OneToOneField(
get_user_model(), unique=True,
......@@ -197,7 +200,7 @@ class Student(models.Model):
get_user_model(), unique=True,
on_delete=models.CASCADE, related_name='student')
def score_per_submission(self):
def score_per_submission(self) -> Dict[str, int]:
""" TODO: get rid of it and use an annotation.
Returns:
......@@ -214,7 +217,7 @@ class Student(models.Model):
})
@classmethod
def get_overall_score_annotated_submission_list(cls):
def get_overall_score_annotated_submission_list(cls) -> QuerySet:
"""Can be used to quickly annotate a user with the necessary information
on the overall score of a student and if he does not need any more
correction.
......@@ -331,7 +334,7 @@ class Submission(models.Model):
)
@classmethod
def assign_tutor(cls, tutor, slug=None) -> bool:
def assign_tutor(cls, tutor: Tutor, slug: str=None) -> bool:
"""Assigns a tutor to a submission
A submission is not assigned to the specified tutor in the case
......@@ -493,14 +496,14 @@ class Feedback(models.Model):
def __str__(self) -> str:
return 'Feedback for {}'.format(self.of_submission)
def is_full_score(self):
def is_full_score(self) -> bool:
return self.of_submission.type.full_score == self.score
def get_full_score(self):
def get_full_score(self) -> int:
return self.of_submission.type.full_score
@classmethod
def get_open_feedback(cls, user):
def get_open_feedback(cls, user: Union[Tutor, Reviewer]) -> QuerySet:
"""For a user, returns the feedback that is up for reassignment that
does not belong to the user.
......@@ -523,7 +526,7 @@ class Feedback(models.Model):
)
@classmethod
def tutor_unfinished_feedback(cls, user):
def tutor_unfinished_feedback(cls, user: Union[Tutor, Reviewer]):
"""Gets only the feedback that is assigned and not accepted. A tutor
should have only one feedback assigned that is not accepted
......@@ -541,7 +544,7 @@ class Feedback(models.Model):
)
return tutor_feedback[0] if tutor_feedback else None
def tutor_assigned_feedback(cls, user):
def tutor_assigned_feedback(cls, user: Union[Tutor, Reviewer]):
"""Gets all feedback that is assigned to the tutor including
all status cases.
......@@ -557,7 +560,7 @@ class Feedback(models.Model):
tutor_feedback = cls.objects.filter(of_tutor=user)
return tutor_feedback
def finalize_feedback(self, user):
def finalize_feedback(self, user: Union[Tutor, Reviewer]):
"""Used to mark feedback as accepted (reviewed).
Parameters
......@@ -569,17 +572,7 @@ class Feedback(models.Model):
self.of_reviewer = user
self.save()
def unfinalize_feedback(self):
"""Used to mark feedback as accepted (reviewed)
This makes it uneditable by the tutor.
"""
self.origin = Feedback.MANUAL
self.of_reviewer = None
self.save()
def reassign_to_tutor(self, user):
def reassign_to_tutor(self, user: Union[Tutor, Reviewer]):
"""When a tutor does not want to correct some task they can pass it
along to another tutor who will accept the request.
......
from rest_framework import permissions
from core.models import Reviewer, Student, Tutor
from django.http import HttpRequest
from django.views import View
class IsUserGenericPermission(permissions.BasePermission):
""" Generic class that encapsulates how to identify someone
as a member of a user Group """
def has_permission(self, request, view):
def has_permission(self, request: HttpRequest, view: View) -> bool:
""" required by BasePermission. Check if user is instance of model"""
assert self.model is not None, (
"'%s' has to include a `model` attribute"
......
......@@ -51,7 +51,7 @@ class TutorSerializer(serializers.ModelSerializer):
feedback_count = serializers.IntegerField(source='get_feedback_count',
read_only=True)
def create(self, validated_data):
def create(self, validated_data) -> Tutor:
log.info("Crating tutor from data %s", validated_data)
return user_factory.make_tutor(
username=validated_data['user']['username'])
......
......@@ -5,7 +5,7 @@ import logging
from rest_framework import generics
from core.models import ExamType, Tutor
from core.models import ExamType, Tutor, Student
from core.permissions import IsReviewer, IsStudent
from core.serializers import ExamSerializer, StudentSerializer, TutorSerializer
......@@ -17,7 +17,7 @@ class StudentApiView(generics.RetrieveAPIView):
permission_classes = (IsStudent,)
serializer_class = StudentSerializer
def get_object(self):
def get_object(self) -> Student:
""" The object in question is the student associated with the requests
user. Since the permission IsStudent is satisfied the member exists """
return self.request.user.student
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment