Skip to content

Commit

Permalink
quick save
Browse files Browse the repository at this point in the history
  • Loading branch information
SKairinos committed Dec 7, 2023
1 parent 564e63d commit 84cee42
Show file tree
Hide file tree
Showing 13 changed files with 770 additions and 339 deletions.
17 changes: 17 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Pytest",
"type": "python",
"request": "test",
"justMyCode": false,
"presentation": {
"hidden": true
}
}
]
}
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
"--config",
"pyproject.toml"
],
"pylint.args": [
"--rcfile=pyproject.toml"
],
"python.testing.pytestArgs": [
"-c=pyproject.toml",
"."
Expand Down
4 changes: 4 additions & 0 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ django-extensions = "==3.2.1"
pyparsing = "==3.0.9"
pydot = "==1.4.2"
pytest-env = "==0.8.1"
mypy = "==1.6.1"
django-stubs = {version = "==4.2.6", extras = ["compatible-mypy"]}
djangorestframework-stubs = {version = "==3.14.4", extras = ["compatible-mypy"]}
pylint = "==3.0.2"

[requires]
python_version = "3.8"
747 changes: 502 additions & 245 deletions Pipfile.lock

Large diffs are not rendered by default.

18 changes: 12 additions & 6 deletions codeforlife/__init__.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
from pathlib import Path

import django_stubs_ext

from .version import __version__

# ------------------------------------------------------------------------------
# Package setup.
# ------------------------------------------------------------------------------

BASE_DIR = Path(__file__).resolve().parent
DATA_DIR = BASE_DIR.joinpath("data")

django_stubs_ext.monkeypatch()

from .version import __version__
# ------------------------------------------------------------------------------

from . import (
kurono,
service,
user,
)
# NOTE: These imports need to come after the package setup.
# pylint: disable=wrong-import-position
from . import kurono, service, user
44 changes: 35 additions & 9 deletions codeforlife/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,45 @@
from django.db import models
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from django_stubs_ext.db.models import TypedModelMeta

from .fields import *


class AbstractModel(models.Model):
"""Base model to be inherited by other models throughout the CFL system."""

class Manager(models.Manager):
"""Custom model manager to support CFL's system's operations."""
class QuerySet(models.QuerySet):
"""Custom queryset to support CFL's system's operations."""

def delete(self):
"""Schedules all objects in the queryset for deletion."""
model: "AbstractModel" # type: ignore[assignment]

# TODO: only schedule for deletion.
super().delete()
def update(self, **kwargs):
"""Updates all models in the queryset and notes when they were last
saved.
objects: Manager = Manager()
Args:
last_saved_at: When these models were last modified.
Returns:
The number of models updated.
"""

kwargs["last_saved_at"] = timezone.now()
return super().update(**kwargs)

def delete(self, wait: t.Optional[timedelta] = None):
"""Schedules all models in the queryset for deletion.
Args:
wait: How long to wait before these model are deleted. If not
set, the class-level default value is used.
"""

wait = wait or self.model.delete_wait
self.update(delete_after=timezone.now() + wait)

objects = models.Manager.from_queryset(QuerySet)()

# Type hints for Django's runtime-generated fields.
id: int
Expand Down Expand Up @@ -59,11 +81,15 @@ def delete(self):
),
)

class Meta:
# pylint: disable-next=missing-class-docstring
class Meta(TypedModelMeta):
abstract = True

