Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
31a5bc25
Commit
31a5bc25
authored
Oct 07, 2014
by
Xavier Antoviaque
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #258 from aboudreault/cohorts-rebase
Cohorts rebase
parents
6abc5a05
f75f5534
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
247 additions
and
29 deletions
+247
-29
common/djangoapps/course_groups/cohorts.py
+30
-0
common/djangoapps/course_groups/management/__init__.py
+0
-0
common/djangoapps/course_groups/management/commands/__init__.py
+0
-0
common/djangoapps/course_groups/management/commands/revert_workgroup.py
+111
-0
common/djangoapps/course_groups/models.py
+2
-0
common/djangoapps/course_groups/views.py
+1
-1
lms/djangoapps/api_manager/users/views.py
+15
-0
lms/djangoapps/projects/migrations/0008_auto__add_workgroupusers.py
+0
-0
lms/djangoapps/projects/models.py
+32
-1
lms/djangoapps/projects/tests/test_peer_reviews.py
+1
-1
lms/djangoapps/projects/tests/test_projects.py
+1
-1
lms/djangoapps/projects/tests/test_submission_reviews.py
+1
-1
lms/djangoapps/projects/tests/test_workgroup_reviews.py
+1
-1
lms/djangoapps/projects/tests/test_workgroup_submissions.py
+1
-1
lms/djangoapps/projects/tests/test_workgroups.py
+12
-12
lms/djangoapps/projects/views.py
+39
-10
No files found.
common/djangoapps/course_groups/cohorts.py
View file @
31a5bc25
...
@@ -291,6 +291,36 @@ def is_user_in_cohort(cohort, user_id, group_type=CourseUserGroup.COHORT):
...
@@ -291,6 +291,36 @@ def is_user_in_cohort(cohort, user_id, group_type=CourseUserGroup.COHORT):
group_type
=
group_type
)
.
exists
()
group_type
=
group_type
)
.
exists
()
def
remove_user_from_cohort
(
cohort
,
username_or_email
):
"""
Look up the given user, and if successful, remove them to the specified cohort.
Arguments:
cohort: CourseUserGroup
username_or_email: string. Treated as email if has '@'
Returns:
User object that has been removed from the cohort
Raises:
User.DoesNotExist if can't find user.
ValueError if user is not in this cohort.
"""
user
=
get_user_by_username_or_email
(
username_or_email
)
course_cohorts
=
CourseUserGroup
.
objects
.
filter
(
course_id
=
cohort
.
course_id
,
users__id
=
user
.
id
,
group_type
=
CourseUserGroup
.
COHORT
,
)
if
course_cohorts
.
exists
():
cohort
.
users
.
remove
(
user
)
return
user
def
get_course_cohort_names
(
course_key
):
def
get_course_cohort_names
(
course_key
):
"""
"""
Return a list of the cohort names in a course.
Return a list of the cohort names in a course.
...
...
common/djangoapps/course_groups/management/__init__.py
0 → 100644
View file @
31a5bc25
common/djangoapps/course_groups/management/commands/__init__.py
0 → 100644
View file @
31a5bc25
common/djangoapps/course_groups/management/commands/revert_workgroup.py
0 → 100644
View file @
31a5bc25
from
django.core.management.base
import
BaseCommand
,
CommandError
from
django.core.exceptions
import
MultipleObjectsReturned
from
optparse
import
make_option
from
django.contrib.auth.models
import
User
from
xmodule.modulestore.django
import
modulestore
from
xmodule.course_module
import
CourseDescriptor
from
course_groups.models
import
CourseUserGroup
from
course_groups.cohorts
import
(
get_cohort
,
get_cohort_by_name
,
add_cohort
,
add_user_to_cohort
,
remove_user_from_cohort
)
from
student.models
import
CourseEnrollment
class
Command
(
BaseCommand
):
option_list
=
BaseCommand
.
option_list
+
(
make_option
(
'--fix'
,
action
=
'store_true'
,
dest
=
'fix'
,
default
=
False
,
help
=
'Apply possible fixes automatically'
),
)
help
=
'Revert the multiple cohorts feature.'
def
handle
(
self
,
*
args
,
**
options
):
self
.
stdout
.
write
(
'### Checking CourseUserGroup group types
\n
'
)
error
=
False
for
course_group
in
CourseUserGroup
.
objects
.
all
():
if
course_group
.
group_type
!=
CourseUserGroup
.
COHORT
:
if
options
[
'fix'
]:
self
.
stdout
.
write
(
'Fixed: CourseUserGroup with an invalid group_type found: {} (type: {})
\n
'
.
format
(
course_group
.
name
,
course_group
.
group_type
)
)
course_group
.
group_type
=
CourseUserGroup
.
COHORT
course_group
.
save
()
else
:
error
=
True
self
.
stdout
.
write
(
'CourseUserGroup with an invalid group_type found: {} (type: {})
\n
'
.
format
(
course_group
.
name
,
course_group
.
group_type
)
)
if
not
error
:
self
.
stdout
.
write
(
'Ok.
\n
'
)
self
.
stdout
.
write
(
'
\n
### Checking user cohorts
\n
'
)
error
=
False
users
=
User
.
objects
.
all
()
_courses
=
modulestore
()
.
get_courses
()
courses
=
[
c
for
c
in
_courses
if
isinstance
(
c
,
CourseDescriptor
)]
# for each course, check if users are in atleast and only 1 cohort
for
course
in
courses
:
for
user
in
users
:
if
not
CourseEnrollment
.
is_enrolled
(
user
,
course
.
id
):
continue
try
:
CourseUserGroup
.
objects
.
get
(
course_id
=
course
.
id
,
users__id
=
user
.
id
)
except
CourseUserGroup
.
DoesNotExist
:
if
options
[
'fix'
]:
# create a "default_cohort" is it doesn't already exist
try
:
default_cohort
=
get_cohort_by_name
(
course
.
id
,
CourseUserGroup
.
default_cohort_name
)
except
CourseUserGroup
.
DoesNotExist
:
default_cohort
=
add_cohort
(
course
.
id
,
CourseUserGroup
.
default_cohort_name
)
self
.
stdout
.
write
(
'Default cohort "{}" created for course "{}"'
.
format
(
default_cohort
.
name
,
course
.
display_name
)
)
add_user_to_cohort
(
default_cohort
,
user
.
username
)
self
.
stdout
.
write
(
'Fixed: User "{}" is not in a cohort in course "{}". Added in "{}" cohort
\n
'
.
format
(
user
.
username
,
course
.
display_name
,
default_cohort
.
name
)
)
else
:
error
=
True
self
.
stdout
.
write
(
'User "{}" is not in a cohort in course "{}".
\n
'
.
format
(
user
.
username
,
course
.
display_name
)
)
except
MultipleObjectsReturned
:
self
.
stdout
.
write
(
'User "{}" is in multiple cohorts in course "{}".
\n
'
.
format
(
user
.
username
,
course
.
display_name
)
)
if
options
[
'fix'
]:
user_cohorts
=
CourseUserGroup
.
objects
.
filter
(
course_id
=
course
.
id
,
users__id
=
user
.
id
)
.
all
()
user_cohort
=
user_cohorts
[
0
]
for
cohort
in
user_cohorts
[
1
:]:
remove_user_from_cohort
(
cohort
,
user
.
username
)
self
.
stdout
.
write
(
"User '{}' has been removed from cohort '{}' in course '{}'.
\n
"
.
format
(
user
.
username
,
cohort
.
name
,
course
.
display_name
)
)
self
.
stdout
.
write
(
"User '{}' is now only in cohort '{}' in course '{}'.
\n
"
.
format
(
user
.
username
,
cohort
.
name
,
course
.
display_name
)
)
else
:
error
=
True
if
not
error
:
self
.
stdout
.
write
(
'Ok.
\n
'
)
self
.
stdout
.
write
(
'
\n
To fix issues, run the script with the "--fix" option.
\n
'
)
common/djangoapps/course_groups/models.py
View file @
31a5bc25
...
@@ -13,6 +13,8 @@ class CourseUserGroup(models.Model):
...
@@ -13,6 +13,8 @@ class CourseUserGroup(models.Model):
which may be treated specially. For example, a user can be in at most one cohort per
which may be treated specially. For example, a user can be in at most one cohort per
course, and cohorts are used to split up the forums by group.
course, and cohorts are used to split up the forums by group.
"""
"""
default_cohort_name
=
"default_cohort"
class
Meta
:
class
Meta
:
unique_together
=
((
'name'
,
'course_id'
),
)
unique_together
=
((
'name'
,
'course_id'
),
)
...
...
common/djangoapps/course_groups/views.py
View file @
31a5bc25
...
@@ -228,7 +228,7 @@ def remove_user_from_cohort(request, course_key_string, cohort_id):
...
@@ -228,7 +228,7 @@ def remove_user_from_cohort(request, course_key_string, cohort_id):
cohort
=
cohorts
.
get_cohort_by_id
(
course_key
,
cohort_id
)
cohort
=
cohorts
.
get_cohort_by_id
(
course_key
,
cohort_id
)
try
:
try
:
user
=
User
.
objects
.
get
(
username
=
username
)
user
=
User
.
objects
.
get
(
username
=
username
)
cohort
.
users
.
remove
(
user
)
cohort
s
.
remove_user_from_cohort
(
cohort
,
user
.
username
)
return
json_http_response
({
'success'
:
True
})
return
json_http_response
({
'success'
:
True
})
except
User
.
DoesNotExist
:
except
User
.
DoesNotExist
:
log
.
debug
(
'no user'
)
log
.
debug
(
'no user'
)
...
...
lms/djangoapps/api_manager/users/views.py
View file @
31a5bc25
...
@@ -18,6 +18,12 @@ from rest_framework.response import Response
...
@@ -18,6 +18,12 @@ from rest_framework.response import Response
from
courseware
import
grades
,
module_render
from
courseware
import
grades
,
module_render
from
courseware.model_data
import
FieldDataCache
from
courseware.model_data
import
FieldDataCache
from
courseware.views
import
get_module_for_descriptor
,
save_child_position
,
get_current_child
from
courseware.views
import
get_module_for_descriptor
,
save_child_position
,
get_current_child
from
course_groups.models
import
CourseUserGroup
from
course_groups.cohorts
import
(
get_cohort_by_name
,
add_cohort
,
add_user_to_cohort
)
from
django_comment_common.models
import
Role
,
FORUM_ROLE_MODERATOR
from
django_comment_common.models
import
Role
,
FORUM_ROLE_MODERATOR
from
gradebook.models
import
StudentGradebook
from
gradebook.models
import
StudentGradebook
from
instructor.access
import
revoke_access
,
update_forum_role
from
instructor.access
import
revoke_access
,
update_forum_role
...
@@ -716,6 +722,15 @@ class UsersCoursesList(SecureAPIView):
...
@@ -716,6 +722,15 @@ class UsersCoursesList(SecureAPIView):
return
Response
({},
status
=
status
.
HTTP_404_NOT_FOUND
)
return
Response
({},
status
=
status
.
HTTP_404_NOT_FOUND
)
base_uri
=
generate_base_uri
(
request
)
base_uri
=
generate_base_uri
(
request
)
course_enrollment
=
CourseEnrollment
.
enroll
(
user
,
course_key
)
course_enrollment
=
CourseEnrollment
.
enroll
(
user
,
course_key
)
# Ensure the user is in a cohort. Add it explicitly in the default_cohort
try
:
default_cohort
=
get_cohort_by_name
(
course_id
,
CourseUserGroup
.
default_cohort_name
)
except
CourseUserGroup
.
DoesNotExist
:
default_cohort
=
add_cohort
(
course_id
,
CourseUserGroup
.
default_cohort_name
)
add_user_to_cohort
(
default_cohort
,
user
.
username
)
log
.
debug
(
'User "{}" has been automatically added in cohort "{}" for course "{}"'
.
format
(
user
.
username
,
default_cohort
.
name
,
course_descriptor
.
display_name
)
)
response_data
[
'uri'
]
=
'{}/{}'
.
format
(
base_uri
,
course_id
)
response_data
[
'uri'
]
=
'{}/{}'
.
format
(
base_uri
,
course_id
)
response_data
[
'id'
]
=
unicode
(
course_key
)
response_data
[
'id'
]
=
unicode
(
course_key
)
response_data
[
'name'
]
=
course_descriptor
.
display_name
response_data
[
'name'
]
=
course_descriptor
.
display_name
...
...
lms/djangoapps/projects/migrations/0008_auto__add_workgroupusers.py
0 → 100644
View file @
31a5bc25
This diff is collapsed.
Click to expand it.
lms/djangoapps/projects/models.py
View file @
31a5bc25
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
from
django.contrib.auth.models
import
Group
,
User
from
django.contrib.auth.models
import
Group
,
User
from
django.db
import
models
from
django.db
import
models
from
django.core.exceptions
import
ValidationError
from
model_utils.models
import
TimeStampedModel
from
model_utils.models
import
TimeStampedModel
...
@@ -34,7 +35,8 @@ class Workgroup(TimeStampedModel):
...
@@ -34,7 +35,8 @@ class Workgroup(TimeStampedModel):
"""
"""
name
=
models
.
CharField
(
max_length
=
255
,
null
=
True
,
blank
=
True
)
name
=
models
.
CharField
(
max_length
=
255
,
null
=
True
,
blank
=
True
)
project
=
models
.
ForeignKey
(
Project
,
related_name
=
"workgroups"
)
project
=
models
.
ForeignKey
(
Project
,
related_name
=
"workgroups"
)
users
=
models
.
ManyToManyField
(
User
,
related_name
=
"workgroups"
,
blank
=
True
,
null
=
True
)
users
=
models
.
ManyToManyField
(
User
,
related_name
=
"workgroups"
,
through
=
"WorkgroupUser"
,
blank
=
True
,
null
=
True
)
groups
=
models
.
ManyToManyField
(
Group
,
related_name
=
"workgroups"
,
blank
=
True
,
null
=
True
)
groups
=
models
.
ManyToManyField
(
Group
,
related_name
=
"workgroups"
,
blank
=
True
,
null
=
True
)
@property
@property
...
@@ -53,6 +55,35 @@ class Workgroup(TimeStampedModel):
...
@@ -53,6 +55,35 @@ class Workgroup(TimeStampedModel):
workgroup_name
workgroup_name
)
)
def
add_user
(
self
,
user
):
workgroup_user
=
WorkgroupUser
(
workgroup
=
self
,
user
=
user
)
workgroup_user
.
save
()
def
remove_user
(
self
,
user
):
workgroup_user
=
WorkgroupUser
.
objects
.
get
(
workgroup
=
self
,
user
=
user
)
workgroup_user
.
delete
()
class
WorkgroupUser
(
models
.
Model
):
"""A Folder to store some data between a client and its insurance"""
workgroup
=
models
.
ForeignKey
(
Workgroup
,
null
=
False
)
user
=
models
.
ForeignKey
(
User
,
null
=
False
)
class
Meta
:
db_table
=
'projects_workgroup_users'
def
clean
(
self
):
# Ensure the user is not already assigned to a workgroup for this course
existing_workgroups
=
Workgroup
.
objects
.
filter
(
users
=
self
.
user
)
.
filter
(
project__course_id
=
self
.
workgroup
.
project
.
course_id
)
if
len
(
existing_workgroups
):
raise
ValidationError
(
'User {} is already assigned to a workgroup for this course'
.
format
(
self
.
user
.
username
))
def
save
(
self
,
**
kwargs
):
self
.
clean
()
return
super
(
WorkgroupUser
,
self
)
.
save
(
**
kwargs
)
class
WorkgroupReview
(
TimeStampedModel
):
class
WorkgroupReview
(
TimeStampedModel
):
"""
"""
Model representing the Workgroup Review concept. A Workgroup Review is
Model representing the Workgroup Review concept. A Workgroup Review is
...
...
lms/djangoapps/projects/tests/test_peer_reviews.py
View file @
31a5bc25
...
@@ -84,7 +84,7 @@ class PeerReviewsApiTests(TestCase):
...
@@ -84,7 +84,7 @@ class PeerReviewsApiTests(TestCase):
name
=
"Test Workgroup"
,
name
=
"Test Workgroup"
,
project
=
self
.
test_project
,
project
=
self
.
test_project
,
)
)
self
.
test_workgroup
.
users
.
add
(
self
.
test_peer_user
)
self
.
test_workgroup
.
add_user
(
self
.
test_peer_user
)
self
.
test_workgroup
.
save
()
self
.
test_workgroup
.
save
()
self
.
client
=
SecureClient
()
self
.
client
=
SecureClient
()
...
...
lms/djangoapps/projects/tests/test_projects.py
View file @
31a5bc25
...
@@ -58,7 +58,7 @@ class ProjectsApiTests(TestCase):
...
@@ -58,7 +58,7 @@ class ProjectsApiTests(TestCase):
name
=
"Test Workgroup"
,
name
=
"Test Workgroup"
,
project
=
self
.
test_project
,
project
=
self
.
test_project
,
)
)
self
.
test_workgroup
.
users
.
add
(
self
.
test_user
)
self
.
test_workgroup
.
add_user
(
self
.
test_user
)
self
.
test_workgroup
.
save
()
self
.
test_workgroup
.
save
()
self
.
client
=
SecureClient
()
self
.
client
=
SecureClient
()
...
...
lms/djangoapps/projects/tests/test_submission_reviews.py
View file @
31a5bc25
...
@@ -77,7 +77,7 @@ class SubmissionReviewsApiTests(TestCase):
...
@@ -77,7 +77,7 @@ class SubmissionReviewsApiTests(TestCase):
name
=
"Test Workgroup"
,
name
=
"Test Workgroup"
,
project
=
self
.
test_project
,
project
=
self
.
test_project
,
)
)
self
.
test_workgroup
.
users
.
add
(
self
.
test_user
)
self
.
test_workgroup
.
add_user
(
self
.
test_user
)
self
.
test_workgroup
.
save
()
self
.
test_workgroup
.
save
()
self
.
test_submission
=
WorkgroupSubmission
.
objects
.
create
(
self
.
test_submission
=
WorkgroupSubmission
.
objects
.
create
(
...
...
lms/djangoapps/projects/tests/test_workgroup_reviews.py
View file @
31a5bc25
...
@@ -77,7 +77,7 @@ class WorkgroupReviewsApiTests(TestCase):
...
@@ -77,7 +77,7 @@ class WorkgroupReviewsApiTests(TestCase):
name
=
"Test Workgroup"
,
name
=
"Test Workgroup"
,
project
=
self
.
test_project
,
project
=
self
.
test_project
,
)
)
self
.
test_workgroup
.
users
.
add
(
self
.
test_user
)
self
.
test_workgroup
.
add_user
(
self
.
test_user
)
self
.
test_workgroup
.
save
()
self
.
test_workgroup
.
save
()
self
.
test_submission
=
WorkgroupSubmission
.
objects
.
create
(
self
.
test_submission
=
WorkgroupSubmission
.
objects
.
create
(
...
...
lms/djangoapps/projects/tests/test_workgroup_submissions.py
View file @
31a5bc25
...
@@ -64,7 +64,7 @@ class SubmissionsApiTests(TestCase):
...
@@ -64,7 +64,7 @@ class SubmissionsApiTests(TestCase):
name
=
"Test Workgroup"
,
name
=
"Test Workgroup"
,
project
=
self
.
test_project
,
project
=
self
.
test_project
,
)
)
self
.
test_workgroup
.
users
.
add
(
self
.
test_user
)
self
.
test_workgroup
.
add_user
(
self
.
test_user
)
self
.
test_workgroup
.
save
()
self
.
test_workgroup
.
save
()
self
.
client
=
SecureClient
()
self
.
client
=
SecureClient
()
...
...
lms/djangoapps/projects/tests/test_workgroups.py
View file @
31a5bc25
...
@@ -182,7 +182,7 @@ class WorkgroupsApiTests(TestCase):
...
@@ -182,7 +182,7 @@ class WorkgroupsApiTests(TestCase):
response
.
data
[
'id'
],
response
.
data
[
'id'
],
self
.
test_workgroup_name
self
.
test_workgroup_name
)
)
cohort
=
get_cohort_by_name
(
self
.
test_course
.
id
,
cohort_name
,
CourseUserGroup
.
WORKGROUP
)
cohort
=
get_cohort_by_name
(
self
.
test_course
.
id
,
cohort_name
)
self
.
assertIsNotNone
(
cohort
)
self
.
assertIsNotNone
(
cohort
)
def
test_workgroups_detail_get
(
self
):
def
test_workgroups_detail_get
(
self
):
...
@@ -276,9 +276,9 @@ class WorkgroupsApiTests(TestCase):
...
@@ -276,9 +276,9 @@ class WorkgroupsApiTests(TestCase):
response
.
data
[
'id'
],
response
.
data
[
'id'
],
self
.
test_workgroup_name
self
.
test_workgroup_name
)
)
cohort
=
get_cohort_by_name
(
self
.
test_course
.
id
,
cohort_name
,
CourseUserGroup
.
WORKGROUP
)
cohort
=
get_cohort_by_name
(
self
.
test_course
.
id
,
cohort_name
)
self
.
assertIsNotNone
(
cohort
)
self
.
assertIsNotNone
(
cohort
)
self
.
assertTrue
(
is_user_in_cohort
(
cohort
,
self
.
test_user
.
id
,
CourseUserGroup
.
WORKGROUP
))
self
.
assertTrue
(
is_user_in_cohort
(
cohort
,
self
.
test_user
.
id
))
def
test_workgroups_users_post_preexisting_workgroup
(
self
):
def
test_workgroups_users_post_preexisting_workgroup
(
self
):
...
@@ -360,15 +360,15 @@ class WorkgroupsApiTests(TestCase):
...
@@ -360,15 +360,15 @@ class WorkgroupsApiTests(TestCase):
)
)
# now let's remove existing cohort users
# now let's remove existing cohort users
cohort
=
get_cohort_by_name
(
self
.
test_course
.
id
,
cohort_name
,
CourseUserGroup
.
WORKGROUP
)
cohort
=
get_cohort_by_name
(
self
.
test_course
.
id
,
cohort_name
)
self
.
assertTrue
(
is_user_in_cohort
(
cohort
,
self
.
test_user
.
id
,
CourseUserGroup
.
WORKGROUP
))
self
.
assertTrue
(
is_user_in_cohort
(
cohort
,
self
.
test_user
.
id
))
remove_user_from_cohort
(
cohort
,
self
.
test_user
.
username
,
CourseUserGroup
.
WORKGROUP
)
remove_user_from_cohort
(
cohort
,
self
.
test_user
.
username
)
self
.
assertFalse
(
is_user_in_cohort
(
cohort
,
self
.
test_user
.
id
,
CourseUserGroup
.
WORKGROUP
))
self
.
assertFalse
(
is_user_in_cohort
(
cohort
,
self
.
test_user
.
id
))
# delete cohort
# delete cohort
delete_empty_cohort
(
self
.
test_course
.
id
,
cohort_name
,
CourseUserGroup
.
WORKGROUP
)
delete_empty_cohort
(
self
.
test_course
.
id
,
cohort_name
)
self
.
assertEqual
(
0
,
len
(
get_course_cohort_names
(
self
.
test_course
.
id
,
CourseUserGroup
.
WORKGROUP
)))
self
.
assertEqual
(
0
,
len
(
get_course_cohort_names
(
self
.
test_course
.
id
)))
# add a 2nd user and make sure a discussion cohort was created and users were backfilled
# add a 2nd user and make sure a discussion cohort was created and users were backfilled
test_uri
=
'{}{}/'
.
format
(
self
.
test_workgroups_uri
,
str
(
response
.
data
[
'id'
]))
test_uri
=
'{}{}/'
.
format
(
self
.
test_workgroups_uri
,
str
(
response
.
data
[
'id'
]))
...
@@ -378,10 +378,10 @@ class WorkgroupsApiTests(TestCase):
...
@@ -378,10 +378,10 @@ class WorkgroupsApiTests(TestCase):
self
.
assertEqual
(
response
.
status_code
,
201
)
self
.
assertEqual
(
response
.
status_code
,
201
)
# now inspect cohort and assert that things are as we anticipate (i.e. both users are in there)
# now inspect cohort and assert that things are as we anticipate (i.e. both users are in there)
cohort
=
get_cohort_by_name
(
self
.
test_course
.
id
,
cohort_name
,
CourseUserGroup
.
WORKGROUP
)
cohort
=
get_cohort_by_name
(
self
.
test_course
.
id
,
cohort_name
)
self
.
assertIsNotNone
(
cohort
)
self
.
assertIsNotNone
(
cohort
)
self
.
assertTrue
(
is_user_in_cohort
(
cohort
,
self
.
test_user
.
id
,
CourseUserGroup
.
WORKGROUP
))
self
.
assertTrue
(
is_user_in_cohort
(
cohort
,
self
.
test_user
.
id
))
self
.
assertTrue
(
is_user_in_cohort
(
cohort
,
self
.
test_user2
.
id
,
CourseUserGroup
.
WORKGROUP
))
self
.
assertTrue
(
is_user_in_cohort
(
cohort
,
self
.
test_user2
.
id
))
def
test_workgroups_users_delete
(
self
):
def
test_workgroups_users_delete
(
self
):
data
=
{
data
=
{
...
...
lms/djangoapps/projects/views.py
View file @
31a5bc25
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
""" WORKGROUPS API VIEWS """
""" WORKGROUPS API VIEWS """
from
django.contrib.auth.models
import
Group
,
User
from
django.contrib.auth.models
import
Group
,
User
from
django.core.exceptions
import
ObjectDoesNotExist
from
django.core.exceptions
import
ObjectDoesNotExist
,
ValidationError
from
rest_framework
import
viewsets
from
rest_framework
import
viewsets
from
rest_framework.decorators
import
action
,
link
from
rest_framework.decorators
import
action
,
link
...
@@ -22,6 +22,8 @@ from opaque_keys.edx.keys import CourseKey, UsageKey
...
@@ -22,6 +22,8 @@ from opaque_keys.edx.keys import CourseKey, UsageKey
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
,
Location
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
,
Location
from
xmodule.modulestore
import
Location
,
InvalidLocationError
from
xmodule.modulestore
import
Location
,
InvalidLocationError
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.django
import
modulestore
from
course_groups.cohorts
import
(
add_cohort
,
add_user_to_cohort
,
get_cohort_by_name
,
remove_user_from_cohort
)
from
.models
import
Project
,
Workgroup
,
WorkgroupSubmission
from
.models
import
Project
,
Workgroup
,
WorkgroupSubmission
from
.models
import
WorkgroupReview
,
WorkgroupSubmissionReview
,
WorkgroupPeerReview
from
.models
import
WorkgroupReview
,
WorkgroupSubmissionReview
,
WorkgroupPeerReview
...
@@ -111,6 +113,20 @@ class WorkgroupsViewSet(viewsets.ModelViewSet):
...
@@ -111,6 +113,20 @@ class WorkgroupsViewSet(viewsets.ModelViewSet):
serializer_class
=
WorkgroupSerializer
serializer_class
=
WorkgroupSerializer
model
=
Workgroup
model
=
Workgroup
def
create
(
self
,
request
):
"""
Create a new workgroup and its cohort.
"""
response
=
super
(
WorkgroupsViewSet
,
self
)
.
create
(
request
)
if
response
.
status_code
==
status
.
HTTP_201_CREATED
:
# create the workgroup cohort
workgroup
=
self
.
object
course_descriptor
,
course_key
,
course_content
=
_get_course
(
self
.
request
,
self
.
request
.
user
,
workgroup
.
project
.
course_id
)
# pylint: disable=W0612
add_cohort
(
course_key
,
workgroup
.
cohort_name
)
return
response
@action
(
methods
=
[
'get'
,
'post'
])
@action
(
methods
=
[
'get'
,
'post'
])
def
groups
(
self
,
request
,
pk
):
def
groups
(
self
,
request
,
pk
):
"""
"""
...
@@ -134,7 +150,6 @@ class WorkgroupsViewSet(viewsets.ModelViewSet):
...
@@ -134,7 +150,6 @@ class WorkgroupsViewSet(viewsets.ModelViewSet):
workgroup
=
self
.
get_object
()
workgroup
=
self
.
get_object
()
workgroup
.
groups
.
add
(
group
)
workgroup
.
groups
.
add
(
group
)
workgroup
.
save
()
workgroup
.
save
()
print
workgroup
.
groups
.
all
()
return
Response
({},
status
=
status
.
HTTP_201_CREATED
)
return
Response
({},
status
=
status
.
HTTP_201_CREATED
)
@action
(
methods
=
[
'get'
,
'post'
,
'delete'
])
@action
(
methods
=
[
'get'
,
'post'
,
'delete'
])
...
@@ -160,21 +175,31 @@ class WorkgroupsViewSet(viewsets.ModelViewSet):
...
@@ -160,21 +175,31 @@ class WorkgroupsViewSet(viewsets.ModelViewSet):
workgroup
=
self
.
get_object
()
workgroup
=
self
.
get_object
()
# Ensure the user is not already assigned to a workgroup for this project
existing_workgroups
=
Workgroup
.
objects
.
filter
(
users
=
user
)
.
filter
(
project
=
workgroup
.
project
)
if
len
(
existing_workgroups
):
message
=
'User {} already assigned to a workgroup for this project'
.
format
(
user_id
)
return
Response
({
"detail"
:
message
},
status
.
HTTP_400_BAD_REQUEST
)
# Ensure the user is not already assigned to a project for this course
# Ensure the user is not already assigned to a project for this course
existing_projects
=
Project
.
objects
.
filter
(
course_id
=
workgroup
.
project
.
course_id
)
.
filter
(
workgroups__users__id
=
user
.
id
)
existing_projects
=
Project
.
objects
.
filter
(
course_id
=
workgroup
.
project
.
course_id
)
.
filter
(
workgroups__users__id
=
user
.
id
)
if
len
(
existing_projects
):
if
len
(
existing_projects
):
message
=
'User {} already assigned to a project for this course'
.
format
(
user_id
)
message
=
'User {} already assigned to a project for this course'
.
format
(
user_id
)
return
Response
({
"detail"
:
message
},
status
.
HTTP_400_BAD_REQUEST
)
return
Response
({
"detail"
:
message
},
status
.
HTTP_400_BAD_REQUEST
)
workgroup
.
users
.
add
(
user
)
try
:
workgroup
.
add_user
(
user
)
except
ValidationError
as
e
:
return
Response
({
"detail"
:
unicode
(
e
)},
status
.
HTTP_400_BAD_REQUEST
)
workgroup
.
save
()
workgroup
.
save
()
# add user to the workgroup cohort, create it if it doesn't exist (for cases where there is a legacy
# workgroup)
course_descriptor
,
course_key
,
course_content
=
_get_course
(
self
.
request
,
user
,
workgroup
.
project
.
course_id
)
# pylint: disable=W0612
try
:
cohort
=
get_cohort_by_name
(
course_key
,
workgroup
.
cohort_name
)
add_user_to_cohort
(
cohort
,
user
.
username
)
except
ObjectDoesNotExist
:
# This use case handles cases where a workgroup might have been created before
# the notion of a cohorted discussion. So we need to backfill in the data
cohort
=
add_cohort
(
course_key
,
workgroup
.
cohort_name
)
for
workgroup_user
in
workgroup
.
users
.
all
():
add_user_to_cohort
(
cohort
,
workgroup_user
.
username
)
return
Response
({},
status
=
status
.
HTTP_201_CREATED
)
return
Response
({},
status
=
status
.
HTTP_201_CREATED
)
else
:
else
:
user_id
=
request
.
DATA
.
get
(
'id'
)
user_id
=
request
.
DATA
.
get
(
'id'
)
...
@@ -184,7 +209,11 @@ class WorkgroupsViewSet(viewsets.ModelViewSet):
...
@@ -184,7 +209,11 @@ class WorkgroupsViewSet(viewsets.ModelViewSet):
message
=
'User {} does not exist'
.
format
(
user_id
)
message
=
'User {} does not exist'
.
format
(
user_id
)
return
Response
({
"detail"
:
message
},
status
.
HTTP_400_BAD_REQUEST
)
return
Response
({
"detail"
:
message
},
status
.
HTTP_400_BAD_REQUEST
)
workgroup
=
self
.
get_object
()
workgroup
=
self
.
get_object
()
workgroup
.
users
.
remove
(
user
)
course_descriptor
,
course_key
,
course_content
=
_get_course
(
self
.
request
,
user
,
workgroup
.
project
.
course_id
)
# pylint: disable=W0612
cohort
=
get_cohort_by_name
(
course_key
,
workgroup
.
cohort_name
)
workgroup
.
remove_user
(
user
)
remove_user_from_cohort
(
cohort
,
user
.
username
)
return
Response
({},
status
=
status
.
HTTP_204_NO_CONTENT
)
return
Response
({},
status
=
status
.
HTTP_204_NO_CONTENT
)
@link
()
@link
()
...
...
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