Commit 9d636b5b authored by Bruno Martin's avatar Bruno Martin
Browse files

create classroom app

parent e506169c
......@@ -14,6 +14,8 @@ from .course_material.models import CourseMaterial, File
from .workspaces.models import Workspace
from .classroom.models import Classroom, Event
class LessonInline(admin.TabularInline):
model = Lesson
......@@ -123,3 +125,18 @@ class ProfessorMessageAdmin(admin.ModelAdmin):
@admin.register(CourseAuthor)
class CourseAuthorAdmin(admin.ModelAdmin):
pass
class EventInline(admin.TabularInline):
model = Event
@admin.register(Classroom)
class ClassroomAdmin(admin.ModelAdmin):
filter_horizontal = (
'assistants',
'coordinators',
'access_groups',
)
autocomplete_fields = (
'forum',
'group',
)
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.models import Group
from django.conf import settings
from django.urls import reverse
from discussion.models import Forum
class Classroom(models.Model):
name = models.CharField(
max_length=255,
)
description = models.TextField(
_('Pronatec'),
blank=True,
)
image = models.ImageField(
_('Image'),
# upload_to=hash_name('course_thumbnails', 'name'),
null=True,
blank=True,
)
assistants = models.ManyToManyField(
settings.AUTH_USER_MODEL,
verbose_name=_('Assistants'),
related_name='professor_classrooms',
blank=True,
)
coordinators = models.ManyToManyField(
settings.AUTH_USER_MODEL,
verbose_name=_('Coordinators'),
related_name='coordinator_classrooms',
blank=True,
)
forum = models.ForeignKey(
Forum,
on_delete=models.SET_NULL,
related_name='classrooms',
blank=True,
null=True,
)
courses = models.ManyToManyField(
'Course',
verbose_name=_('Course'),
blank=True,
)
access_groups = models.ManyToManyField(
Group,
verbose_name=_('Grupos cursistas'),
related_name='classrooms_access',
blank=True,
)
group = models.ForeignKey(
Group,
verbose_name=_('Group'),
on_delete=models.SET_NULL,
related_name='classrooms',
blank=True,
null=True
)
def __str__(self):
return '{} @ {}'.format(self.name, self.course)
class Event(models.Model):
title = models.CharField(
_('Title'),
max_length=255,
)
text = models.CharField(
_('text'),
max_length=512,
blank=True,
)
date_time = models.DateTimeField(
_('Start date'),
default=None,
blank=True,
null=True,
)
classroom = models.ForeignKey(
Classroom,
verbose_name=_('Classroom'),
on_delete=models.CASCADE,
null=True
)
from rest_framework import permissions
class IsClassroomAssistantOrCoordinatorOrReadOnly(permissions.BasePermission):
"""
Check if a user can send messages to students enrolled in a course
"""
def has_object_permission(self, request, view, obj):
# Read permissions are allowed to any request,
# so we'll always allow GET, HEAD or OPTIONS requests.
if request.method in permissions.SAFE_METHODS:
return True
elif request.user and request.user.is_superuser:
return True
elif request.user and (request.user in obj.assistants or request.user in obj.coordinators):
return True
from rest_framework import serializers
from baquara.users.serializers import SimpleUserSerializer
from courses.serializers import BasicCourseSerializer
from .models import Classroom, Event
class EventSerializer(serializers.ModelSerializer):
class Meta:
model = Event
fields = '__all__'
class BasicClassroomSerializer(serializers.ModelSerializer):
assistants = SimpleUserSerializer(read_only=True, many=True)
coordinators = SimpleUserSerializer(read_only=True, many=True)
class Meta:
model = Classroom
fields = (
'name',
'description',
'image',
'assistants',
'coordinators',
)
class ClassroomSerializer(serializers.ModelSerializer):
assistants = SimpleUserSerializer(read_only=True, many=True)
coordinators = SimpleUserSerializer(read_only=True, many=True)
events = EventSerializer(read_only=True, many=True)
courses = BasicCourseSerializer(read_only=True)
# turma_iat = TurmaiatSerializer(read_only=True)
class Meta:
model = Classroom
fields = (
'name',
'description',
'image',
'assistants',
'coordinators',
'courses',
'access_groups',
'group',
'events',
'turma_iat',
)
depth = 1
from rest_framework import viewsets, mixins, status
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from django.db.models import Q
from courses.models import Course
from .models import Classroom
from .serializers import (
BasicClassroomSerializer,
ClassroomSerializer,
)
from .permissions import IsClassroomAssistantOrCoordinatorOrReadOnly
class BasicClassroomViewSet(viewsets.ReadOnlyModelViewSet):
queryset = Classroom.objects.all()
serializer_class = BasicClassroomSerializer
# filter_fields = ['course']
permission_classes = [IsAuthenticated]
def get_queryset(self):
queryset = super().get_queryset()
if not self.request.user.is_superuser:
queryset = queryset.filter(
Q(groups__in=self.request.user.groups.all())
| Q(assistants=self.request.user)
| Q(coordinators=self.request.user)
)
queryset = queryset.prefetch_related(
'assistants',
'coordinators',
'courses',
'access_groups',
)
return queryset
class ClassroomViewSet(BasicClassroomViewSet, viewsets.ModelViewSet):
queryset = Classroom.objects.all()
serializer_class = ClassroomSerializer
permission_classes = [
IsClassroomAssistantOrCoordinatorOrReadOnly,
IsAuthenticated,
]
def get_queryset(self):
queryset = super().get_queryset()
return queryset
\ No newline at end of file
# Generated by Django 2.2.14 on 2020-07-25 01:46
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('discussion', '0023_merge_20200624_0343'),
('auth', '0011_update_proxy_permissions'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('courses', '0009_auto_20200609_1453'),
]
operations = [
migrations.CreateModel(
name='Classroom',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255)),
('description', models.TextField(blank=True, verbose_name='Pronatec')),
('image', models.ImageField(blank=True, null=True, upload_to='', verbose_name='Image')),
('access_groups', models.ManyToManyField(blank=True, related_name='classrooms_access', to='auth.Group', verbose_name='Grupos cursistas')),
('assistants', models.ManyToManyField(blank=True, related_name='professor_classrooms', to=settings.AUTH_USER_MODEL, verbose_name='Assistants')),
('coordinators', models.ManyToManyField(blank=True, related_name='coordinator_classrooms', to=settings.AUTH_USER_MODEL, verbose_name='Coordinators')),
('courses', models.ManyToManyField(blank=True, to='courses.Course', verbose_name='Course')),
('forum', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='classrooms', to='discussion.Forum')),
('group', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='classrooms', to='auth.Group', verbose_name='Group')),
],
),
migrations.CreateModel(
name='Event',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=255, verbose_name='Title')),
('text', models.CharField(blank=True, max_length=512, verbose_name='text')),
('date_time', models.DateTimeField(blank=True, default=None, null=True, verbose_name='Start date')),
('classroom', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='courses.Classroom', verbose_name='Classroom')),
],
),
]
......@@ -20,6 +20,7 @@ from .videos.models import Video
from .notes.models import Note
from .course_material.models import CourseMaterial
from .classes.models import Class
from .classroom.models import Classroom, Event
import re
......
......@@ -25,6 +25,11 @@ from courses.reports.views import (
UsersByGroupViewSet,
UsersByClassViewSet,
)
from courses.classroom.views import (
BasicClassroomViewSet,
ClassroomViewSet,
)
router = routers.DefaultRouter()
router.register(r'course', CourseViewSet, base_name='course')
......@@ -54,6 +59,10 @@ router.register(r'professor_message', ProfessorMessageViewSet, base_name='profes
router.register(r'professor_message_global', ProfessorGlobalMessageViewSet, base_name='professor_message_global')
router.register(r'professor_message_read', ProfessorMessageReadViewSet, base_name='professor_message_read')
# Classroom
router.register(r'classrooms', BasicClassroomViewSet, base_name='classrooms')
router.register(r'classroom', ClassroomViewSet, base_name='classroom')
app_name = 'courses'
urlpatterns = [
url(r'^course/(?P<course_id>[1-9][0-9]*)/export/$', ExportCourseView.as_view(), name="course_export"),
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment