Add recently visited modules to user

This commit is contained in:
Ramon Wenger 2020-06-25 15:11:17 +02:00
parent 991efbe613
commit e899bbe21b
7 changed files with 89 additions and 28 deletions

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,26 @@
# Generated by Django 2.2.12 on 2020-06-23 09:52
import datetime
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('books', '0021_auto_20200520_0954'),
]
operations = [
migrations.CreateModel(
name='RecentModule',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('visited', models.DateTimeField(default=datetime.datetime.now)),
('module', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='books.Module')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]

View File

@ -1,4 +1,5 @@
import logging
from datetime import datetime
from django.db import models
from wagtail.admin.edit_handlers import FieldPanel, TabbedInterface, ObjectList
@ -58,3 +59,12 @@ class Module(StrictHierarchyPage):
def get_child_ids(self):
return self.get_children().values_list('id', flat=True)
class RecentModule(models.Model):
module = models.ForeignKey(Module, on_delete=models.CASCADE, related_name='recent_modules')
user = models.ForeignKey('users.User', on_delete=models.CASCADE)
visited = models.DateTimeField(default=datetime.now)
class Meta:
get_latest_by = 'visited'

View File

@ -1,8 +1,10 @@
from datetime import datetime
import graphene
from graphene import relay
from api.utils import get_errors, get_object
from books.models import Module, Topic
from books.models import Module, Topic, RecentModule
from books.schema.queries import ModuleNode, TopicNode
@ -47,30 +49,30 @@ class UpdateLastModule(relay.ClientIDMutation):
# todo: use slug here too
id = graphene.ID()
module = graphene.Field(ModuleNode)
errors = graphene.List(graphene.String)
last_module = graphene.Field(ModuleNode)
@classmethod
def mutate_and_get_payload(cls, root, info, **args):
user = info.context.user
id = args.get('id')
module = get_object(Module, id)
if not module:
raise Module.DoesNotExist
try:
user = info.context.user
id = args.get('id')
same_module = RecentModule.objects.get(user=user, module=module)
same_module.visited = datetime.now()
same_module.save()
return cls(last_module=same_module.module)
except RecentModule.DoesNotExist:
recent_modules = RecentModule.objects.filter(user=user)
while recent_modules.all().count() >= 3:
recent_modules.earliest().delete()
module = get_object(Module, id)
if not module:
raise Module.DoesNotExist
last_module = RecentModule.objects.create(user=user, module=module)
user.last_module = module
user.save()
return cls(module=module)
except Module.DoesNotExist:
return cls(errors=['Module not found'])
except Exception as e:
errors = ['Error: {}'.format(e)]
return cls(errors=errors)
return cls(last_module=last_module.module)
class UpdateLastTopic(relay.ClientIDMutation):
@ -93,4 +95,3 @@ class UpdateLastTopic(relay.ClientIDMutation):
user.save()
return cls(topic=topic)

View File

@ -13,7 +13,7 @@ from notes.schema import ContentBlockBookmarkNode, ChapterBookmarkNode, ModuleBo
from rooms.models import ModuleRoomSlug
from surveys.models import Answer
from surveys.schema import AnswerNode
from ..models import Book, Topic, Module, Chapter, ContentBlock
from ..models import Book, Topic, Module, Chapter, ContentBlock, RecentModule
def process_module_room_slug_block(content):
@ -187,6 +187,12 @@ class ModuleNode(DjangoObjectType):
.prefetch_related('objectives__objective_progress')
class RecentModuleNode(DjangoObjectType):
class Meta:
model = RecentModule
interfaces = (relay.Node,)
class TopicNode(DjangoObjectType):
pk = graphene.Int()
modules = DjangoFilterConnectionField(ModuleNode)

View File

@ -17,6 +17,7 @@ DEFAULT_SCHOOL_ID = 1
class User(AbstractUser):
last_module = models.ForeignKey('books.Module', related_name='+', on_delete=models.SET_NULL, null=True)
# recent_modules = models.ManyToManyField('books.Module', related_name='+', through='books.RecentModule')
last_topic = models.ForeignKey('books.Topic', related_name='+', on_delete=models.SET_NULL, null=True)
avatar_url = models.CharField(max_length=254, blank=True, default='')
email = models.EmailField(_('email address'), unique=True)
@ -97,7 +98,6 @@ class User(AbstractUser):
user_settings.selected_class = school_class
user_settings.save()
@property
def full_name(self):
return self.get_full_name()
@ -245,7 +245,7 @@ class UserData(models.Model):
class License(models.Model):
for_role = models.ForeignKey(Role, blank=False, null=True, on_delete=models.CASCADE)
licensee = models.ForeignKey(User, blank=False, null=True, on_delete=models.CASCADE)
expire_date = models.DateField(blank=False, null=True,)
expire_date = models.DateField(blank=False, null=True, )
order_id = models.IntegerField(blank=False, null=False, default=-1)
raw = models.TextField(default='')
@ -255,8 +255,9 @@ class License(models.Model):
return self.for_role.key == RoleManager.TEACHER_KEY
def is_valid(self):
return HepClient.is_product_active(datetime(self.expire_date.year, self.expire_date.month, self.expire_date.day),
self.for_role.key)
return HepClient.is_product_active(
datetime(self.expire_date.year, self.expire_date.month, self.expire_date.day),
self.for_role.key)
def __str__(self):
return f'License for role: {self.for_role}'
@ -266,4 +267,3 @@ class SchoolClassMember(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
school_class = models.ForeignKey(SchoolClass, on_delete=models.CASCADE)
active = models.BooleanField(default=True)

View File

@ -2,6 +2,7 @@ from datetime import datetime
import graphene
from django.db.models import Q
from django_filters import FilterSet, OrderingFilter
from graphene import relay, ObjectType
from graphene_django import DjangoObjectType
from graphene_django.filter import DjangoFilterConnectionField
@ -10,7 +11,7 @@ from graphql_relay import to_global_id
from basicknowledge.models import BasicKnowledge
from basicknowledge.queries import InstrumentNode
from books.models import Module
from books.models import Module, RecentModule
from books.schema.queries import ModuleNode
from users.models import User, SchoolClass, SchoolClassMember
@ -39,6 +40,18 @@ class SchoolClassNode(DjangoObjectType):
return self.code
class RecentModuleFilter(FilterSet):
class Meta:
model = Module
fields = ('recent_modules',)
order_by = OrderingFilter(
fields=(
('recent_modules__visited', 'visited'),
)
)
class UserNode(DjangoObjectType):
pk = graphene.Int()
permissions = graphene.List(graphene.String)
@ -46,6 +59,7 @@ class UserNode(DjangoObjectType):
expiry_date = graphene.String()
is_teacher = graphene.Boolean()
old_classes = DjangoFilterConnectionField(SchoolClassNode)
recent_modules = DjangoFilterConnectionField(ModuleNode, filterset_class=RecentModuleFilter)
class Meta:
model = User
@ -82,6 +96,10 @@ class UserNode(DjangoObjectType):
def resolve_old_classes(self, info):
return SchoolClass.objects.filter(schoolclassmember__active=False, schoolclassmember__user=self)
def resolve_recent_modules(self, info, **kwargs):
# see https://docs.graphene-python.org/projects/django/en/latest/filtering/
return RecentModuleFilter(kwargs).qs.filter(recent_modules__user=self)
class ClassMemberNode(ObjectType):
"""