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
f44d794e
Commit
f44d794e
authored
Aug 20, 2012
by
Victor Shnayder
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add course_id to StudentModule
* Update all uses.
parent
9f23e437
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
172 additions
and
41 deletions
+172
-41
lms/djangoapps/courseware/grades.py
+5
-4
lms/djangoapps/courseware/management/commands/check_course.py
+1
-0
lms/djangoapps/courseware/migrations/0004_add_field_studentmodule_course_id.py
+112
-0
lms/djangoapps/courseware/models.py
+36
-23
lms/djangoapps/courseware/module_render.py
+15
-11
lms/djangoapps/courseware/views.py
+3
-3
No files found.
lms/djangoapps/courseware/grades.py
View file @
f44d794e
...
@@ -42,7 +42,7 @@ def grade(student, request, course, student_module_cache=None):
...
@@ -42,7 +42,7 @@ def grade(student, request, course, student_module_cache=None):
grading_context
=
course
.
grading_context
grading_context
=
course
.
grading_context
if
student_module_cache
==
None
:
if
student_module_cache
==
None
:
student_module_cache
=
StudentModuleCache
(
student
,
grading_context
[
'all_descriptors'
])
student_module_cache
=
StudentModuleCache
(
course
.
id
,
student
,
grading_context
[
'all_descriptors'
])
totaled_scores
=
{}
totaled_scores
=
{}
# This next complicated loop is just to collect the totaled_scores, which is
# This next complicated loop is just to collect the totaled_scores, which is
...
@@ -56,7 +56,8 @@ def grade(student, request, course, student_module_cache=None):
...
@@ -56,7 +56,8 @@ def grade(student, request, course, student_module_cache=None):
should_grade_section
=
False
should_grade_section
=
False
# If we haven't seen a single problem in the section, we don't have to grade it at all! We can assume 0%
# If we haven't seen a single problem in the section, we don't have to grade it at all! We can assume 0%
for
moduledescriptor
in
section
[
'xmoduledescriptors'
]:
for
moduledescriptor
in
section
[
'xmoduledescriptors'
]:
if
student_module_cache
.
lookup
(
moduledescriptor
.
category
,
moduledescriptor
.
location
.
url
()
):
if
student_module_cache
.
lookup
(
course
.
id
,
moduledescriptor
.
category
,
moduledescriptor
.
location
.
url
()):
should_grade_section
=
True
should_grade_section
=
True
break
break
...
@@ -64,10 +65,9 @@ def grade(student, request, course, student_module_cache=None):
...
@@ -64,10 +65,9 @@ def grade(student, request, course, student_module_cache=None):
scores
=
[]
scores
=
[]
# TODO: We need the request to pass into here. If we could forgo that, our arguments
# TODO: We need the request to pass into here. If we could forgo that, our arguments
# would be simpler
# would be simpler
course_id
=
CourseDescriptor
.
location_to_id
(
course
.
location
)
section_module
=
get_module
(
student
,
request
,
section_module
=
get_module
(
student
,
request
,
section_descriptor
.
location
,
student_module_cache
,
section_descriptor
.
location
,
student_module_cache
,
course
_
id
)
course
.
id
)
if
section_module
is
None
:
if
section_module
is
None
:
# student doesn't have access to this module, or something else
# student doesn't have access to this module, or something else
# went wrong.
# went wrong.
...
@@ -219,6 +219,7 @@ def get_score(user, problem, student_module_cache):
...
@@ -219,6 +219,7 @@ def get_score(user, problem, student_module_cache):
# instance_module = student_module_cache.lookup(problem.category, problem.id)
# instance_module = student_module_cache.lookup(problem.category, problem.id)
# if instance_module is None:
# if instance_module is None:
# instance_module = StudentModule(module_type=problem.category,
# instance_module = StudentModule(module_type=problem.category,
# course_id=????,
# module_state_key=problem.id,
# module_state_key=problem.id,
# student=user,
# student=user,
# state=None,
# state=None,
...
...
lms/djangoapps/courseware/management/commands/check_course.py
View file @
f44d794e
...
@@ -84,6 +84,7 @@ class Command(BaseCommand):
...
@@ -84,6 +84,7 @@ class Command(BaseCommand):
# TODO (cpennington): Get coursename in a legitimate way
# TODO (cpennington): Get coursename in a legitimate way
course_location = 'i4x://edx/6002xs12/course/6.002_Spring_2012'
course_location = 'i4x://edx/6002xs12/course/6.002_Spring_2012'
student_module_cache = StudentModuleCache.cache_for_descriptor_descendents(
student_module_cache = StudentModuleCache.cache_for_descriptor_descendents(
course_id,
sample_user, modulestore().get_item(course_location))
sample_user, modulestore().get_item(course_location))
course = get_module(sample_user, None, course_location, student_module_cache)
course = get_module(sample_user, None, course_location, student_module_cache)
...
...
lms/djangoapps/courseware/migrations/0004_add_field_studentmodule_course_id.py
0 → 100644
View file @
f44d794e
# -*- coding: utf-8 -*-
import
datetime
from
south.db
import
db
from
south.v2
import
SchemaMigration
from
django.db
import
models
class
Migration
(
SchemaMigration
):
def
forwards
(
self
,
orm
):
# Adding field 'StudentModule.course_id'
db
.
add_column
(
'courseware_studentmodule'
,
'course_id'
,
self
.
gf
(
'django.db.models.fields.CharField'
)(
default
=
""
,
max_length
=
255
,
db_index
=
True
),
keep_default
=
False
)
# Removing unique constraint on 'StudentModule', fields ['module_id', 'student']
db
.
delete_unique
(
'courseware_studentmodule'
,
[
'module_id'
,
'student_id'
])
# Adding unique constraint on 'StudentModule', fields ['course_id', 'module_state_key', 'student']
db
.
create_unique
(
'courseware_studentmodule'
,
[
'course_id'
,
'module_id'
,
'student_id'
])
def
backwards
(
self
,
orm
):
# Removing unique constraint on 'StudentModule', fields ['course_id', 'module_state_key', 'student']
db
.
delete_unique
(
'courseware_studentmodule'
,
[
'course_id'
,
'module_id'
,
'student_id'
])
# Deleting field 'StudentModule.course_id'
db
.
delete_column
(
'courseware_studentmodule'
,
'course_id'
)
# Adding unique constraint on 'StudentModule', fields ['module_id', 'student']
db
.
create_unique
(
'courseware_studentmodule'
,
[
'module_id'
,
'student_id'
])
models
=
{
'auth.group'
:
{
'Meta'
:
{
'object_name'
:
'Group'
},
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'80'
}),
'permissions'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
"orm['auth.Permission']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
})
},
'auth.permission'
:
{
'Meta'
:
{
'ordering'
:
"('content_type__app_label', 'content_type__model', 'codename')"
,
'unique_together'
:
"(('content_type', 'codename'),)"
,
'object_name'
:
'Permission'
},
'codename'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'content_type'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['contenttypes.ContentType']"
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'50'
})
},
'auth.user'
:
{
'Meta'
:
{
'object_name'
:
'User'
},
'about'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'avatar_type'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'n'"
,
'max_length'
:
'1'
}),
'bronze'
:
(
'django.db.models.fields.SmallIntegerField'
,
[],
{
'default'
:
'0'
}),
'consecutive_days_visit_count'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'default'
:
'0'
}),
'country'
:
(
'django_countries.fields.CountryField'
,
[],
{
'max_length'
:
'2'
,
'blank'
:
'True'
}),
'date_joined'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'date_of_birth'
:
(
'django.db.models.fields.DateField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
'display_tag_filter_strategy'
:
(
'django.db.models.fields.SmallIntegerField'
,
[],
{
'default'
:
'0'
}),
'email'
:
(
'django.db.models.fields.EmailField'
,
[],
{
'max_length'
:
'75'
,
'blank'
:
'True'
}),
'email_isvalid'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'email_key'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'32'
,
'null'
:
'True'
}),
'email_tag_filter_strategy'
:
(
'django.db.models.fields.SmallIntegerField'
,
[],
{
'default'
:
'1'
}),
'first_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'30'
,
'blank'
:
'True'
}),
'gold'
:
(
'django.db.models.fields.SmallIntegerField'
,
[],
{
'default'
:
'0'
}),
'gravatar'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'32'
}),
'groups'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
"orm['auth.Group']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'ignored_tags'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'interesting_tags'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'is_active'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'True'
}),
'is_staff'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'is_superuser'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'last_login'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'last_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'30'
,
'blank'
:
'True'
}),
'last_seen'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'location'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
,
'blank'
:
'True'
}),
'new_response_count'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'default'
:
'0'
}),
'password'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'128'
}),
'questions_per_page'
:
(
'django.db.models.fields.SmallIntegerField'
,
[],
{
'default'
:
'10'
}),
'real_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
,
'blank'
:
'True'
}),
'reputation'
:
(
'django.db.models.fields.PositiveIntegerField'
,
[],
{
'default'
:
'1'
}),
'seen_response_count'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'default'
:
'0'
}),
'show_country'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'silver'
:
(
'django.db.models.fields.SmallIntegerField'
,
[],
{
'default'
:
'0'
}),
'status'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'w'"
,
'max_length'
:
'2'
}),
'user_permissions'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
"orm['auth.Permission']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
}),
'username'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'30'
}),
'website'
:
(
'django.db.models.fields.URLField'
,
[],
{
'max_length'
:
'200'
,
'blank'
:
'True'
})
},
'contenttypes.contenttype'
:
{
'Meta'
:
{
'ordering'
:
"('name',)"
,
'unique_together'
:
"(('app_label', 'model'),)"
,
'object_name'
:
'ContentType'
,
'db_table'
:
"'django_content_type'"
},
'app_label'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'model'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
})
},
'courseware.studentmodule'
:
{
'Meta'
:
{
'unique_together'
:
"(('course_id', 'student', 'module_state_key'),)"
,
'object_name'
:
'StudentModule'
},
'course_id'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
,
'db_index'
:
'True'
}),
'created'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'db_index'
:
'True'
,
'blank'
:
'True'
}),
'done'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'na'"
,
'max_length'
:
'8'
,
'db_index'
:
'True'
}),
'grade'
:
(
'django.db.models.fields.FloatField'
,
[],
{
'db_index'
:
'True'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'max_grade'
:
(
'django.db.models.fields.FloatField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
'modified'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now'
:
'True'
,
'db_index'
:
'True'
,
'blank'
:
'True'
}),
'module_state_key'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
,
'db_column'
:
"'module_id'"
,
'db_index'
:
'True'
}),
'module_type'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'problem'"
,
'max_length'
:
'32'
,
'db_index'
:
'True'
}),
'state'
:
(
'django.db.models.fields.TextField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
'student'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
})
}
}
complete_apps
=
[
'courseware'
]
lms/djangoapps/courseware/models.py
View file @
f44d794e
...
@@ -22,6 +22,9 @@ from django.contrib.auth.models import User
...
@@ -22,6 +22,9 @@ from django.contrib.auth.models import User
class
StudentModule
(
models
.
Model
):
class
StudentModule
(
models
.
Model
):
"""
Keeps student state for a particular module in a particular course.
"""
# For a homework problem, contains a JSON
# For a homework problem, contains a JSON
# object consisting of state
# object consisting of state
MODULE_TYPES
=
((
'problem'
,
'problem'
),
MODULE_TYPES
=
((
'problem'
,
'problem'
),
...
@@ -37,9 +40,10 @@ class StudentModule(models.Model):
...
@@ -37,9 +40,10 @@ class StudentModule(models.Model):
# Filename for homeworks, etc.
# Filename for homeworks, etc.
module_state_key
=
models
.
CharField
(
max_length
=
255
,
db_index
=
True
,
db_column
=
'module_id'
)
module_state_key
=
models
.
CharField
(
max_length
=
255
,
db_index
=
True
,
db_column
=
'module_id'
)
student
=
models
.
ForeignKey
(
User
,
db_index
=
True
)
student
=
models
.
ForeignKey
(
User
,
db_index
=
True
)
course_id
=
models
.
CharField
(
max_length
=
255
,
db_index
=
True
)
class
Meta
:
class
Meta
:
unique_together
=
((
'student'
,
'module_state_key'
),)
unique_together
=
((
'
course_id'
,
'
student'
,
'module_state_key'
),)
## Internal state of the object
## Internal state of the object
state
=
models
.
TextField
(
null
=
True
,
blank
=
True
)
state
=
models
.
TextField
(
null
=
True
,
blank
=
True
)
...
@@ -57,7 +61,8 @@ class StudentModule(models.Model):
...
@@ -57,7 +61,8 @@ class StudentModule(models.Model):
modified
=
models
.
DateTimeField
(
auto_now
=
True
,
db_index
=
True
)
modified
=
models
.
DateTimeField
(
auto_now
=
True
,
db_index
=
True
)
def
__unicode__
(
self
):
def
__unicode__
(
self
):
return
'/'
.
join
([
self
.
module_type
,
self
.
student
.
username
,
self
.
module_state_key
,
str
(
self
.
state
)[:
20
]])
return
'/'
.
join
([
self
.
course_id
,
self
.
module_type
,
self
.
student
.
username
,
self
.
module_state_key
,
str
(
self
.
state
)[:
20
]])
# TODO (cpennington): Remove these once the LMS switches to using XModuleDescriptors
# TODO (cpennington): Remove these once the LMS switches to using XModuleDescriptors
...
@@ -67,20 +72,20 @@ class StudentModuleCache(object):
...
@@ -67,20 +72,20 @@ class StudentModuleCache(object):
"""
"""
A cache of StudentModules for a specific student
A cache of StudentModules for a specific student
"""
"""
def
__init__
(
self
,
user
,
descriptors
,
select_for_update
=
False
):
def
__init__
(
self
,
course_id
,
user
,
descriptors
,
select_for_update
=
False
):
'''
'''
Find any StudentModule objects that are needed by any descriptor
Find any StudentModule objects that are needed by any descriptor
in descriptors. Avoids making multiple queries to the database.
in descriptors. Avoids making multiple queries to the database.
Note: Only modules that have store_state = True or have shared
Note: Only modules that have store_state = True or have shared
state will have a StudentModule.
state will have a StudentModule.
Arguments
Arguments
user: The user for which to fetch maching StudentModules
user: The user for which to fetch maching StudentModules
descriptors: An array of XModuleDescriptors.
descriptors: An array of XModuleDescriptors.
select_for_update: Flag indicating whether the rows should be locked until end of transaction
select_for_update: Flag indicating whether the rows should be locked until end of transaction
'''
'''
if
user
.
is_authenticated
():
if
user
.
is_authenticated
():
module_ids
=
self
.
_get_module_state_keys
(
descriptors
)
module_ids
=
self
.
_get_module_state_keys
(
descriptors
)
# This works around a limitation in sqlite3 on the number of parameters
# This works around a limitation in sqlite3 on the number of parameters
# that can be put into a single query
# that can be put into a single query
...
@@ -89,78 +94,86 @@ class StudentModuleCache(object):
...
@@ -89,78 +94,86 @@ class StudentModuleCache(object):
for
id_chunk
in
[
module_ids
[
i
:
i
+
chunk_size
]
for
i
in
xrange
(
0
,
len
(
module_ids
),
chunk_size
)]:
for
id_chunk
in
[
module_ids
[
i
:
i
+
chunk_size
]
for
i
in
xrange
(
0
,
len
(
module_ids
),
chunk_size
)]:
if
select_for_update
:
if
select_for_update
:
self
.
cache
.
extend
(
StudentModule
.
objects
.
select_for_update
()
.
filter
(
self
.
cache
.
extend
(
StudentModule
.
objects
.
select_for_update
()
.
filter
(
course_id
=
course_id
,
student
=
user
,
student
=
user
,
module_state_key__in
=
id_chunk
)
module_state_key__in
=
id_chunk
)
)
)
else
:
else
:
self
.
cache
.
extend
(
StudentModule
.
objects
.
filter
(
self
.
cache
.
extend
(
StudentModule
.
objects
.
filter
(
course_id
=
course_id
,
student
=
user
,
student
=
user
,
module_state_key__in
=
id_chunk
)
module_state_key__in
=
id_chunk
)
)
)
else
:
else
:
self
.
cache
=
[]
self
.
cache
=
[]
@classmethod
@classmethod
def
cache_for_descriptor_descendents
(
cls
,
user
,
descriptor
,
depth
=
None
,
descriptor_filter
=
lambda
descriptor
:
True
,
select_for_update
=
False
):
def
cache_for_descriptor_descendents
(
cls
,
course_id
,
user
,
descriptor
,
depth
=
None
,
descriptor_filter
=
lambda
descriptor
:
True
,
select_for_update
=
False
):
"""
"""
course_id: the course in the context of which we want StudentModules.
user: the django user for whom to load modules.
descriptor: An XModuleDescriptor
descriptor: An XModuleDescriptor
depth is the number of levels of descendent modules to load StudentModules for, in addition to
depth is the number of levels of descendent modules to load StudentModules for, in addition to
the supplied descriptor. If depth is None, load all descendent StudentModules
the supplied descriptor. If depth is None, load all descendent StudentModules
descriptor_filter is a function that accepts a descriptor and return wether the StudentModule
descriptor_filter is a function that accepts a descriptor and return wether the StudentModule
should be cached
should be cached
select_for_update: Flag indicating whether the rows should be locked until end of transaction
select_for_update: Flag indicating whether the rows should be locked until end of transaction
"""
"""
def
get_child_descriptors
(
descriptor
,
depth
,
descriptor_filter
):
def
get_child_descriptors
(
descriptor
,
depth
,
descriptor_filter
):
if
descriptor_filter
(
descriptor
):
if
descriptor_filter
(
descriptor
):
descriptors
=
[
descriptor
]
descriptors
=
[
descriptor
]
else
:
else
:
descriptors
=
[]
descriptors
=
[]
if
depth
is
None
or
depth
>
0
:
if
depth
is
None
or
depth
>
0
:
new_depth
=
depth
-
1
if
depth
is
not
None
else
depth
new_depth
=
depth
-
1
if
depth
is
not
None
else
depth
for
child
in
descriptor
.
get_children
():
for
child
in
descriptor
.
get_children
():
descriptors
.
extend
(
get_child_descriptors
(
child
,
new_depth
,
descriptor_filter
))
descriptors
.
extend
(
get_child_descriptors
(
child
,
new_depth
,
descriptor_filter
))
return
descriptors
return
descriptors
descriptors
=
get_child_descriptors
(
descriptor
,
depth
,
descriptor_filter
)
descriptors
=
get_child_descriptors
(
descriptor
,
depth
,
descriptor_filter
)
return
StudentModuleCache
(
user
,
descriptors
,
select_for_update
)
return
StudentModuleCache
(
course_id
,
user
,
descriptors
,
select_for_update
)
def
_get_module_state_keys
(
self
,
descriptors
):
def
_get_module_state_keys
(
self
,
descriptors
):
'''
'''
Get a list of the state_keys needed for StudentModules
Get a list of the state_keys needed for StudentModules
required for this module descriptor
required for this module descriptor
descriptor_filter is a function that accepts a descriptor and return wether the StudentModule
descriptor_filter is a function that accepts a descriptor and return wether the StudentModule
should be cached
should be cached
'''
'''
keys
=
[]
keys
=
[]
for
descriptor
in
descriptors
:
for
descriptor
in
descriptors
:
if
descriptor
.
stores_state
:
if
descriptor
.
stores_state
:
keys
.
append
(
descriptor
.
location
.
url
())
keys
.
append
(
descriptor
.
location
.
url
())
shared_state_key
=
getattr
(
descriptor
,
'shared_state_key'
,
None
)
shared_state_key
=
getattr
(
descriptor
,
'shared_state_key'
,
None
)
if
shared_state_key
is
not
None
:
if
shared_state_key
is
not
None
:
keys
.
append
(
shared_state_key
)
keys
.
append
(
shared_state_key
)
return
keys
return
keys
def
lookup
(
self
,
module_type
,
module_state_key
):
def
lookup
(
self
,
course_id
,
module_type
,
module_state_key
):
'''
'''
Look for a student module with the given
type
and id in the cache.
Look for a student module with the given
course_id, type,
and id in the cache.
cache -- list of student modules
cache -- list of student modules
returns first found object, or None
returns first found object, or None
'''
'''
for
o
in
self
.
cache
:
for
o
in
self
.
cache
:
if
o
.
module_type
==
module_type
and
o
.
module_state_key
==
module_state_key
:
if
(
o
.
course_id
==
course_id
and
o
.
module_type
==
module_type
and
o
.
module_state_key
==
module_state_key
):
return
o
return
o
return
None
return
None
...
...
lms/djangoapps/courseware/module_render.py
View file @
f44d794e
...
@@ -70,7 +70,8 @@ def toc_for_course(user, request, course, active_chapter, active_section, course
...
@@ -70,7 +70,8 @@ def toc_for_course(user, request, course, active_chapter, active_section, course
None if this is not the case.
None if this is not the case.
'''
'''
student_module_cache
=
StudentModuleCache
.
cache_for_descriptor_descendents
(
user
,
course
,
depth
=
2
)
student_module_cache
=
StudentModuleCache
.
cache_for_descriptor_descendents
(
course_id
,
user
,
course
,
depth
=
2
)
course
=
get_module
(
user
,
request
,
course
.
location
,
student_module_cache
,
course_id
)
course
=
get_module
(
user
,
request
,
course
.
location
,
student_module_cache
,
course_id
)
chapters
=
list
()
chapters
=
list
()
...
@@ -159,12 +160,13 @@ def get_module(user, request, location, student_module_cache, course_id, positio
...
@@ -159,12 +160,13 @@ def get_module(user, request, location, student_module_cache, course_id, positio
shared_module
=
None
shared_module
=
None
if
user
.
is_authenticated
():
if
user
.
is_authenticated
():
if
descriptor
.
stores_state
:
if
descriptor
.
stores_state
:
instance_module
=
student_module_cache
.
lookup
(
descriptor
.
category
,
instance_module
=
student_module_cache
.
lookup
(
descriptor
.
location
.
url
())
course_id
,
descriptor
.
category
,
descriptor
.
location
.
url
())
shared_state_key
=
getattr
(
descriptor
,
'shared_state_key'
,
None
)
shared_state_key
=
getattr
(
descriptor
,
'shared_state_key'
,
None
)
if
shared_state_key
is
not
None
:
if
shared_state_key
is
not
None
:
shared_module
=
student_module_cache
.
lookup
(
descriptor
.
category
,
shared_module
=
student_module_cache
.
lookup
(
course_id
,
descriptor
.
category
,
shared_state_key
)
shared_state_key
)
...
@@ -241,7 +243,7 @@ def get_module(user, request, location, student_module_cache, course_id, positio
...
@@ -241,7 +243,7 @@ def get_module(user, request, location, student_module_cache, course_id, positio
return
module
return
module
def
get_instance_module
(
user
,
module
,
student_module_cache
):
def
get_instance_module
(
course_id
,
user
,
module
,
student_module_cache
):
"""
"""
Returns instance_module is a StudentModule specific to this module for this student,
Returns instance_module is a StudentModule specific to this module for this student,
or None if this is an anonymous user
or None if this is an anonymous user
...
@@ -252,11 +254,12 @@ def get_instance_module(user, module, student_module_cache):
...
@@ -252,11 +254,12 @@ def get_instance_module(user, module, student_module_cache):
+
str
(
module
.
id
)
+
" which does not store state."
)
+
str
(
module
.
id
)
+
" which does not store state."
)
return
None
return
None
instance_module
=
student_module_cache
.
lookup
(
module
.
category
,
instance_module
=
student_module_cache
.
lookup
(
module
.
location
.
url
())
course_id
,
module
.
category
,
module
.
location
.
url
())
if
not
instance_module
:
if
not
instance_module
:
instance_module
=
StudentModule
(
instance_module
=
StudentModule
(
course_id
=
course_id
,
student
=
user
,
student
=
user
,
module_type
=
module
.
category
,
module_type
=
module
.
category
,
module_state_key
=
module
.
id
,
module_state_key
=
module
.
id
,
...
@@ -285,6 +288,7 @@ def get_shared_instance_module(course_id, user, module, student_module_cache):
...
@@ -285,6 +288,7 @@ def get_shared_instance_module(course_id, user, module, student_module_cache):
shared_state_key
)
shared_state_key
)
if
not
shared_module
:
if
not
shared_module
:
shared_module
=
StudentModule
(
shared_module
=
StudentModule
(
course_id
=
course_id
,
student
=
user
,
student
=
user
,
module_type
=
descriptor
.
category
,
module_type
=
descriptor
.
category
,
module_state_key
=
shared_state_key
,
module_state_key
=
shared_state_key
,
...
@@ -317,14 +321,14 @@ def xqueue_callback(request, course_id, userid, id, dispatch):
...
@@ -317,14 +321,14 @@ def xqueue_callback(request, course_id, userid, id, dispatch):
# Retrieve target StudentModule
# Retrieve target StudentModule
user
=
User
.
objects
.
get
(
id
=
userid
)
user
=
User
.
objects
.
get
(
id
=
userid
)
student_module_cache
=
StudentModuleCache
.
cache_for_descriptor_descendents
(
student_module_cache
=
StudentModuleCache
.
cache_for_descriptor_descendents
(
course_id
,
user
,
modulestore
()
.
get_instance
(
course_id
,
id
),
depth
=
0
,
select_for_update
=
True
)
user
,
modulestore
()
.
get_instance
(
course_id
,
id
),
depth
=
0
,
select_for_update
=
True
)
instance
=
get_module
(
user
,
request
,
id
,
student_module_cache
,
course_id
)
instance
=
get_module
(
user
,
request
,
id
,
student_module_cache
,
course_id
)
if
instance
is
None
:
if
instance
is
None
:
log
.
debug
(
"No module {0} for user {1}--access denied?"
.
format
(
id
,
user
))
log
.
debug
(
"No module {0} for user {1}--access denied?"
.
format
(
id
,
user
))
raise
Http404
raise
Http404
instance_module
=
get_instance_module
(
user
,
instance
,
student_module_cache
)
instance_module
=
get_instance_module
(
course_id
,
user
,
instance
,
student_module_cache
)
if
instance_module
is
None
:
if
instance_module
is
None
:
log
.
debug
(
"Couldn't find instance of module '
%
s' for user '
%
s'"
,
id
,
user
)
log
.
debug
(
"Couldn't find instance of module '
%
s' for user '
%
s'"
,
id
,
user
)
...
@@ -387,7 +391,7 @@ def modx_dispatch(request, dispatch, location, course_id):
...
@@ -387,7 +391,7 @@ def modx_dispatch(request, dispatch, location, course_id):
return
HttpResponse
(
json
.
dumps
({
'success'
:
file_too_big_msg
}))
return
HttpResponse
(
json
.
dumps
({
'success'
:
file_too_big_msg
}))
p
[
fileinput_id
]
=
inputfiles
p
[
fileinput_id
]
=
inputfiles
student_module_cache
=
StudentModuleCache
.
cache_for_descriptor_descendents
(
student_module_cache
=
StudentModuleCache
.
cache_for_descriptor_descendents
(
course_id
,
request
.
user
,
modulestore
()
.
get_instance
(
course_id
,
location
))
request
.
user
,
modulestore
()
.
get_instance
(
course_id
,
location
))
instance
=
get_module
(
request
.
user
,
request
,
location
,
student_module_cache
,
course_id
)
instance
=
get_module
(
request
.
user
,
request
,
location
,
student_module_cache
,
course_id
)
...
@@ -397,7 +401,7 @@ def modx_dispatch(request, dispatch, location, course_id):
...
@@ -397,7 +401,7 @@ def modx_dispatch(request, dispatch, location, course_id):
log
.
debug
(
"No module {0} for user {1}--access denied?"
.
format
(
location
,
user
))
log
.
debug
(
"No module {0} for user {1}--access denied?"
.
format
(
location
,
user
))
raise
Http404
raise
Http404
instance_module
=
get_instance_module
(
request
.
user
,
instance
,
student_module_cache
)
instance_module
=
get_instance_module
(
course_id
,
request
.
user
,
instance
,
student_module_cache
)
shared_module
=
get_shared_instance_module
(
course_id
,
request
.
user
,
instance
,
student_module_cache
)
shared_module
=
get_shared_instance_module
(
course_id
,
request
.
user
,
instance
,
student_module_cache
)
# Don't track state for anonymous users (who don't have student modules)
# Don't track state for anonymous users (who don't have student modules)
...
...
lms/djangoapps/courseware/views.py
View file @
f44d794e
...
@@ -149,8 +149,7 @@ def index(request, course_id, chapter=None, section=None,
...
@@ -149,8 +149,7 @@ def index(request, course_id, chapter=None, section=None,
section_descriptor
=
get_section
(
course
,
chapter
,
section
)
section_descriptor
=
get_section
(
course
,
chapter
,
section
)
if
section_descriptor
is
not
None
:
if
section_descriptor
is
not
None
:
student_module_cache
=
StudentModuleCache
.
cache_for_descriptor_descendents
(
student_module_cache
=
StudentModuleCache
.
cache_for_descriptor_descendents
(
request
.
user
,
course_id
,
request
.
user
,
section_descriptor
)
section_descriptor
)
module
=
get_module
(
request
.
user
,
request
,
module
=
get_module
(
request
.
user
,
request
,
section_descriptor
.
location
,
section_descriptor
.
location
,
student_module_cache
,
course_id
)
student_module_cache
,
course_id
)
...
@@ -310,7 +309,8 @@ def progress(request, course_id, student_id=None):
...
@@ -310,7 +309,8 @@ def progress(request, course_id, student_id=None):
raise
Http404
raise
Http404
student
=
User
.
objects
.
get
(
id
=
int
(
student_id
))
student
=
User
.
objects
.
get
(
id
=
int
(
student_id
))
student_module_cache
=
StudentModuleCache
.
cache_for_descriptor_descendents
(
request
.
user
,
course
)
student_module_cache
=
StudentModuleCache
.
cache_for_descriptor_descendents
(
course_id
,
request
.
user
,
course
)
course_module
=
get_module
(
request
.
user
,
request
,
course
.
location
,
course_module
=
get_module
(
request
.
user
,
request
,
course
.
location
,
student_module_cache
,
course_id
)
student_module_cache
,
course_id
)
...
...
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