# pylint: disable-next=arguments-differ
def delete(self, wait: t.Optional[timedelta] = None):
def delete( # type: ignore[override]
self,
wait: t.Optional[timedelta] = None,
):
"""Schedules the deletion of this model.
Args:
Expand Down
18 changes: 18 additions & 0 deletions codeforlife/user/fixtures/teachers.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[
{
"model": "user.Teacher",
"pk": 1,
"fields": {
"last_saved_at": "2023-01-01 00:00:00.0+00:00",
"is_admin": true
}
},
{
"model": "user.Teacher",
"pk": 2,
"fields": {
"last_saved_at": "2023-01-01 00:00:00.0+00:00",
"is_admin": true
}
}
]
26 changes: 26 additions & 0 deletions codeforlife/user/fixtures/users.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[
{
"model": "user.User",
"pk": 1,
"fields": {
"last_saved_at": "2023-01-01 00:00:00.0+00:00",
"first_name": "John",
"last_name": "Doe",
"username": "john.doe",
"email": "[email protected]",
"teacher": 1
}
},
{
"model": "user.User",
"pk": 2,
"fields": {
"last_saved_at": "2023-01-01 00:00:00.0+00:00",
"first_name": "Jane",
"last_name": "Doe",
"username": "jane.doe",
"email": "[email protected]",
"teacher": 2
}
}
]
80 changes: 40 additions & 40 deletions codeforlife/user/models/class_student_join_request.py
Original file line number Diff line number Diff line change
@@ -1,40 +1,40 @@
"""
© Ocado Group
Created on 05/12/2023 at 17:46:22(+00:00).
Class student join request model.
"""

from django.db import models

from ...models import AbstractModel
from . import klass as _class
from . import student as _student


# TODO: move to portal
class ClassStudentJoinRequest(AbstractModel):
"""A request from a student to join a class."""

klass: "_class.Class" = models.ForeignKey(
"user.Class",
related_name="student_join_requests",
on_delete=models.CASCADE,
)

student: "_student.Student" = models.ForeignKey(
"user.Student",
related_name="class_join_requests",
on_delete=models.CASCADE,
)

# created_at = models.DateTimeField(
# _("created at"),
# auto_now_add=True,
# help_text=_("When the teacher was invited to the school."),
# )

class Meta:
unique_together = ["klass", "student"]
# TODO: check student is independent
# assert class is receiving requests
# """
# © Ocado Group
# Created on 05/12/2023 at 17:46:22(+00:00).

# Class student join request model.
# """

# from django.db import models

# from ...models import AbstractModel
# from . import klass as _class
# from . import student as _student


# # TODO: move to portal
# class ClassStudentJoinRequest(AbstractModel):
# """A request from a student to join a class."""

# klass: "_class.Class" = models.ForeignKey(
# "user.Class",
# related_name="student_join_requests",
# on_delete=models.CASCADE,
# )

# student: "_student.Student" = models.ForeignKey(
# "user.Student",
# related_name="class_join_requests",
# on_delete=models.CASCADE,
# )

# # created_at = models.DateTimeField(
# # _("created at"),
# # auto_now_add=True,
# # help_text=_("When the teacher was invited to the school."),
# # )

# class Meta:
# unique_together = ["klass", "student"]
# # TODO: check student is independent
# # assert class is receiving requests
37 changes: 20 additions & 17 deletions codeforlife/user/models/teacher.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,18 @@
from django.utils.translation import gettext_lazy as _

from ...models import AbstractModel
from . import klass as _class
from . import school as _school
from . import school_teacher_invitation as _school_teacher_invitation

# from . import klass as _class
# from . import school as _school
# from . import school_teacher_invitation as _school_teacher_invitation
from . import user as _user


class Teacher(AbstractModel):
"""A user's teacher profile."""

# pylint: disable-next=missing-class-docstring
class Manager(AbstractModel.Manager):
class Manager(models.Manager["Teacher"]):
def create_user(self, teacher: t.Dict[str, t.Any], **fields):
"""Create a user with a teacher profile.
Expand All @@ -38,21 +39,23 @@ def create_user(self, teacher: t.Dict[str, t.Any], **fields):
teacher=self.create(**teacher),
)

objects: Manager = Manager()
objects: Manager = Manager.from_queryset( # type: ignore[misc]
AbstractModel.QuerySet
)() # type: ignore[assignment]

user: "_user.User"
classes: QuerySet["_class.Class"]
school_invitations: QuerySet[
"_school_teacher_invitation.SchoolTeacherInvitation"
]

school: "_school.School" = models.ForeignKey(
"user.School",
related_name="teachers",
null=True,
editable=False,
on_delete=models.SET_NULL,
)
# classes: QuerySet["_class.Class"]
# school_invitations: QuerySet[
# "_school_teacher_invitation.SchoolTeacherInvitation"
# ]

# school: "_school.School" = models.ForeignKey(
# "user.School",
# related_name="teachers",
# null=True,
# editable=False,
# on_delete=models.SET_NULL,
# )

is_admin = models.BooleanField(
_("is administrator"),
Expand Down
Loading

0 comments on commit 84cee42

Please sign in to comment.