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
75942770
Commit
75942770
authored
Apr 21, 2014
by
chrisndodge
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #12 from edx-solutions/cdodge/course_users_list
add ability to enroll users into courses
parents
f59612ce
4527a67d
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
146 additions
and
1 deletions
+146
-1
lms/djangoapps/api_manager/courses_urls.py
+1
-0
lms/djangoapps/api_manager/courses_views.py
+71
-1
lms/djangoapps/api_manager/tests/test_courses_views.py
+71
-0
lms/djangoapps/api_manager/users_views.py
+3
-0
No files found.
lms/djangoapps/api_manager/courses_urls.py
View file @
75942770
...
...
@@ -16,5 +16,6 @@ urlpatterns = patterns(
url
(
r'^(?P<course_id>[^/]+/[^/]+/[^/]+)/updates$'
,
'course_updates'
),
url
(
r'^(?P<course_id>[^/]+/[^/]+/[^/]+)/static_tabs/(?P<tab_id>[a-zA-Z0-9/_:]+)$'
,
'static_tab_detail'
),
url
(
r'^(?P<course_id>[^/]+/[^/]+/[^/]+)/static_tabs$'
,
'static_tabs_list'
),
url
(
r'^(?P<course_id>[^/]+/[^/]+/[^/]+)/users$'
,
'course_users_list'
),
url
(
r'^(?P<course_id>[^/]+/[^/]+/[^/]+)$'
,
'courses_detail'
),
)
lms/djangoapps/api_manager/courses_views.py
View file @
75942770
""" API implementation for course-oriented interactions. """
from
django.contrib.auth.models
import
Group
from
django.contrib.auth.models
import
Group
,
User
from
django.core.exceptions
import
ObjectDoesNotExist
from
lxml
import
etree
from
StringIO
import
StringIO
...
...
@@ -18,6 +18,7 @@ from xmodule.modulestore import Location, InvalidLocationError
from
courseware.courses
import
get_course_about_section
,
get_course_info_section
from
courseware.views
import
get_static_tab_contents
from
student.models
import
CourseEnrollment
,
CourseEnrollmentAllowed
log
=
logging
.
getLogger
(
__name__
)
...
...
@@ -549,3 +550,72 @@ def static_tab_detail(request, course_id, tab_id):
return
Response
({},
status
=
status
.
HTTP_404_NOT_FOUND
)
return
Response
(
response_data
)
@api_view
([
'GET'
,
'POST'
,
'DELETE'
])
@permission_classes
((
ApiKeyHeaderPermission
,))
def
course_users_list
(
request
,
course_id
):
"""
GET returns a list of users enrolled in the course_id
POST enrolls a student in the course. Note, this can be a user_id or just an email, in case
the user does not exist in the system
"""
store
=
modulestore
()
response_data
=
OrderedDict
()
try
:
# find the course
course_module
=
store
.
get_course
(
course_id
)
if
not
course_module
:
return
Response
({},
status
=
status
.
HTTP_404_NOT_FOUND
)
except
InvalidLocationError
:
return
Response
({},
status
=
status
.
HTTP_404_NOT_FOUND
)
if
request
.
method
==
'GET'
:
# Get a list of all enrolled students
users
=
CourseEnrollment
.
users_enrolled_in
(
course_id
)
response_data
[
'enrollments'
]
=
[]
for
user
in
users
:
user_data
=
OrderedDict
()
user_data
[
'id'
]
=
user
.
id
user_data
[
'email'
]
=
user
.
email
user_data
[
'username'
]
=
user
.
username
# @TODO: Should we create a URI resourse that points to user?!? But that's in a different URL subpath
response_data
[
'enrollments'
]
.
append
(
user_data
)
# Then list all enrollments which are pending. These are enrollments for students that have not yet
# created an account
pending_enrollments
=
CourseEnrollmentAllowed
.
objects
.
filter
(
course_id
=
course_id
)
if
pending_enrollments
:
response_data
[
'pending_enrollments'
]
=
[]
for
cea
in
pending_enrollments
:
response_data
[
'pending_enrollments'
]
.
append
(
cea
.
email
)
return
Response
(
response_data
)
elif
request
.
method
==
'POST'
:
if
'user_id'
in
request
.
DATA
:
user_id
=
request
.
DATA
[
'user_id'
]
try
:
existing_user
=
User
.
objects
.
get
(
id
=
user_id
)
CourseEnrollment
.
enroll
(
existing_user
,
course_id
)
except
ObjectDoesNotExist
:
return
Response
({
'err'
:
'user_does_not_exist'
},
status
=
status
.
HTTP_400_BAD_REQUEST
)
elif
'email'
in
request
.
DATA
:
# If caller passed in an email, then let's look up user by email address
# if it doesn't exist then we need to assume that the student does not exist
# in our database and that the instructor is pre-enrolling ment
email
=
request
.
DATA
[
'email'
]
try
:
existing_user
=
User
.
objects
.
get
(
email
=
email
)
CourseEnrollment
.
enroll
(
existing_user
,
course_id
)
except
ObjectDoesNotExist
:
if
not
request
.
DATA
.
get
(
'allow_pending'
,
False
):
return
Response
({
'err'
:
'user_does_not_exist'
},
status
=
status
.
HTTP_400_BAD_REQUEST
)
# In this case we can pre-enroll a non-existing student. This is what the
# CourseEnrollmentAllowed table is for
# NOTE: This logic really should live in CourseEnrollment.....
cea
,
_
=
CourseEnrollmentAllowed
.
objects
.
get_or_create
(
course_id
=
course_id
,
email
=
email
)
cea
.
auto_enroll
=
True
cea
.
save
()
return
Response
({},
status
.
HTTP_201_CREATED
)
lms/djangoapps/api_manager/tests/test_courses_views.py
View file @
75942770
...
...
@@ -7,6 +7,7 @@ Run these tests @ Devstack:
import
simplejson
as
json
import
unittest
import
uuid
from
random
import
randint
from
django.core.cache
import
cache
from
django.test
import
TestCase
,
Client
...
...
@@ -450,3 +451,73 @@ class CoursesApiTests(TestCase):
response
=
self
.
do_get
(
test_uri
)
self
.
assertEqual
(
response
.
status_code
,
404
)
def
test_course_enrollments
(
self
):
test_uri
=
self
.
base_courses_uri
+
'/'
+
self
.
test_course_id
+
'/users'
response
=
self
.
do_get
(
test_uri
)
self
.
assertEqual
(
response
.
status_code
,
200
)
self
.
assertGreater
(
len
(
response
.
data
),
0
)
# assert that there is no enrolled students
enrollments
=
response
.
data
[
'enrollments'
]
self
.
assertEqual
(
len
(
enrollments
),
0
)
self
.
assertNotIn
(
'pending_enrollments'
,
response
.
data
)
# enroll a non-existing student
# first, don't allow non-existing
post_data
=
{}
post_data
[
'email'
]
=
'test+pending@tester.com'
post_data
[
'allow_pending'
]
=
False
response
=
self
.
do_post
(
test_uri
,
post_data
)
self
.
assertEqual
(
response
.
status_code
,
400
)
post_data
[
'allow_pending'
]
=
True
response
=
self
.
do_post
(
test_uri
,
post_data
)
self
.
assertEqual
(
response
.
status_code
,
201
)
# re-run query
response
=
self
.
do_get
(
test_uri
)
self
.
assertEqual
(
response
.
status_code
,
200
)
self
.
assertGreater
(
len
(
response
.
data
),
0
)
# assert that we just have a single pending enrollment
enrollments
=
response
.
data
[
'enrollments'
]
self
.
assertEqual
(
len
(
enrollments
),
0
)
self
.
assertIn
(
'pending_enrollments'
,
response
.
data
)
pending
=
response
.
data
[
'pending_enrollments'
]
self
.
assertEqual
(
len
(
pending
),
1
)
self
.
assertEqual
(
pending
[
0
],
'test+pending@tester.com'
)
# create a new user (note, this calls into the /users/ subsystem)
test_user_uri
=
'/api/users'
local_username
=
"some_test_user"
+
str
(
randint
(
11
,
99
))
local_email
=
"test+notpending@tester.com"
data
=
{
'email'
:
local_email
,
'username'
:
local_username
,
'password'
:
'fooabr'
,
'first_name'
:
'Joe'
,
'last_name'
:
'Brown'
}
response
=
self
.
do_post
(
test_user_uri
,
data
)
self
.
assertEqual
(
response
.
status_code
,
201
)
self
.
assertGreater
(
response
.
data
[
'id'
],
0
)
created_user_id
=
response
.
data
[
'id'
]
# now register this user
post_data
=
{}
post_data
[
'user_id'
]
=
created_user_id
response
=
self
.
do_post
(
test_uri
,
post_data
)
self
.
assertEqual
(
response
.
status_code
,
201
)
# now re-query, we should see it listed now in the list of enrollments
# re-run query
response
=
self
.
do_get
(
test_uri
)
self
.
assertEqual
(
response
.
status_code
,
200
)
self
.
assertGreater
(
len
(
response
.
data
),
0
)
# assert that we just have a single pending enrollment
enrollments
=
response
.
data
[
'enrollments'
]
self
.
assertEqual
(
len
(
enrollments
),
1
)
self
.
assertEqual
(
enrollments
[
0
][
'id'
],
created_user_id
)
self
.
assertEqual
(
enrollments
[
0
][
'email'
],
local_email
)
self
.
assertEqual
(
enrollments
[
0
][
'username'
],
local_username
)
lms/djangoapps/api_manager/users_views.py
View file @
75942770
...
...
@@ -105,6 +105,9 @@ def user_list(request):
user
.
last_name
=
last_name
user
.
save
()
# CDODGE: @TODO: We will have to extend this to look in the CourseEnrollmentAllowed table and
# auto-enroll students when they create a new account. Also be sure to remove from
# the CourseEnrollmentAllow table after the auto-registration has taken place
if
user
:
status_code
=
status
.
HTTP_201_CREATED
response_data
=
_serialize_user
(
response_data
,
user
)
...
...
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