fix: [FC-0092] fix 500 when return_type is list (#36969)

There was problem in filter_discussion_xblocks_from_response(). This
function was breaking the list response for the BlocksInCourseView by
returning a dict instead of list.
This commit is contained in:
Kyrylo Kireiev
2025-09-09 21:35:09 +03:00
committed by GitHub
parent cb7f0f4811
commit 7f885c79f7
2 changed files with 51 additions and 41 deletions

View File

@@ -11,47 +11,55 @@ from openedx.core.djangoapps.discussions.models import (
def filter_discussion_xblocks_from_response(response, course_key):
"""
Removes discussion xblocks if discussion provider is openedx
Removes discussion xblocks if discussion provider is openedx.
"""
configuration = DiscussionsConfiguration.get(context_key=course_key)
provider = configuration.provider_type
if provider == Provider.OPEN_EDX:
# Finding ids of discussion xblocks
if isinstance(response.data, ReturnList):
discussion_xblocks = [
value.get('id') for value in response.data if value.get('type') == 'discussion'
]
else:
discussion_xblocks = [
key for key, value in response.data.get('blocks', {}).items()
if value.get('type') == 'discussion'
]
# Filtering discussion xblocks keys from blocks
if isinstance(response.data, ReturnList):
filtered_blocks = {
value.get('id'): value
for value in response.data
if value.get('type') != 'discussion'
}
else:
filtered_blocks = {
key: value
for key, value in response.data.get('blocks', {}).items()
if value.get('type') != 'discussion'
}
# Removing reference of discussion xblocks from unit
# These references needs to be removed because they no longer exist
for _, block_data in filtered_blocks.items():
for key in ['descendants', 'children']:
descendants = block_data.get(key, [])
if descendants:
descendants = [
descendant for descendant in descendants
if descendant not in discussion_xblocks
]
block_data[key] = descendants
if isinstance(response.data, ReturnList):
response.data = filtered_blocks
else:
response.data['blocks'] = filtered_blocks
if provider != Provider.OPEN_EDX:
return response
is_list_response = isinstance(response.data, ReturnList)
# Find discussion xblock IDs
if is_list_response:
discussion_xblocks = [
block.get('id') for block in response.data
if block.get('type') == 'discussion'
]
else:
discussion_xblocks = [
key for key, value in response.data.get('blocks', {}).items()
if value.get('type') == 'discussion'
]
# Filter out discussion blocks
if is_list_response:
filtered_blocks = [
block for block in response.data
if block.get('type') != 'discussion'
]
else:
filtered_blocks = {
key: value for key, value in response.data.get('blocks', {}).items()
if value.get('type') != 'discussion'
}
# Remove references to discussion xblocks
# These references needs to be removed because they no longer exist
blocks_iterable = filtered_blocks if is_list_response else filtered_blocks.values()
for block_data in blocks_iterable:
for key in ['descendants', 'children']:
if key in block_data:
block_data[key] = [
descendant for descendant in block_data[key]
if descendant not in discussion_xblocks
]
# Update response
if is_list_response:
response.data = ReturnList(filtered_blocks, serializer=None)
else:
response.data['blocks'] = filtered_blocks
return response

View File

@@ -330,12 +330,14 @@ class BlocksInCourseView(BlocksView):
if course_block.get('type') == 'course':
root = course_block['id']
else:
root = str(course_usage_key)
else:
root = response.data['root']
course_blocks = response.data['blocks']
if not root:
raise ValueError(f"Unable to find course block in {course_key_string}")
raise ValidationError(f"Unable to find course block in '{course_key_string}'")
recurse_mark_complete(root, course_blocks)
return response