diff --git a/openedx/features/content_tagging/migrations/0003_system_defined_taxonomies.py b/openedx/features/content_tagging/migrations/0003_system_defined_taxonomies.py index 6bee20ff3e5f..53e0d7046466 100644 --- a/openedx/features/content_tagging/migrations/0003_system_defined_taxonomies.py +++ b/openedx/features/content_tagging/migrations/0003_system_defined_taxonomies.py @@ -1,12 +1,13 @@ -# Generated by Django 3.2.20 on 2023-07-22 18:30 +# Generated by Django 3.2.20 on 2023-07-24 01:58 from django.db import migrations +import openedx.features.content_tagging.models.base class Migration(migrations.Migration): dependencies = [ - ('oel_tagging', '0003_auto_20230721_1238'), + ('oel_tagging', '__latest__'), ('content_tagging', '0002_system_defined_taxonomies'), ] @@ -20,7 +21,7 @@ class Migration(migrations.Migration): 'indexes': [], 'constraints': [], }, - bases=('oel_tagging.usersystemdefinedtaxonomy',), + bases=(openedx.features.content_tagging.models.base.ContentTaxonomyMixin, 'oel_tagging.usersystemdefinedtaxonomy'), ), migrations.CreateModel( name='ContentLanguageTaxonomy', @@ -31,10 +32,10 @@ class Migration(migrations.Migration): 'indexes': [], 'constraints': [], }, - bases=('oel_tagging.languagetaxonomy',), + bases=(openedx.features.content_tagging.models.base.ContentTaxonomyMixin, 'oel_tagging.languagetaxonomy'), ), migrations.CreateModel( - name='OrganizarionSystemDefinedTaxonomy', + name='OrganizationModelObjectTag', fields=[ ], options={ @@ -42,10 +43,10 @@ class Migration(migrations.Migration): 'indexes': [], 'constraints': [], }, - bases=('oel_tagging.modelsystemdefinedtaxonomy',), + bases=('oel_tagging.modelobjecttag',), ), migrations.CreateModel( - name='OrganizationModelObjectTag', + name='OrganizationSystemDefinedTaxonomy', fields=[ ], options={ @@ -53,7 +54,7 @@ class Migration(migrations.Migration): 'indexes': [], 'constraints': [], }, - bases=('oel_tagging.modelobjecttag',), + bases=('oel_tagging.modelsystemdefinedtaxonomy',), ), migrations.CreateModel( name='ContentOrganizationTaxonomy', @@ -64,6 +65,6 @@ class Migration(migrations.Migration): 'indexes': [], 'constraints': [], }, - bases=('content_tagging.organizarionsystemdefinedtaxonomy',), + bases=(openedx.features.content_tagging.models.base.ContentTaxonomyMixin, 'content_tagging.organizationsystemdefinedtaxonomy'), ), ] diff --git a/openedx/features/content_tagging/models/base.py b/openedx/features/content_tagging/models/base.py index e25dd949a2b9..54505d0e9d1e 100644 --- a/openedx/features/content_tagging/models/base.py +++ b/openedx/features/content_tagging/models/base.py @@ -98,14 +98,20 @@ def object_key(self) -> OpaqueKey: return None -class ContentTaxonomy(Taxonomy): +class ContentTaxonomyMixin: """ Taxonomy that accepts ContentTags, and ensures a valid TaxonomyOrg owner relationship with the content object. """ - class Meta: - proxy = True + @property + def object_tag_class(self) -> Type: + """ + Returns the ObjectTag subclass associated with this taxonomy, which is ObjectTag by default. + + Taxonomy subclasses may override this method to use different subclasses of ObjectTag. + """ + return ContentTag def _check_object(self, object_tag: ObjectTag) -> bool: """ @@ -124,3 +130,13 @@ def _check_taxonomy(self, object_tag: ObjectTag) -> bool: and object_key and TaxonomyOrg.is_owner(self, object_key.org) ) + + +class ContentTaxonomy(ContentTaxonomyMixin, Taxonomy): + """ + Taxonomy that accepts ContentTags, + and ensures a valid TaxonomyOrg owner relationship with the content object. + """ + + class Meta: + proxy = True diff --git a/openedx/features/content_tagging/models/system_defined.py b/openedx/features/content_tagging/models/system_defined.py index fbee3be5f75d..1b187aa0b7b5 100644 --- a/openedx/features/content_tagging/models/system_defined.py +++ b/openedx/features/content_tagging/models/system_defined.py @@ -4,7 +4,6 @@ from typing import Type from openedx_tagging.core.tagging.models import ( - ObjectTag, ModelSystemDefinedTaxonomy, ModelObjectTag, UserSystemDefinedTaxonomy, @@ -12,12 +11,12 @@ ) from organizations.models import Organization -from .base import ContentTaxonomy +from .base import ContentTaxonomyMixin class OrganizationModelObjectTag(ModelObjectTag): """ - ObjectTags for the OrganizarionSystemDefinedTaxonomy. + ObjectTags for the OrganizationSystemDefinedTaxonomy. """ class Meta: @@ -38,7 +37,7 @@ def tag_class_value(self) -> str: return "name" -class OrganizarionSystemDefinedTaxonomy(ModelSystemDefinedTaxonomy): +class OrganizationSystemDefinedTaxonomy(ModelSystemDefinedTaxonomy): """ Organization based system taxonomy class. """ @@ -54,61 +53,31 @@ def object_tag_class(self) -> Type: return OrganizationModelObjectTag -class ContentLanguageTaxonomy(LanguageTaxonomy): +class ContentLanguageTaxonomy(ContentTaxonomyMixin, LanguageTaxonomy): """ Language system-defined taxonomy that accepts ContentTags - - Inherit `_check_tag` from LanguageTaxonomy and uses - `_check_object` and `_check_taxonomy` from ContentTaxonomy """ class Meta: proxy = True - def _check_object(self, object_tag: ObjectTag) -> bool: - taxonomy = ContentTaxonomy().copy(self) - return taxonomy._check_object(object_tag) # pylint: disable=protected-access - - def _check_taxonomy(self, object_tag: ObjectTag) -> bool: - taxonomy = ContentTaxonomy().copy(self) - return taxonomy._check_taxonomy(object_tag) # pylint: disable=protected-access -class ContentAuthorTaxonomy(UserSystemDefinedTaxonomy): +class ContentAuthorTaxonomy(ContentTaxonomyMixin, UserSystemDefinedTaxonomy): """ Author system-defined taxonomy that accepts Content Tags - - Inherit `_check_tag` from UserSystemDefinedTaxonomy and uses - `_check_object` and `_check_taxonomy` from ContentTaxonomy """ class Meta: proxy = True - def _check_object(self, object_tag: ObjectTag) -> bool: - taxonomy = ContentTaxonomy().copy(self) - return taxonomy._check_object(object_tag) # pylint: disable=protected-access - def _check_taxonomy(self, object_tag: ObjectTag) -> bool: - taxonomy = ContentTaxonomy().copy(self) - return taxonomy._check_taxonomy(object_tag) # pylint: disable=protected-access - -class ContentOrganizationTaxonomy(OrganizarionSystemDefinedTaxonomy): +class ContentOrganizationTaxonomy(ContentTaxonomyMixin, OrganizationSystemDefinedTaxonomy): """ Organization system-defined taxonomy that accepts Content Tags - - Inherit `_check_tag` from OrganizarionSystemDefinedTaxonomy and uses - `_check_object` and `_check_taxonomy` from ContentTaxonomy """ class Meta: proxy = True - def _check_object(self, object_tag: ObjectTag) -> bool: - taxonomy = ContentTaxonomy().copy(self) - return taxonomy._check_object(object_tag) # pylint: disable=protected-access - - def _check_taxonomy(self, object_tag: ObjectTag) -> bool: - taxonomy = ContentTaxonomy().copy(self) - return taxonomy._check_taxonomy(object_tag) # pylint: disable=protected-access