openedx / openedx/openedx-core
Store XBlock field data in a new model
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 10
- Forks
- 32
- Avg merge
- 2d 17h
- Merged PRs (30d)
- 12
Description
Background
The v2 content libraries use the LearningCoreXBlockRuntime. This runtime uses Learning Core data models underneath. Every version of an XBlock component (e.g. a ProblemBlock) is represented using a ComponentVersion. The field data is stored in the ComponentVersion's contents, as a text Content named block.xml, which holds the OLX for that block.
We do want to keep the block.xml file around, because it's the thing we're going to export when the XBlock gets deprecated and goes away twelve years from now. But relying on this causes some issues:
- There are situations where XBlocks want data from multiple source files.
TheHTMLBlockis kinda hacked to use CDATA for libraries right now, but it usually defines an HTML file in Modulestore. Looking forward more, it would be nice if we could modify ProblemBlock to keep Python source files separate from the XML, but still read them in for the purposes of the XBlock rendering in an optimized way that just did one select instead of each XBlock making n-queries for all the pieces it needs. - XML is slower to parse, search, and read.
This will be particularly important when we start shimming a layer between Learning Core and ModuleStore, for the long term porting of courses to Learning Core.
Acceptance Criteria
- Create a new model to store XBlock field data.
- Have the LearningCoreXBlockRuntime write to that new model, based on the OLX in block.xml.
- Have the LearningCoreXBlockRuntime read from that new model for the purposes of XBlock rendering.
- (Optional) Create a data migration to bootstrap existing content and write it into the new model.
Implementation Thoughts
This is just a first stab at things. Please feel free to discuss and amend this as we learn more.
- The new model should be created in edx-platform's openedx.core.djangoapps.xblock app.
This is a representation that's specific to the runtime, so it makes sense to create the model in the same app. - This new model should be made 1:1 with PublishableEntityVersion.
PublishableEntityVersionis more generic thanComponentVersion, which will allow us to attach XBlock field data to other models in the future (like Units). - We often make publishable models in pairs and register them: one for the entity, another for versions, e.g. Component and ComponentVersion. But since we're only hanging some extra data off of the
PublishableEntityVersion, I don't think we need to do that in this case, and you can just inherit from PublishableEntityVersionMixin PublishableEntityVersionsare intended to be immutable, and this model would be the same way.
It could look something like:
from django.db.models import JSONField
from openedx_learning.api.authoring_models import PublishableEntityVersionMixin
class XBlockVersionFieldData(PublishableEntityVersionMixin):
content = JSONField()
settings = JSONField()
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with openedx/core/djangoapps/xblock/runtime/learning_core_runtime.py, then read PublishableEntityVersionMixin and PublishableEntityVersion in the referenced openedx-learning models. Done means the xblock app has a field-data model, LearningCoreXBlockRuntime writes data from block.xml and reads it for rendering, with an optional migration for existing content.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- django, python
- Domain
- backend, database
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100