Skip to content

Commit 36283f1

Browse files
authored
feat! Modify DiscussionsConfiguration to allow programs (#28541)
* feat! Modify DiscussionsConfiguration to allow programs * feat: add model for program discussions configuration
1 parent fe20509 commit 36283f1

3 files changed

Lines changed: 122 additions & 3 deletions

File tree

openedx/core/djangoapps/discussions/admin.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
from openedx.core.djangoapps.config_model_utils.admin import StackedConfigModelAdmin
99

10-
from .models import DiscussionsConfiguration
10+
from .models import DiscussionsConfiguration, ProgramDiscussionsConfiguration
1111
from .models import ProviderFilter
1212

1313

@@ -27,6 +27,22 @@ class DiscussionsConfigurationAdmin(SimpleHistoryAdmin):
2727
)
2828

2929

30+
class ProgramDiscussionsConfigurationAdmin(SimpleHistoryAdmin):
31+
"""
32+
Customize the admin interface for the program discussions configuration
33+
"""
34+
35+
search_fields = (
36+
'program_uuid',
37+
'enabled',
38+
'provider_type',
39+
)
40+
list_filter = (
41+
'enabled',
42+
'provider_type',
43+
)
44+
45+
3046
class AllowListFilter(SimpleListFilter):
3147
"""
3248
Customize the admin interface for the AllowList
@@ -88,4 +104,5 @@ class ProviderFilterAdmin(StackedConfigModelAdmin):
88104

89105

90106
admin.site.register(DiscussionsConfiguration, DiscussionsConfigurationAdmin)
107+
admin.site.register(ProgramDiscussionsConfiguration, ProgramDiscussionsConfigurationAdmin)
91108
admin.site.register(ProviderFilter, ProviderFilterAdmin)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Generated by Django 2.2.24 on 2021-08-31 11:18
2+
3+
from django.conf import settings
4+
from django.db import migrations, models
5+
import django.db.models.deletion
6+
import django.utils.timezone
7+
import model_utils.fields
8+
import simple_history.models
9+
10+
11+
class Migration(migrations.Migration):
12+
13+
dependencies = [
14+
('lti_consumer', '0012_rename_courseeditltifieldsenabledflag_model'),
15+
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
16+
('discussions', '0003_alter_provider_filter_list'),
17+
]
18+
19+
operations = [
20+
migrations.CreateModel(
21+
name='ProgramDiscussionsConfiguration',
22+
fields=[
23+
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created')),
24+
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified')),
25+
('program_uuid', models.CharField(db_index=True, max_length=50, primary_key=True, serialize=False, verbose_name='Program UUID')),
26+
('enabled', models.BooleanField(default=True, help_text='If disabled, the discussions in the associated program will be disabled.')),
27+
('provider_type', models.CharField(help_text="The discussion provider's id", max_length=50, verbose_name='Discussion provider')),
28+
('lti_configuration', models.ForeignKey(blank=True, help_text='The LTI configuration data for this program/provider.', null=True, on_delete=django.db.models.deletion.SET_NULL, to='lti_consumer.LtiConfiguration')),
29+
],
30+
options={
31+
'abstract': False,
32+
},
33+
),
34+
migrations.CreateModel(
35+
name='HistoricalProgramDiscussionsConfiguration',
36+
fields=[
37+
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created')),
38+
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified')),
39+
('program_uuid', models.CharField(db_index=True, max_length=50, verbose_name='Program UUID')),
40+
('enabled', models.BooleanField(default=True, help_text='If disabled, the discussions in the associated program will be disabled.')),
41+
('provider_type', models.CharField(help_text="The discussion provider's id", max_length=50, verbose_name='Discussion provider')),
42+
('history_id', models.AutoField(primary_key=True, serialize=False)),
43+
('history_date', models.DateTimeField()),
44+
('history_change_reason', models.CharField(max_length=100, null=True)),
45+
('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)),
46+
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
47+
('lti_configuration', models.ForeignKey(blank=True, db_constraint=False, help_text='The LTI configuration data for this program/provider.', null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='lti_consumer.LtiConfiguration')),
48+
],
49+
options={
50+
'verbose_name': 'historical program discussions configuration',
51+
'ordering': ('-history_date', '-history_id'),
52+
'get_latest_by': 'history_date',
53+
},
54+
bases=(simple_history.models.HistoricalChanges, models.Model),
55+
),
56+
]

openedx/core/djangoapps/discussions/models.py

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -360,8 +360,7 @@ class DiscussionsConfiguration(TimeStampedModel):
360360

361361
def clean(self):
362362
"""
363-
Validate the model
364-
363+
Validate the model.
365364
Currently, this only support courses, this can be extended
366365
whenever discussions are available in other contexts
367366
"""
@@ -418,3 +417,50 @@ def available_providers(self) -> list[str]:
418417
@classmethod
419418
def get_available_providers(cls, context_key: CourseKey) -> list[str]:
420419
return ProviderFilter.current(course_key=context_key).available_providers
420+
421+
422+
class ProgramDiscussionsConfiguration(TimeStampedModel):
423+
"""
424+
Associates a program with a discussion provider and configuration
425+
"""
426+
427+
program_uuid = models.CharField(
428+
primary_key=True,
429+
db_index=True,
430+
max_length=50,
431+
verbose_name=_("Program UUID"),
432+
)
433+
enabled = models.BooleanField(
434+
default=True,
435+
help_text=_("If disabled, the discussions in the associated program will be disabled.")
436+
)
437+
lti_configuration = models.ForeignKey(
438+
LtiConfiguration,
439+
on_delete=models.SET_NULL,
440+
blank=True,
441+
null=True,
442+
help_text=_("The LTI configuration data for this program/provider."),
443+
)
444+
provider_type = models.CharField(
445+
blank=False,
446+
max_length=50,
447+
verbose_name=_("Discussion provider"),
448+
help_text=_("The discussion provider's id"),
449+
)
450+
history = HistoricalRecords()
451+
452+
def __str__(self):
453+
return f"ProgramDiscussionConfiguration(uuid='{self.uuid}', provider='{self.provider}', enabled={self.enabled})"
454+
455+
@classmethod
456+
def is_enabled(cls, program_uuid) -> bool:
457+
"""
458+
Check if there is an active configuration for a given program uuid
459+
460+
Default to False, if no configuration exists
461+
"""
462+
try:
463+
configuration = cls.objects.get(program_uuid=program_uuid)
464+
return configuration.enabled
465+
except cls.DoesNotExist:
466+
return False

0 commit comments

Comments
 (0)