Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Open sidebar
MOOC packages by hacklab
django-courses
Commits
2c4f6761
Commit
2c4f6761
authored
Jun 05, 2020
by
Fernando Ribeiro
Browse files
Feat: Add Message Professor classes coming from django-courses-legacy to solve part-1 of #158
parent
68db30ef
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
188 additions
and
7 deletions
+188
-7
courses/permissions.py
courses/permissions.py
+23
-0
courses/serializers.py
courses/serializers.py
+70
-0
courses/urls.py
courses/urls.py
+13
-2
courses/views.py
courses/views.py
+82
-5
No files found.
courses/permissions.py
View file @
2c4f6761
...
...
@@ -39,3 +39,26 @@ class IsAdmin(permissions.BasePermission):
return
True
elif
request
.
user
and
request
.
user
.
is_superuser
:
return
True
class
IsAssistantOrCoordinatorOrReadOnly
(
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
else
:
return
obj
.
course
.
is_assistant_or_coordinator
(
request
.
user
)
class
IsAdminOrReadOnly
(
IsAdmin
):
"""
Custom permission to only allow not safe methods to admin.
"""
def
has_permission
(
self
,
request
,
view
):
# 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
return
super
(
IsAdminOrReadOnly
,
self
).
has_permission
(
request
,
view
)
courses/serializers.py
View file @
2c4f6761
...
...
@@ -5,11 +5,14 @@ from .videos.serializers import VideoSerializer
from
.models
import
(
Course
,
CourseProfessor
,
ProfessorMessage
,
ProfessorMessageRead
,
)
User
=
get_user_model
()
class
SimpleUserSerializer
(
serializers
.
ModelSerializer
):
class
Meta
:
...
...
@@ -107,3 +110,70 @@ class BasicCourseProfessorSerializer(serializers.ModelSerializer):
model
=
CourseProfessor
class
ProfessorMessageReadSerializer
(
serializers
.
ModelSerializer
):
class
Meta
:
model
=
ProfessorMessageRead
fields
=
(
'id'
,
'message'
,
'is_read'
)
class
ProfessorMessageSerializer
(
serializers
.
ModelSerializer
):
professor
=
SimpleUserSerializer
(
read_only
=
True
)
course_slug
=
serializers
.
SerializerMethodField
(
read_only
=
True
)
course_name
=
serializers
.
SerializerMethodField
(
read_only
=
True
)
is_read
=
serializers
.
SerializerMethodField
(
read_only
=
True
)
class
Meta
:
model
=
ProfessorMessage
fields
=
(
'id'
,
'course'
,
'course_name'
,
'course_slug'
,
'professor'
,
'users'
,
'subject'
,
'message'
,
'date'
,
'is_read'
)
def
get_course_slug
(
self
,
obj
):
try
:
return
obj
.
course
.
slug
except
AttributeError
as
e
:
return
''
# no course is associated with this message
def
get_course_name
(
self
,
obj
):
try
:
return
obj
.
course
.
name
except
AttributeError
as
e
:
return
''
# no course is associated with this message
def
get_is_read
(
self
,
obj
):
try
:
read_state
=
ProfessorMessageRead
.
objects
.
get
(
user
=
self
.
context
[
'request'
].
user
,
message
=
obj
)
return
read_state
.
is_read
except
ProfessorMessageRead
.
DoesNotExist
as
e
:
return
False
class
ProfessorGlobalMessageSerializer
(
ProfessorMessageSerializer
):
users
=
SimpleUserSerializer
(
read_only
=
True
,
required
=
False
,
many
=
True
)
def
create
(
self
,
validated_data
):
all_students
=
self
.
context
[
'request'
].
data
.
get
(
'all_students'
,
None
)
groups
=
self
.
context
[
'request'
].
data
.
get
(
'groups'
,
None
)
recipients
=
self
.
context
[
'request'
].
data
.
get
(
'users'
,
None
)
validated_data
[
'professor'
]
=
self
.
context
[
'request'
].
user
global_message
=
ProfessorMessage
(
**
validated_data
)
global_message
.
save
()
User
=
get_user_model
()
if
all_students
:
# If all_students was set to True by the client, this is a global message
global_message
.
users
.
add
(
*
[
user
for
user
in
User
.
objects
.
all
()])
elif
groups
:
# If groups were specified, their users are the recipients
global_message
.
users
.
add
(
*
[
user
for
user
in
User
.
objects
.
filter
(
groups__in
=
groups
)])
elif
recipients
:
# Otherwise, user the recipients list
for
user_id
in
self
.
context
[
'request'
].
data
[
'users'
]:
global_message
.
users
.
add
(
User
.
objects
.
get
(
id
=
user_id
))
global_message
.
send
()
return
global_message
courses/urls.py
View file @
2c4f6761
...
...
@@ -3,7 +3,12 @@ from django.views.generic import TemplateView
from
rest_framework
import
routers
from
.views
import
CourseViewSet
,
BaseCourseProfessorViewSet
from
.views
import
(
CourseViewSet
,
BaseCourseProfessorViewSet
,
ProfessorMessageViewSet
,
ProfessorMessageReadViewSet
,
ProfessorGlobalMessageViewSet
,
)
from
.course_material.views
import
CourseMaterialViewSet
,
CourseMaterialFileViewSet
from
.import_export.views
import
ExportCourseView
,
ImportCourseView
from
courses.workspaces.views
import
(
...
...
@@ -26,6 +31,7 @@ router.register(r'course', CourseViewSet, base_name='course')
router
.
register
(
r
'course_material'
,
CourseMaterialViewSet
,
base_name
=
'course_material'
)
router
.
register
(
r
'course_material_file'
,
CourseMaterialFileViewSet
,
base_name
=
'course_material_file'
)
# Workspaces
router
.
register
(
r
'workspaces'
,
WorkspaceViewSet
)
router
.
register
(
r
'group'
,
WorkspaceGroupViewSet
,
base_name
=
'group'
)
...
...
@@ -41,9 +47,14 @@ router.register(r'users-by-group', UsersByGroupViewSet, base_name='users-by-grou
router
.
register
(
r
'users-by-class'
,
UsersByClassViewSet
,
base_name
=
'users-by-class'
)
# router.register(r'course_carousel', views.CarouselCourseView, base_name='course_carousel')
#Professor
router
.
register
(
r
'course_professor_basic'
,
BaseCourseProfessorViewSet
,
base_name
=
'course_professor'
)
app_name
=
'courses'
router
.
register
(
r
'professor_message'
,
ProfessorMessageViewSet
,
base_name
=
'professor_message'
)
router
.
register
(
r
'professor_message_global'
,
ProfessorGlobalMessageViewSet
,
base_name
=
'professor_message_global'
)
router
.
register
(
r
'professor_message_read'
,
ProfessorMessageReadViewSet
,
base_name
=
'professor_message_read'
)
app_name
=
'courses'
urlpatterns
=
[
url
(
r
'^course/(?P<course_id>[1-9][0-9]*)/export/$'
,
ExportCourseView
.
as_view
(),
name
=
"course_export"
),
url
(
r
'^course/import/$'
,
ImportCourseView
.
as_view
(),
name
=
"course_import"
),
...
...
courses/views.py
View file @
2c4f6761
from
django.db.models
import
Q
from
rest_framework
import
viewsets
from
django.db
import
IntegrityError
from
rest_framework
import
viewsets
,
mixins
from
rest_framework.response
import
Response
from
rest_framework.permissions
import
IsAuthenticated
from
.models
import
(
Course
,
CourseProfessor
,
ProfessorMessage
,
ProfessorMessageRead
)
from
.serializers
import
(
CourseSerializer
,
BasicCourseProfessorSerializer
,
ProfessorMessageSerializer
,
ProfessorMessageReadSerializer
,
ProfessorGlobalMessageSerializer
,
)
from
.models
import
Course
,
CourseProfessor
from
.serializers
import
CourseSerializer
,
BasicCourseProfessorSerializer
from
.permissions
import
IsProfessorCoordinatorOrAdminPermissionOrReadOnly
from
.permissions
import
(
IsProfessorCoordinatorOrAdminPermissionOrReadOnly
,
IsAssistantOrCoordinatorOrReadOnly
,
IsAdminOrReadOnly
)
class
CourseViewSet
(
viewsets
.
ModelViewSet
):
...
...
@@ -20,7 +27,7 @@ class CourseViewSet(viewsets.ModelViewSet):
queryset
=
super
(
CourseViewSet
,
self
).
get_queryset
()
if
not
self
.
request
.
user
.
is_authenticated
:
return
queryset
.
filter
(
is_public
=
True
,
status
=
'published'
).
prefetch_related
(
'professors'
)
return
queryset
.
filter
(
is_public
=
True
,
status
=
'published'
).
prefetch_related
(
'professors'
)
if
not
self
.
request
.
user
.
is_superuser
:
role
=
self
.
request
.
query_params
.
get
(
'role'
,
None
)
...
...
@@ -80,3 +87,73 @@ class BaseCourseProfessorViewSet(viewsets.ModelViewSet):
permission_classes
=
(
IsProfessorCoordinatorOrAdminPermissionOrReadOnly
,
)
class
ProfessorMessageViewSet
(
viewsets
.
ModelViewSet
):
model
=
ProfessorMessage
lookup_field
=
'id'
filter_fields
=
(
'course'
,)
serializer_class
=
ProfessorMessageSerializer
permission_classes
=
(
IsAssistantOrCoordinatorOrReadOnly
,)
def
perform_create
(
self
,
serializer
):
obj
=
serializer
.
save
(
professor
=
self
.
request
.
user
)
if
obj
:
obj
.
send
()
def
get_queryset
(
self
):
queryset
=
ProfessorMessage
.
objects
.
filter
(
users__in
=
[
self
.
request
.
user
]).
order_by
(
'-id'
)
unread
=
self
.
request
.
query_params
.
get
(
'unread'
,
None
)
if
unread
:
# Exclude read messages
queryset
=
queryset
.
exclude
(
read_status__is_read
=
True
,
read_status__user
=
self
.
request
.
user
)
limit_to
=
self
.
request
.
query_params
.
get
(
'limit_to'
,
None
)
if
limit_to
:
queryset
=
queryset
[:
int
(
limit_to
)]
return
queryset
# This view creates ProfessorMessages targeting specific users and with no ties to any course
# Only site admins can create messages using this endpoint
class
ProfessorGlobalMessageViewSet
(
mixins
.
CreateModelMixin
,
mixins
.
ListModelMixin
,
viewsets
.
GenericViewSet
):
model
=
ProfessorMessage
serializer_class
=
ProfessorGlobalMessageSerializer
permission_classes
=
(
IsAdminOrReadOnly
,)
def
get_queryset
(
self
):
# Get all admin messages sent using this view
queryset
=
ProfessorMessage
.
objects
.
filter
(
course
=
None
).
order_by
(
'-id'
)
limit_to
=
self
.
request
.
query_params
.
get
(
'limit_to'
,
None
)
if
limit_to
:
queryset
=
queryset
[:
int
(
limit_to
)]
return
queryset
class
ProfessorMessageReadViewSet
(
viewsets
.
ModelViewSet
):
model
=
ProfessorMessageRead
lookup_field
=
'message'
serializer_class
=
ProfessorMessageReadSerializer
permission_classes
=
(
IsAuthenticated
,)
def
perform_create
(
self
,
serializer
):
try
:
read_info
=
serializer
.
save
(
user
=
self
.
request
.
user
,
is_read
=
True
)
except
IntegrityError
as
e
:
read_info
=
ProfessorMessageRead
.
objects
.
get
(
message
=
self
.
request
.
data
[
'message'
],
user
=
self
.
request
.
user
)
read_info
.
is_read
=
True
read_info
.
save
()
def
get_queryset
(
self
):
queryset
=
ProfessorMessageRead
.
objects
.
filter
(
user
=
self
.
request
.
user
).
order_by
(
'-id'
)
limit_to
=
self
.
request
.
query_params
.
get
(
'limit_to'
,
None
)
if
limit_to
:
queryset
=
queryset
[:
int
(
limit_to
)]
return
queryset
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment