Skip to content

Commit 2179109

Browse files
authored
Merge branch 'master' into arslan/fix-validation-api
2 parents b9d6a8c + ec1d959 commit 2179109

84 files changed

Lines changed: 1187 additions & 782 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

cms/djangoapps/contentstore/exams.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,13 @@ def register_exams(course_key):
7474
# Exams in courses not using an LTI based proctoring provider should use the original definition of due_date
7575
# from contentstore/proctoring.py. These exams are powered by the edx-proctoring plugin and not the edx-exams
7676
# microservice.
77+
is_instructor_paced = not course.self_paced
7778
if course.proctoring_provider == 'lti_external':
78-
due_date = (
79-
timed_exam.due.isoformat() if timed_exam.due
80-
else (course.end.isoformat() if course.end else None)
81-
)
79+
due_date_source = timed_exam.due if is_instructor_paced else course.end
8280
else:
83-
due_date = timed_exam.due if not course.self_paced else None
81+
due_date_source = timed_exam.due if is_instructor_paced else None
82+
83+
due_date = due_date_source.isoformat() if due_date_source else None
8484

8585
exams_list.append({
8686
'course_id': str(course_key),

cms/djangoapps/contentstore/helpers.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,7 @@ def _import_xml_node_to_parent(
529529
node_copied_version = node.attrib.get('copied_from_version', None)
530530

531531
# Modulestore's IdGenerator here is SplitMongoIdManager which is assigned
532-
# by CachingDescriptorSystem Runtime and since we need our custom ImportIdGenerator
532+
# by SplitModuleStoreRuntime and since we need our custom ImportIdGenerator
533533
# here we are temporaraliy swtiching it.
534534
original_id_generator = runtime.id_generator
535535

@@ -566,7 +566,8 @@ def _import_xml_node_to_parent(
566566
else:
567567
# We have to handle the children ourselves, because there are lots of complex interactions between
568568
# * the vanilla XBlock parse_xml() method, and its lack of API for "create and save a new XBlock"
569-
# * the XmlMixin version of parse_xml() which only works with ImportSystem, not modulestore or the v2 runtime
569+
# * the XmlMixin version of parse_xml() which only works with XMLImportingModuleStoreRuntime,
570+
# not modulestore or the v2 runtime
570571
# * the modulestore APIs for creating and saving a new XBlock, which work but don't support XML parsing.
571572
# We can safely assume that if the XBLock class supports children, every child node will be the XML
572573
# serialization of a child block, in order. For blocks that don't support children, their XML content/nodes
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Generated by Django 5.2.7 on 2025-10-27 14:07
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('contentstore', '0013_componentlink_downstream_is_modified_and_more'),
10+
]
11+
12+
operations = [
13+
migrations.RemoveField(
14+
model_name='componentlink',
15+
name='downstream_is_modified',
16+
),
17+
migrations.RemoveField(
18+
model_name='containerlink',
19+
name='downstream_is_modified',
20+
),
21+
migrations.AddField(
22+
model_name='componentlink',
23+
name='downstream_customized',
24+
field=models.JSONField(
25+
default=list,
26+
help_text=(
27+
'Names of the fields which have values set on the upstream block yet have been explicitly'
28+
' overridden on this downstream block'
29+
),
30+
),
31+
),
32+
migrations.AddField(
33+
model_name='containerlink',
34+
name='downstream_customized',
35+
field=models.JSONField(
36+
default=list,
37+
help_text=(
38+
'Names of the fields which have values set on the upstream block yet have been explicitly'
39+
' overridden on this downstream block'
40+
),
41+
),
42+
),
43+
]

cms/djangoapps/contentstore/models.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,13 @@ class EntityLinkBase(models.Model):
108108
top_level_parent = models.ForeignKey("ContainerLink", on_delete=models.SET_NULL, null=True, blank=True)
109109
version_synced = models.IntegerField()
110110
version_declined = models.IntegerField(null=True, blank=True)
111-
downstream_is_modified = models.BooleanField(default=False)
111+
downstream_customized = models.JSONField(
112+
default=list,
113+
help_text=(
114+
'Names of the fields which have values set on the upstream block yet have been explicitly'
115+
' overridden on this downstream block'
116+
),
117+
)
112118
created = manual_date_time_field()
113119
updated = manual_date_time_field()
114120

@@ -258,7 +264,7 @@ def update_or_create(
258264
version_synced: int,
259265
top_level_parent_usage_key: UsageKey | None = None,
260266
version_declined: int | None = None,
261-
downstream_is_modified: bool = False,
267+
downstream_customized: list[str] | None = None,
262268
created: datetime | None = None,
263269
) -> "ComponentLink":
264270
"""
@@ -283,7 +289,7 @@ def update_or_create(
283289
'version_synced': version_synced,
284290
'version_declined': version_declined,
285291
'top_level_parent': top_level_parent,
286-
'downstream_is_modified': downstream_is_modified,
292+
'downstream_customized': downstream_customized,
287293
}
288294
if upstream_block:
289295
new_values['upstream_block'] = upstream_block
@@ -485,7 +491,7 @@ def update_or_create(
485491
version_synced: int,
486492
top_level_parent_usage_key: UsageKey | None = None,
487493
version_declined: int | None = None,
488-
downstream_is_modified: bool = False,
494+
downstream_customized: list[str] | None = None,
489495
created: datetime | None = None,
490496
) -> "ContainerLink":
491497
"""
@@ -510,7 +516,7 @@ def update_or_create(
510516
'version_synced': version_synced,
511517
'version_declined': version_declined,
512518
'top_level_parent': top_level_parent,
513-
'downstream_is_modified': downstream_is_modified,
519+
'downstream_customized': downstream_customized,
514520
}
515521
if upstream_container_id:
516522
new_values['upstream_container_id'] = upstream_container_id

cms/djangoapps/contentstore/rest_api/v1/serializers/vertical_block.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ class UpstreamLinkSerializer(serializers.Serializer):
124124
version_declined = serializers.IntegerField(allow_null=True)
125125
error_message = serializers.CharField(allow_null=True)
126126
ready_to_sync = serializers.BooleanField()
127-
is_modified = serializers.BooleanField()
127+
downstream_customized = serializers.ListField(child=serializers.CharField(), allow_empty=True)
128128
has_top_level_parent = serializers.BooleanField()
129129
ready_to_sync_children = UpstreamChildrenInfoSerializer(many=True, required=False)
130130

@@ -185,7 +185,7 @@ class UpstreamReadyToSyncChildrenInfoSerializer(serializers.Serializer):
185185
name = serializers.CharField()
186186
upstream = serializers.CharField()
187187
block_type = serializers.CharField()
188-
is_modified = serializers.BooleanField()
188+
downstream_customized = serializers.ListField(child=serializers.CharField(), allow_empty=True)
189189

190190
children = ContainerChildSerializer(many=True)
191191
is_published = serializers.BooleanField()

cms/djangoapps/contentstore/rest_api/v1/views/course_index.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ def get(self, request: Request, usage_key_string: str):
242242
"name": "Text",
243243
"upstream": "lb:org:mylib:html:abcd",
244244
'block_type': "html",
245-
'is_modified': true,
245+
'downstream_customized': ["display_name"],
246246
'id': "block-v1:org+101+101+type@html+block@3e3fa1f88adb4a108cd14e9002143690",
247247
}]
248248
}

cms/djangoapps/contentstore/rest_api/v1/views/tests/test_vertical_block.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ def test_success_response_with_upstream_info(self):
248248
"id": str(self.html_unit_second.usage_key),
249249
"upstream": self.html_block["id"],
250250
"block_type": "html",
251-
"is_modified": False,
251+
"downstream_customized": [],
252252
"name": "Html Content 2",
253253
}])
254254

@@ -324,7 +324,7 @@ def test_children_content(self):
324324
"error_message": None,
325325
"ready_to_sync": True,
326326
"has_top_level_parent": False,
327-
"is_modified": False,
327+
"downstream_customized": [],
328328
},
329329
"user_partition_info": expected_user_partition_info,
330330
"user_partitions": expected_user_partitions,

0 commit comments

Comments
 (0)