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
3f43fb64
Commit
3f43fb64
authored
Feb 04, 2014
by
chrisndodge
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1967 from edx/feature/cdodge/cap-num-enrollments
Add ability to cap number of enrollments in a course
parents
818ad159
ad7348ec
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
96 additions
and
4 deletions
+96
-4
CHANGELOG.rst
+2
-0
common/djangoapps/student/models.py
+22
-0
common/djangoapps/student/views.py
+6
-0
common/lib/xmodule/xmodule/course_module.py
+4
-1
lms/djangoapps/courseware/tests/test_about.py
+51
-0
lms/djangoapps/courseware/views.py
+5
-1
lms/djangoapps/instructor/views/instructor_dashboard.py
+1
-1
lms/djangoapps/instructor/views/legacy.py
+1
-1
lms/templates/courseware/course_about.html
+4
-0
No files found.
CHANGELOG.rst
View file @
3f43fb64
...
...
@@ -193,6 +193,8 @@ it pauses on the end time.
Blades: Disallow users to enter video url's in http.
Studio/LMS: Ability to cap the max number of active enrollments in a course
LMS: Improve the acessibility of the forum follow post buttons.
Blades: Latex problems are now enabled via use_latex_compiler
...
...
common/djangoapps/student/models.py
View file @
3f43fb64
...
...
@@ -424,6 +424,28 @@ class CourseEnrollment(models.Model):
return
enrollment
@classmethod
def
num_enrolled_in
(
cls
,
course_id
):
"""
Returns the count of active enrollments in a course.
'course_id' is the course_id to return enrollments
"""
enrollment_number
=
CourseEnrollment
.
objects
.
filter
(
course_id
=
course_id
,
is_active
=
1
)
.
count
()
return
enrollment_number
@classmethod
def
is_course_full
(
cls
,
course
):
"""
Returns a boolean value regarding whether a course has already reached it's max enrollment
capacity
"""
is_course_full
=
False
if
course
.
max_student_enrollments_allowed
is
not
None
:
is_course_full
=
cls
.
num_enrolled_in
(
course
.
location
.
course_id
)
>=
course
.
max_student_enrollments_allowed
return
is_course_full
def
update_enrollment
(
self
,
mode
=
None
,
is_active
=
None
):
"""
Updates an enrollment for a user in a class. This includes options
...
...
common/djangoapps/student/views.py
View file @
3f43fb64
...
...
@@ -561,6 +561,12 @@ def change_enrollment(request):
if
not
has_access
(
user
,
course
,
'enroll'
):
return
HttpResponseBadRequest
(
_
(
"Enrollment is closed"
))
# see if we have already filled up all allowed enrollments
is_course_full
=
CourseEnrollment
.
is_course_full
(
course
)
if
is_course_full
:
return
HttpResponseBadRequest
(
_
(
"Course is full"
))
# If this course is available in multiple modes, redirect them to a page
# where they can choose which mode they want.
available_modes
=
CourseMode
.
modes_for_course
(
course_id
)
...
...
common/lib/xmodule/xmodule/course_module.py
View file @
3f43fb64
...
...
@@ -13,7 +13,7 @@ from xmodule.seq_module import SequenceDescriptor, SequenceModule
from
xmodule.graders
import
grader_from_conf
import
json
from
xblock.fields
import
Scope
,
List
,
String
,
Dict
,
Boolean
from
xblock.fields
import
Scope
,
List
,
String
,
Dict
,
Boolean
,
Integer
from
.fields
import
Date
from
xmodule.modulestore.locator
import
CourseLocator
from
django.utils.timezone
import
UTC
...
...
@@ -384,6 +384,9 @@ class CourseFields(object):
display_coursenumber
=
String
(
help
=
"An optional display string for the course number that will get rendered in the LMS"
,
scope
=
Scope
.
settings
)
max_student_enrollments_allowed
=
Integer
(
help
=
"Limit the number of students allowed to enroll in this course."
,
scope
=
Scope
.
settings
)
class
CourseDescriptor
(
CourseFields
,
SequenceDescriptor
):
module_class
=
SequenceModule
...
...
lms/djangoapps/courseware/tests/test_about.py
View file @
3f43fb64
...
...
@@ -51,3 +51,54 @@ class AboutTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase):
resp
=
self
.
client
.
get
(
url
)
self
.
assertEqual
(
resp
.
status_code
,
200
)
self
.
assertIn
(
self
.
xml_data
,
resp
.
content
)
@override_settings
(
MODULESTORE
=
TEST_DATA_MIXED_MODULESTORE
)
class
AboutWithCappedEnrollmentsTestCase
(
LoginEnrollmentTestCase
,
ModuleStoreTestCase
):
"""
This test case will check the About page when a course has a capped enrollment
"""
def
setUp
(
self
):
"""
Set up the tests
"""
self
.
course
=
CourseFactory
.
create
(
metadata
=
{
"max_student_enrollments_allowed"
:
1
})
self
.
about
=
ItemFactory
.
create
(
category
=
"about"
,
parent_location
=
self
.
course
.
location
,
data
=
"OOGIE BLOOGIE"
,
display_name
=
"overview"
)
# The following XML course is closed; we're testing that
# an about page still appears when the course is already closed
self
.
xml_course_id
=
'edX/detached_pages/2014'
self
.
xml_data
=
"about page 463139"
def
test_enrollment_cap
(
self
):
"""
This test will make sure that enrollment caps are enforced
"""
self
.
setup_user
()
url
=
reverse
(
'about_course'
,
args
=
[
self
.
course
.
id
])
resp
=
self
.
client
.
get
(
url
)
self
.
assertEqual
(
resp
.
status_code
,
200
)
self
.
assertIn
(
'<a href="#" class="register">'
,
resp
.
content
)
self
.
enroll
(
self
.
course
,
verify
=
True
)
# create a new account since the first account is already registered for the course
self
.
email
=
'foo_second@test.com'
self
.
password
=
'bar'
self
.
username
=
'test_second'
self
.
create_account
(
self
.
username
,
self
.
email
,
self
.
password
)
self
.
activate_user
(
self
.
email
)
self
.
login
(
self
.
email
,
self
.
password
)
# Get the about page again and make sure that the page says that the course is full
resp
=
self
.
client
.
get
(
url
)
self
.
assertEqual
(
resp
.
status_code
,
200
)
self
.
assertIn
(
"Course is full"
,
resp
.
content
)
# Try to enroll as well
result
=
self
.
enroll
(
self
.
course
)
self
.
assertFalse
(
result
)
lms/djangoapps/courseware/views.py
View file @
3f43fb64
...
...
@@ -562,6 +562,9 @@ def course_about(request, course_id):
reg_then_add_to_cart_link
=
"{reg_url}?course_id={course_id}&enrollment_action=add_to_cart"
.
format
(
reg_url
=
reverse
(
'register_user'
),
course_id
=
course
.
id
)
# see if we have already filled up all allowed enrollments
is_course_full
=
CourseEnrollment
.
is_course_full
(
course
)
return
render_to_response
(
'courseware/course_about.html'
,
{
'course'
:
course
,
'registered'
:
registered
,
...
...
@@ -569,7 +572,8 @@ def course_about(request, course_id):
'registration_price'
:
registration_price
,
'in_cart'
:
in_cart
,
'reg_then_add_to_cart_link'
:
reg_then_add_to_cart_link
,
'show_courseware_link'
:
show_courseware_link
})
'show_courseware_link'
:
show_courseware_link
,
'is_course_full'
:
is_course_full
})
@ensure_csrf_cookie
...
...
lms/djangoapps/instructor/views/instructor_dashboard.py
View file @
3f43fb64
...
...
@@ -115,7 +115,7 @@ def _section_course_info(course_id, access):
'course_num'
:
course_num
,
'course_name'
:
course_name
,
'course_display_name'
:
course
.
display_name
,
'enrollment_count'
:
CourseEnrollment
.
objects
.
filter
(
course_id
=
course_id
,
is_active
=
1
)
.
count
(
),
'enrollment_count'
:
CourseEnrollment
.
num_enrolled_in
(
course_id
),
'has_started'
:
course
.
has_started
(),
'has_ended'
:
course
.
has_ended
(),
'list_instructor_tasks_url'
:
reverse
(
'list_instructor_tasks'
,
kwargs
=
{
'course_id'
:
course_id
}),
...
...
lms/djangoapps/instructor/views/legacy.py
View file @
3f43fb64
...
...
@@ -110,7 +110,7 @@ def instructor_dashboard(request, course_id):
else
:
idash_mode
=
request
.
session
.
get
(
'idash_mode'
,
'Grades'
)
enrollment_number
=
CourseEnrollment
.
objects
.
filter
(
course_id
=
course_id
,
is_active
=
1
)
.
count
(
)
enrollment_number
=
CourseEnrollment
.
num_enrolled_in
(
course_id
)
# assemble some course statistics for output to instructor
def
get_course_stats_table
():
...
...
lms/templates/courseware/course_about.html
View file @
3f43fb64
...
...
@@ -166,6 +166,10 @@
cost=registration_price)}
</a>
<div
id=
"register_error"
></div>
% elif is_course_full:
<span
class=
"register disabled"
>
${_("Course is full")}
</span>
%else:
<a
href=
"#"
class=
"register"
>
${_("Register for {course.display_number_with_default}").format(course=course) | h}
...
...
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