Skip to content

Commit

Permalink
feat: clean up field data loading
Browse files Browse the repository at this point in the history
  • Loading branch information
bradenmacdonald committed Jun 1, 2024
1 parent a0cceb1 commit fe71266
Showing 1 changed file with 29 additions and 13 deletions.
42 changes: 29 additions & 13 deletions lms/djangoapps/courseware/unit_render.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@
from opaque_keys.edx.keys import UsageKey
from rest_framework.decorators import api_view
from rest_framework.exceptions import ValidationError
from xblock.fields import Scope
from xblock.core import XBlock2

from lms.djangoapps.course_blocks.api import get_course_blocks
from lms.djangoapps.courseware.models import StudentModule
from lms.djangoapps.courseware.models import StudentModule, XModuleUserStateSummaryField
from openedx.core.lib.api.view_utils import view_auth_classes
from common.djangoapps.util.json_request import JsonResponse
from xmodule.modulestore import ModuleStoreEnum
Expand Down Expand Up @@ -76,12 +77,13 @@ def add_field(field_name, value):
field = block_class.fields.get(field_name)
if field: # TODO: and not field.private
block_data_out["content_fields"][field_name] = field.to_json(value)
else:
for mixin in store.xblock_mixins:
field = mixin.fields.get(field_name)
if field:
block_data_out["system_fields"][field_name] = field.to_json(value)
return
# Do we even need to share these "system fields" with the frontend? probably not...
# else:
# for mixin in store.xblock_mixins:
# field = mixin.fields.get(field_name)
# if field:
# block_data_out["system_fields"][field_name] = field.to_json(value)
# return

# We cannot get ALL of the field data from the block transfomers API(s), because they only support a
# small subset of fields defined in course_api.blocks.serializers.SUPPORTED_FIELDS. However, all the
Expand All @@ -92,7 +94,7 @@ def add_field(field_name, value):
# and "category" will be silently dropped here since they're in the block transformer data but
# they aren't actual XBlock fields. (Except lti_block.has_score which is actually a field.)

# TODO: load additional fields from split modulestore if needed.
# Load additional fields from split modulestore if needed.
block_data = store._get_block_from_structure(
structure_data.structure,
BlockKey.from_usage_key(usage_key),
Expand All @@ -103,11 +105,25 @@ def add_field(field_name, value):

# Get the user-specific field data:
sm = next((sm for sm in student_modules if sm.module_state_key == usage_key), None)
if sm:
for field_name, value in json.loads(sm.state).items():
field = block_class.fields.get(field_name)
if field: # TODO: and not field.private
block_data_out["user_fields"][field_name] = value # value is already in JSON format
user_state_data = json.loads(sm.state) if sm else {}

for field_name, field in block_class.fields.items():
if field.scope == Scope.user_state:
if field_name in user_state_data:
# Note: this value is already in a JSON-compatible format
block_data_out["user_fields"][field_name] = user_state_data[field_name]
else:
block_data_out["user_fields"][field_name] = field.to_json(field.default)
elif field.scope == Scope.user_state_summary:
try:
uss = XModuleUserStateSummaryField.objects.get(
usage_id=usage_key,
field_name=field_name,
)
block_data_out["user_fields"][field_name] = json.loads(uss.value)
except XModuleUserStateSummaryField.DoesNotExist:
block_data_out["user_fields"][field_name] = field.to_json(field.default)

else:
block_data_out["xblock_api_version"] = 1
block_data_out["embed_uri"] = request.build_absolute_uri(
Expand Down

0 comments on commit fe71266

Please sign in to comment.