Merge PR #27343 bd03/api/legacy

* Commits:
  docs: Remove completed TODO discussions item
  feat: Add support to Discussions API for legacy cohort settings
  refactor: Remove get_course_discussion_settings helper
  refactor: Remove set_course_discussion_settings helper
  refactor: Add better DRF support to legacy discussions settings
This commit is contained in:
stvn
2021-04-30 12:33:13 -07:00
18 changed files with 240 additions and 230 deletions

View File

@@ -47,7 +47,6 @@ from openedx.core.djangoapps.django_comment_common.models import (
from openedx.core.djangoapps.django_comment_common.utils import (
ThreadContext,
seed_permissions_roles,
set_course_discussion_settings
)
from openedx.core.djangoapps.waffle_utils.testutils import WAFFLE_TABLES
from openedx.core.lib.teams_config import TeamsConfig
@@ -1425,13 +1424,13 @@ class TeamsPermissionsTestCase(ForumsEnableMixin, UrlResetMixin, SharedModuleSto
If dividing by cohorts, create and assign users to a cohort.
"""
enable_cohorts = True if scheme is CourseDiscussionSettings.COHORT else False
set_course_discussion_settings(
self.course.id,
enable_cohorts=enable_cohorts,
divided_discussions=[],
always_divide_inline_discussions=True,
division_scheme=scheme,
)
discussion_settings = CourseDiscussionSettings.get(self.course.id)
discussion_settings.update({
'enable_cohorts': enable_cohorts,
'divided_discussions': [],
'always_divide_inline_discussions': True,
'division_scheme': scheme,
})
set_course_cohorted(self.course.id, enable_cohorts)
@classmethod

View File

@@ -14,7 +14,6 @@ from openedx.core.djangoapps.django_comment_common.models import (
CourseDiscussionSettings,
all_permissions_for_user_in_course
)
from openedx.core.djangoapps.django_comment_common.utils import get_course_discussion_settings
from openedx.core.lib.cache_utils import request_cached
@@ -145,7 +144,7 @@ def _check_conditions_permissions(user, permissions, course_id, content, user_gr
# or a course has divided discussions, but the current user's content group does not equal
# the content group of the commenter/poster,
# then the current user does not have group edit permissions.
division_scheme = get_course_discussion_settings(course_id).division_scheme
division_scheme = CourseDiscussionSettings.get(course_id).division_scheme
if (division_scheme is CourseDiscussionSettings.NONE
or user_group_id is None
or content_user_group is None

View File

@@ -8,7 +8,6 @@ from common.djangoapps.course_modes.models import CourseMode
from common.djangoapps.course_modes.tests.factories import CourseModeFactory
from lms.djangoapps.teams.tests.factories import CourseTeamFactory
from openedx.core.djangoapps.django_comment_common.models import CourseDiscussionSettings
from openedx.core.djangoapps.django_comment_common.utils import set_course_discussion_settings
class GroupIdAssertionMixin:
@@ -108,12 +107,12 @@ class CohortedTopicGroupIdTestMixin(GroupIdAssertionMixin):
def test_cohorted_topic_enrollment_track_invalid_group_id(self, mock_request):
CourseModeFactory.create(course_id=self.course.id, mode_slug=CourseMode.AUDIT)
CourseModeFactory.create(course_id=self.course.id, mode_slug=CourseMode.VERIFIED)
set_course_discussion_settings(
course_key=self.course.id,
divided_discussions=['cohorted_topic'],
division_scheme=CourseDiscussionSettings.ENROLLMENT_TRACK,
always_divide_inline_discussions=True,
)
discussion_settings = CourseDiscussionSettings.get(self.course.id)
discussion_settings.update({
'divided_discussions': ['cohorted_topic'],
'division_scheme': CourseDiscussionSettings.ENROLLMENT_TRACK,
'always_divide_inline_discussions': True,
})
invalid_id = -1000
response = self.call_view(mock_request, "cohorted_topic", self.moderator, invalid_id) # lint-amnesty, pylint: disable=assignment-from-no-return

View File

@@ -39,11 +39,7 @@ from openedx.core.djangoapps.django_comment_common.models import (
ForumsConfig,
assign_role
)
from openedx.core.djangoapps.django_comment_common.utils import (
get_course_discussion_settings,
seed_permissions_roles,
set_course_discussion_settings
)
from openedx.core.djangoapps.django_comment_common.utils import seed_permissions_roles
from openedx.core.djangoapps.util.testing import ContentGroupTestCase
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.django import modulestore
@@ -1387,7 +1383,7 @@ class GroupIdForUserTestCase(ModuleStoreTestCase):
)
def test_discussion_division_disabled(self):
course_discussion_settings = get_course_discussion_settings(self.course.id)
course_discussion_settings = CourseDiscussionSettings.get(self.course.id)
assert CourseDiscussionSettings.NONE == course_discussion_settings.division_scheme
assert utils.get_group_id_for_user(self.test_user, course_discussion_settings) is None
@@ -1395,7 +1391,7 @@ class GroupIdForUserTestCase(ModuleStoreTestCase):
set_discussion_division_settings(
self.course.id, enable_cohorts=True, division_scheme=CourseDiscussionSettings.COHORT
)
course_discussion_settings = get_course_discussion_settings(self.course.id)
course_discussion_settings = CourseDiscussionSettings.get(self.course.id)
assert CourseDiscussionSettings.COHORT == course_discussion_settings.division_scheme
assert self.test_cohort.id == utils.get_group_id_for_user(self.test_user, course_discussion_settings)
@@ -1403,7 +1399,7 @@ class GroupIdForUserTestCase(ModuleStoreTestCase):
set_discussion_division_settings(
self.course.id, division_scheme=CourseDiscussionSettings.ENROLLMENT_TRACK
)
course_discussion_settings = get_course_discussion_settings(self.course.id)
course_discussion_settings = CourseDiscussionSettings.get(self.course.id)
assert CourseDiscussionSettings.ENROLLMENT_TRACK == course_discussion_settings.division_scheme
assert (- 2) == utils.get_group_id_for_user(self.test_user, course_discussion_settings)
@@ -1422,7 +1418,7 @@ class CourseDiscussionDivisionEnabledTestCase(ModuleStoreTestCase):
)
def test_discussion_division_disabled(self):
course_discussion_settings = get_course_discussion_settings(self.course.id)
course_discussion_settings = CourseDiscussionSettings.get(self.course.id)
assert not utils.course_discussion_division_enabled(course_discussion_settings)
assert [] == utils.available_division_schemes(self.course.id)
@@ -1431,13 +1427,13 @@ class CourseDiscussionDivisionEnabledTestCase(ModuleStoreTestCase):
self.course.id, enable_cohorts=False, division_scheme=CourseDiscussionSettings.COHORT
)
# Because cohorts are disabled, discussion division is not enabled.
assert not utils.course_discussion_division_enabled(get_course_discussion_settings(self.course.id))
assert not utils.course_discussion_division_enabled(CourseDiscussionSettings.get(self.course.id))
assert [] == utils.available_division_schemes(self.course.id)
# Now enable cohorts, which will cause discussions to be divided.
set_discussion_division_settings(
self.course.id, enable_cohorts=True, division_scheme=CourseDiscussionSettings.COHORT
)
assert utils.course_discussion_division_enabled(get_course_discussion_settings(self.course.id))
assert utils.course_discussion_division_enabled(CourseDiscussionSettings.get(self.course.id))
assert [CourseDiscussionSettings.COHORT] == utils.available_division_schemes(self.course.id)
def test_discussion_division_by_enrollment_track(self):
@@ -1445,12 +1441,12 @@ class CourseDiscussionDivisionEnabledTestCase(ModuleStoreTestCase):
self.course.id, division_scheme=CourseDiscussionSettings.ENROLLMENT_TRACK
)
# Only a single enrollment track exists, so discussion division is not enabled.
assert not utils.course_discussion_division_enabled(get_course_discussion_settings(self.course.id))
assert not utils.course_discussion_division_enabled(CourseDiscussionSettings.get(self.course.id))
assert [] == utils.available_division_schemes(self.course.id)
# Now create a second CourseMode, which will cause discussions to be divided.
CourseModeFactory.create(course_id=self.course.id, mode_slug=CourseMode.VERIFIED)
assert utils.course_discussion_division_enabled(get_course_discussion_settings(self.course.id))
assert utils.course_discussion_division_enabled(CourseDiscussionSettings.get(self.course.id))
assert [CourseDiscussionSettings.ENROLLMENT_TRACK] == utils.available_division_schemes(self.course.id)
@@ -1474,7 +1470,7 @@ class GroupNameTestCase(ModuleStoreTestCase):
)
def test_discussion_division_disabled(self):
course_discussion_settings = get_course_discussion_settings(self.course.id)
course_discussion_settings = CourseDiscussionSettings.get(self.course.id)
assert {} == utils.get_group_names_by_id(course_discussion_settings)
assert utils.get_group_name((- 1000), course_discussion_settings) is None
@@ -1482,7 +1478,7 @@ class GroupNameTestCase(ModuleStoreTestCase):
set_discussion_division_settings(
self.course.id, enable_cohorts=True, division_scheme=CourseDiscussionSettings.COHORT
)
course_discussion_settings = get_course_discussion_settings(self.course.id)
course_discussion_settings = CourseDiscussionSettings.get(self.course.id)
assert {self.test_cohort_1.id: self.test_cohort_1.name, self.test_cohort_2.id: self.test_cohort_2.name} == utils.get_group_names_by_id(course_discussion_settings)
assert self.test_cohort_2.name == utils.get_group_name(self.test_cohort_2.id, course_discussion_settings)
# Test also with a group_id that doesn't exist.
@@ -1492,7 +1488,7 @@ class GroupNameTestCase(ModuleStoreTestCase):
set_discussion_division_settings(
self.course.id, division_scheme=CourseDiscussionSettings.ENROLLMENT_TRACK
)
course_discussion_settings = get_course_discussion_settings(self.course.id)
course_discussion_settings = CourseDiscussionSettings.get(self.course.id)
assert {(- 1): 'audit course', (- 2): 'verified course'} == utils.get_group_names_by_id(course_discussion_settings)
assert 'verified course' == utils.get_group_name((- 2), course_discussion_settings)
@@ -1697,12 +1693,12 @@ def set_discussion_division_settings(
COHORT is the default division_scheme, as no other schemes were supported at
the time that the unit tests were originally written.
"""
set_course_discussion_settings(
course_key=course_key,
divided_discussions=divided_discussions,
division_scheme=division_scheme,
always_divide_inline_discussions=always_divide_inline_discussions,
)
discussion_settings = CourseDiscussionSettings.get(course_key)
discussion_settings.update({
'divided_discussions': divided_discussions,
'division_scheme': division_scheme,
'always_divide_inline_discussions': always_divide_inline_discussions,
})
set_course_cohorted(course_key, enable_cohorts)

View File

@@ -8,12 +8,9 @@ from unittest.mock import patch
from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory
from common.djangoapps.util.testing import UrlResetMixin
from openedx.core.djangoapps.course_groups.tests.helpers import CohortFactory
from openedx.core.djangoapps.django_comment_common.models import CourseDiscussionSettings
from openedx.core.djangoapps.django_comment_common.models import ForumsConfig, Role
from openedx.core.djangoapps.django_comment_common.utils import (
CourseDiscussionSettings,
seed_permissions_roles,
set_course_discussion_settings
)
from openedx.core.djangoapps.django_comment_common.utils import seed_permissions_roles
from openedx.core.lib.teams_config import TeamsConfig
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.django import modulestore
@@ -108,12 +105,15 @@ def config_course_discussions(
"""Convert name to id."""
return topic_name_to_id(course, name)
set_course_discussion_settings(
course.id,
divided_discussions=[to_id(name) for name in divided_discussions],
always_divide_inline_discussions=always_divide_inline_discussions,
division_scheme=CourseDiscussionSettings.COHORT,
)
discussion_settings = CourseDiscussionSettings.get(course.id)
discussion_settings.update({
'divided_discussions': [
to_id(name)
for name in divided_discussions
],
'always_divide_inline_discussions': always_divide_inline_discussions,
'division_scheme': CourseDiscussionSettings.COHORT,
})
course.discussion_topics = {name: {"sort_key": "A", "id": to_id(name)}
for name in discussion_topics}

View File

@@ -33,7 +33,6 @@ from openedx.core.djangoapps.django_comment_common.models import (
DiscussionsIdMapping,
Role
)
from openedx.core.djangoapps.django_comment_common.utils import get_course_discussion_settings
from openedx.core.lib.cache_utils import request_cached
from openedx.core.lib.courses import get_course_by_id
from xmodule.modulestore.django import modulestore
@@ -358,7 +357,7 @@ def get_discussion_category_map(course, user, divided_only_if_explicit=False, ex
xblocks = get_accessible_discussion_xblocks(course, user)
discussion_settings = get_course_discussion_settings(course.id)
discussion_settings = CourseDiscussionSettings.get(course.id)
discussion_division_enabled = course_discussion_division_enabled(discussion_settings)
divided_discussion_ids = discussion_settings.divided_discussions
@@ -797,7 +796,7 @@ def prepare_content(content, course_key, is_staff=False, discussion_division_ena
del endorsement["user_id"]
if discussion_division_enabled is None:
discussion_division_enabled = course_discussion_division_enabled(get_course_discussion_settings(course_key))
discussion_division_enabled = course_discussion_division_enabled(CourseDiscussionSettings.get(course_key))
for child_content_key in ["children", "endorsed_responses", "non_endorsed_responses"]:
if child_content_key in content:
@@ -816,7 +815,7 @@ def prepare_content(content, course_key, is_staff=False, discussion_division_ena
if discussion_division_enabled:
# Augment the specified thread info to include the group name if a group id is present.
if content.get('group_id') is not None:
course_discussion_settings = get_course_discussion_settings(course_key)
course_discussion_settings = CourseDiscussionSettings.get(course_key)
if group_names_by_id:
content['group_name'] = group_names_by_id.get(content.get('group_id'))
else:
@@ -843,7 +842,7 @@ def get_group_id_for_comments_service(request, course_key, commentable_id=None):
Raises:
ValueError if the requested group_id is invalid
"""
course_discussion_settings = get_course_discussion_settings(course_key)
course_discussion_settings = CourseDiscussionSettings.get(course_key)
if commentable_id is None or is_commentable_divided(course_key, commentable_id, course_discussion_settings):
if request.method == "GET":
requested_group_id = request.GET.get('group_id')
@@ -870,7 +869,7 @@ def get_group_id_for_user_from_cache(user, course_id):
Caches the results of get_group_id_for_user, but serializes the course_id
instead of the course_discussions_settings object as cache keys.
"""
return get_group_id_for_user(user, get_course_discussion_settings(course_id))
return get_group_id_for_user(user, CourseDiscussionSettings.get(course_id))
def get_group_id_for_user(user, course_discussion_settings):
@@ -922,7 +921,7 @@ def is_commentable_divided(course_key, commentable_id, course_discussion_setting
Http404 if the course doesn't exist.
"""
if not course_discussion_settings:
course_discussion_settings = get_course_discussion_settings(course_key)
course_discussion_settings = CourseDiscussionSettings.get(course_key)
course = get_course_by_id(course_key)

View File

@@ -51,6 +51,7 @@ from lms.djangoapps.discussion.rest_api.utils import discussion_open_for_user
from openedx.core.djangoapps.django_comment_common.comment_client.comment import Comment
from openedx.core.djangoapps.django_comment_common.comment_client.thread import Thread
from openedx.core.djangoapps.django_comment_common.comment_client.utils import CommentClientRequestError
from openedx.core.djangoapps.django_comment_common.models import CourseDiscussionSettings
from openedx.core.djangoapps.django_comment_common.signals import (
comment_created,
comment_deleted,
@@ -61,7 +62,6 @@ from openedx.core.djangoapps.django_comment_common.signals import (
thread_edited,
thread_voted
)
from openedx.core.djangoapps.django_comment_common.utils import get_course_discussion_settings
from openedx.core.djangoapps.user_api.accounts.api import get_account_settings
from openedx.core.djangoapps.user_api.accounts.views import \
AccountViewSet # lint-amnesty, pylint: disable=unused-import
@@ -126,7 +126,7 @@ def _get_thread_and_context(request, thread_id, retrieve_kwargs=None):
course_key = CourseKey.from_string(cc_thread["course_id"])
course = _get_course(course_key, request.user)
context = get_context(course, request, cc_thread)
course_discussion_settings = get_course_discussion_settings(course_key)
course_discussion_settings = CourseDiscussionSettings.get(course_key)
if (
not context["is_requester_privileged"] and
cc_thread["group_id"] and
@@ -590,7 +590,7 @@ def get_thread_list(
"user_id": str(request.user.id),
"group_id": (
None if context["is_requester_privileged"] else
get_group_id_for_user(request.user, get_course_discussion_settings(course.id))
get_group_id_for_user(request.user, CourseDiscussionSettings.get(course.id))
),
"page": page,
"per_page": page_size,
@@ -875,7 +875,7 @@ def create_thread(request, thread_data):
context = get_context(course, request)
_check_initializable_thread_fields(thread_data, context)
discussion_settings = get_course_discussion_settings(course_key)
discussion_settings = CourseDiscussionSettings.get(course_key)
if (
"group_id" not in thread_data and
is_commentable_divided(course_key, thread_data.get("topic_id"), discussion_settings)

View File

@@ -11,6 +11,7 @@ from six.moves.urllib.parse import urlencode, urlunparse
from common.djangoapps.student.models import get_user_by_username_or_email
from lms.djangoapps.discussion.django_comment_client.utils import (
available_division_schemes,
course_discussion_division_enabled,
get_group_id_for_user,
get_group_name,
@@ -29,12 +30,12 @@ from openedx.core.djangoapps.django_comment_common.comment_client.thread import
from openedx.core.djangoapps.django_comment_common.comment_client.user import User as CommentClientUser
from openedx.core.djangoapps.django_comment_common.comment_client.utils import CommentClientRequestError
from openedx.core.djangoapps.django_comment_common.models import (
CourseDiscussionSettings,
FORUM_ROLE_ADMINISTRATOR,
FORUM_ROLE_COMMUNITY_TA,
FORUM_ROLE_MODERATOR,
Role
)
from openedx.core.djangoapps.django_comment_common.utils import get_course_discussion_settings
def get_context(course, request, thread=None):
@@ -59,7 +60,7 @@ def get_context(course, request, thread=None):
requester = request.user
cc_requester = CommentClientUser.from_django_user(requester).retrieve()
cc_requester["course_id"] = course.id
course_discussion_settings = get_course_discussion_settings(course.id)
course_discussion_settings = CourseDiscussionSettings.get(course.id)
return {
"course": course,
"request": request,
@@ -466,57 +467,83 @@ class DiscussionSettingsSerializer(serializers.Serializer):
"""
Serializer for course discussion settings.
"""
divided_discussions = serializers.ListField(
child=serializers.CharField(),
write_only=True,
)
divided_course_wide_discussions = serializers.ListField(
child=serializers.CharField(),
read_only=True,
)
divided_inline_discussions = serializers.ListField(
child=serializers.CharField(),
read_only=True,
)
always_divide_inline_discussions = serializers.BooleanField()
division_scheme = serializers.CharField()
def __init__(self, *args, **kwargs):
self.course = kwargs.pop('course')
self.discussion_settings = kwargs.pop('discussion_settings')
super().__init__(*args, **kwargs)
def validate(self, attrs):
def to_internal_value(self, data: dict) -> dict:
"""
Validate the fields in combination.
Transform the *incoming* primitive data into a native value.
"""
if not any(field in attrs for field in self.fields):
raise ValidationError('Bad request')
settings_to_change = {}
divided_course_wide_discussions, divided_inline_discussions = get_divided_discussions(
self.course, self.discussion_settings
)
if any(item in attrs for item in ('divided_course_wide_discussions', 'divided_inline_discussions')):
divided_course_wide_discussions = attrs.get(
payload = super().to_internal_value(data) or {}
course = self.context['course']
instance = self.context['settings']
if any(item in data for item in ('divided_course_wide_discussions', 'divided_inline_discussions')):
divided_course_wide_discussions, divided_inline_discussions = get_divided_discussions(
course, instance
)
divided_course_wide_discussions = data.get(
'divided_course_wide_discussions',
divided_course_wide_discussions
)
divided_inline_discussions = attrs.get('divided_inline_discussions', divided_inline_discussions)
settings_to_change['divided_discussions'] = divided_course_wide_discussions + divided_inline_discussions
divided_inline_discussions = data.get('divided_inline_discussions', divided_inline_discussions)
try:
payload['divided_discussions'] = divided_course_wide_discussions + divided_inline_discussions
except TypeError as error:
raise ValidationError(str(error)) from error
for item in ('always_divide_inline_discussions', 'division_scheme'):
if item in attrs:
settings_to_change[item] = attrs[item]
attrs['settings_to_change'] = settings_to_change
return attrs
if item in data:
payload[item] = data[item]
return payload
def to_representation(self, instance: CourseDiscussionSettings) -> dict:
"""
Return a serialized representation of the course discussion settings.
"""
payload = super().to_representation(instance)
course = self.context['course']
instance = self.context['settings']
course_key = course.id
divided_course_wide_discussions, divided_inline_discussions = get_divided_discussions(
course, instance
)
payload = {
'id': instance.id,
'divided_inline_discussions': divided_inline_discussions,
'divided_course_wide_discussions': divided_course_wide_discussions,
'always_divide_inline_discussions': instance.always_divide_inline_discussions,
'division_scheme': instance.division_scheme,
'available_division_schemes': available_division_schemes(course_key)
}
return payload
def create(self, validated_data):
"""
Overriden create abstract method
This method intentionally left empty
"""
pass # lint-amnesty, pylint: disable=unnecessary-pass
def update(self, instance, validated_data):
def update(self, instance: CourseDiscussionSettings, validated_data: dict) -> CourseDiscussionSettings:
"""
Overriden update abstract method
Update and save an existing instance
"""
pass # lint-amnesty, pylint: disable=unnecessary-pass
if not any(field in validated_data for field in self.fields):
raise ValidationError('Bad request')
try:
instance.update(validated_data)
except ValueError as e:
raise ValidationError(str(e)) from e
return instance
class DiscussionRolesSerializer(serializers.Serializer):

View File

@@ -16,7 +16,6 @@ from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.viewsets import ViewSet
from common.djangoapps.util.json_request import JsonResponse
from lms.djangoapps.discussion.django_comment_client.utils import available_division_schemes
from lms.djangoapps.discussion.rest_api.api import (
create_comment,
@@ -48,10 +47,7 @@ from lms.djangoapps.discussion.views import get_divided_discussions
from lms.djangoapps.instructor.access import update_forum_role
from openedx.core.djangoapps.django_comment_common import comment_client
from openedx.core.djangoapps.django_comment_common.models import Role
from openedx.core.djangoapps.django_comment_common.utils import (
get_course_discussion_settings,
set_course_discussion_settings
)
from openedx.core.djangoapps.django_comment_common.models import CourseDiscussionSettings
from openedx.core.djangoapps.user_api.accounts.permissions import CanReplaceUsername, CanRetireUser
from openedx.core.djangoapps.user_api.models import UserRetirementStatus
from openedx.core.lib.api.authentication import BearerAuthenticationAllowInactiveUser
@@ -756,22 +752,6 @@ class CourseDiscussionSettingsAPIView(DeveloperErrorViewMixin, APIView):
parser_classes = (JSONParser, MergePatchParser,)
permission_classes = (permissions.IsAuthenticated, permissions.IsAdminUser)
def _get_representation(self, course, course_key, discussion_settings):
"""
Return a serialized representation of the course discussion settings.
"""
divided_course_wide_discussions, divided_inline_discussions = get_divided_discussions(
course, discussion_settings
)
return JsonResponse({
'id': discussion_settings.id,
'divided_inline_discussions': divided_inline_discussions,
'divided_course_wide_discussions': divided_course_wide_discussions,
'always_divide_inline_discussions': discussion_settings.always_divide_inline_discussions,
'division_scheme': discussion_settings.division_scheme,
'available_division_schemes': available_division_schemes(course_key)
})
def _get_request_kwargs(self, course_id):
return dict(course_id=course_id)
@@ -787,8 +767,17 @@ class CourseDiscussionSettingsAPIView(DeveloperErrorViewMixin, APIView):
course_key = form.cleaned_data['course_key']
course = form.cleaned_data['course']
discussion_settings = get_course_discussion_settings(course_key)
return self._get_representation(course, course_key, discussion_settings)
discussion_settings = CourseDiscussionSettings.get(course_key)
serializer = DiscussionSettingsSerializer(
discussion_settings,
context={
'course': course,
'settings': discussion_settings,
},
partial=True,
)
response = Response(serializer.data)
return response
def patch(self, request, course_id):
"""
@@ -804,24 +793,20 @@ class CourseDiscussionSettingsAPIView(DeveloperErrorViewMixin, APIView):
course = form.cleaned_data['course']
course_key = form.cleaned_data['course_key']
discussion_settings = get_course_discussion_settings(course_key)
discussion_settings = CourseDiscussionSettings.get(course_key)
serializer = DiscussionSettingsSerializer(
discussion_settings,
context={
'course': course,
'settings': discussion_settings,
},
data=request.data,
partial=True,
course=course,
discussion_settings=discussion_settings
)
if not serializer.is_valid():
raise ValidationError(serializer.errors)
settings_to_change = serializer.validated_data['settings_to_change']
try:
discussion_settings = set_course_discussion_settings(course_key, **settings_to_change)
except ValueError as e:
raise ValidationError(str(e)) # lint-amnesty, pylint: disable=raise-missing-from
serializer.save()
return Response(status=status.HTTP_204_NO_CONTENT)
@@ -907,7 +892,7 @@ class CourseDiscussionRolesAPIView(DeveloperErrorViewMixin, APIView):
role = form.cleaned_data['role']
data = {'course_id': course_id, 'users': role.users.all()}
context = {'course_discussion_settings': get_course_discussion_settings(course_id)}
context = {'course_discussion_settings': CourseDiscussionSettings.get(course_id)}
serializer = DiscussionRolesListSerializer(data, context=context)
return Response(serializer.data)
@@ -937,6 +922,6 @@ class CourseDiscussionRolesAPIView(DeveloperErrorViewMixin, APIView):
role = form.cleaned_data['role']
data = {'course_id': course_id, 'users': role.users.all()}
context = {'course_discussion_settings': get_course_discussion_settings(course_id)}
context = {'course_discussion_settings': CourseDiscussionSettings.get(course_id)}
serializer = DiscussionRolesListSerializer(data, context=context)
return Response(serializer.data)

View File

@@ -51,11 +51,7 @@ from lms.djangoapps.discussion.exceptions import TeamDiscussionHiddenFromUserExc
from lms.djangoapps.experiments.utils import get_experiment_user_metadata_context
from lms.djangoapps.teams import api as team_api
from openedx.core.djangoapps.django_comment_common.models import CourseDiscussionSettings
from openedx.core.djangoapps.django_comment_common.utils import (
ThreadContext,
get_course_discussion_settings,
set_course_discussion_settings
)
from openedx.core.djangoapps.django_comment_common.utils import ThreadContext
from openedx.core.djangoapps.plugin_api.views import EdxFragmentView
from openedx.features.course_duration_limits.access import generate_course_expired_fragment
from xmodule.modulestore.django import modulestore
@@ -76,7 +72,7 @@ def make_course_settings(course, user, include_category_map=True):
Generate a JSON-serializable model for course settings, which will be used to initialize a
DiscussionCourseSettings object on the client.
"""
course_discussion_settings = get_course_discussion_settings(course.id)
course_discussion_settings = CourseDiscussionSettings.get(course.id)
group_names_by_id = get_group_names_by_id(course_discussion_settings)
course_setting = {
'is_discussion_division_enabled': course_discussion_division_enabled(course_discussion_settings),
@@ -225,7 +221,7 @@ def inline_discussion(request, course_key, discussion_id):
with function_trace('determine_group_permissions'):
is_staff = has_permission(request.user, 'openclose_thread', course.id)
course_discussion_settings = get_course_discussion_settings(course.id)
course_discussion_settings = CourseDiscussionSettings.get(course.id)
group_names_by_id = get_group_names_by_id(course_discussion_settings)
course_is_divided = course_discussion_settings.division_scheme is not CourseDiscussionSettings.NONE
@@ -378,7 +374,7 @@ def _find_thread(request, course, discussion_id, thread_id):
# verify that the thread belongs to the requesting student's group
is_moderator = has_permission(request.user, "see_all_cohorts", course.id)
course_discussion_settings = get_course_discussion_settings(course.id)
course_discussion_settings = CourseDiscussionSettings.get(course.id)
if is_commentable_divided(course.id, discussion_id, course_discussion_settings) and not is_moderator:
user_group_id = get_group_id_for_user(request.user, course_discussion_settings)
if getattr(thread, "group_id", None) is not None and user_group_id != thread.group_id:
@@ -489,7 +485,7 @@ def _create_discussion_board_context(request, base_context, thread=None):
add_courseware_context(threads, course, user)
with function_trace("get_cohort_info"):
course_discussion_settings = get_course_discussion_settings(course_key)
course_discussion_settings = CourseDiscussionSettings.get(course_key)
user_group_id = get_group_id_for_user(user, course_discussion_settings)
context.update({
@@ -563,7 +559,7 @@ def create_user_profile_context(request, course_key, user_id):
).order_by("name").values_list("name", flat=True).distinct()
with function_trace("get_cohort_info"):
course_discussion_settings = get_course_discussion_settings(course_key)
course_discussion_settings = CourseDiscussionSettings.get(course_key)
user_group_id = get_group_id_for_user(request.user, course_discussion_settings)
context = _create_base_discussion_view_context(request, course_key)
@@ -909,7 +905,7 @@ def course_discussions_settings_handler(request, course_key_string):
"""
course_key = CourseKey.from_string(course_key_string)
course = get_course_with_access(request.user, 'staff', course_key)
discussion_settings = get_course_discussion_settings(course_key)
discussion_settings = CourseDiscussionSettings.get(course_key)
if request.method == 'PATCH':
divided_course_wide_discussions, divided_inline_discussions = get_divided_discussions(
@@ -941,7 +937,7 @@ def course_discussions_settings_handler(request, course_key_string):
try:
if settings_to_change:
discussion_settings = set_course_discussion_settings(course_key, **settings_to_change)
discussion_settings.update(settings_to_change)
except ValueError as err:
# Note: error message not translated because it is not exposed to the user (UI prevents this state).

View File

@@ -77,7 +77,6 @@ from lms.djangoapps.courseware.access import has_access
from lms.djangoapps.courseware.courses import get_course_with_access
from lms.djangoapps.courseware.models import StudentModule
from lms.djangoapps.discussion.django_comment_client.utils import (
get_course_discussion_settings,
get_group_id_for_user,
get_group_name,
has_forum_access
@@ -103,6 +102,7 @@ from lms.djangoapps.instructor_task.models import ReportStore
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
from openedx.core.djangoapps.course_groups.cohorts import is_course_cohorted
from openedx.core.djangoapps.django_comment_common.models import (
CourseDiscussionSettings,
FORUM_ROLE_ADMINISTRATOR,
FORUM_ROLE_COMMUNITY_TA,
FORUM_ROLE_GROUP_MODERATOR,
@@ -2131,7 +2131,7 @@ def list_forum_members(request, course_id):
except Role.DoesNotExist:
users = []
course_discussion_settings = get_course_discussion_settings(course_id)
course_discussion_settings = CourseDiscussionSettings.get(course_id)
def extract_user_info(user):
""" Convert user to dict for json rendering. """