From c9d90f2f970f95c1a0c9ff472d79c2b830a77744 Mon Sep 17 00:00:00 2001 From: XnpioChV Date: Tue, 11 Jul 2023 16:21:20 -0500 Subject: [PATCH 01/13] feat: System defined taxonomies --- .../fixtures/system_defined.yaml | 22 +++++ .../0002_system_defined_taxonomies.py | 39 ++++++++ .../system_defined_taxonomies/object_tags.py | 90 +++++++++++++++++++ requirements/edx-sandbox/py38.txt | 2 +- requirements/edx/base.txt | 4 +- requirements/edx/coverage.txt | 2 +- requirements/edx/development.txt | 3 +- requirements/edx/doc.txt | 8 +- requirements/edx/paver.txt | 2 +- requirements/edx/testing.txt | 2 +- requirements/pip-tools.txt | 2 +- requirements/pip.txt | 2 +- scripts/xblock/requirements.txt | 2 +- 13 files changed, 167 insertions(+), 13 deletions(-) create mode 100644 openedx/features/content_tagging/fixtures/system_defined.yaml create mode 100644 openedx/features/content_tagging/migrations/0002_system_defined_taxonomies.py create mode 100644 openedx/features/content_tagging/system_defined_taxonomies/object_tags.py diff --git a/openedx/features/content_tagging/fixtures/system_defined.yaml b/openedx/features/content_tagging/fixtures/system_defined.yaml new file mode 100644 index 000000000000..c33f80a72950 --- /dev/null +++ b/openedx/features/content_tagging/fixtures/system_defined.yaml @@ -0,0 +1,22 @@ +- model: oel_tagging.taxonomy + pk: 2 + fields: + name: Organizations + description: Allows tags for any organization ID created on the instance. + enabled: true + required: true + allow_multiple: false + allow_free_text: true + system_defined: true + visible_to_authors: false +- model: oel_tagging.taxonomy + pk: 3 + fields: + name: Content Authors + description: Allows tags for any user ID created on the instance. + enabled: true + required: true + allow_multiple: false + allow_free_text: true + system_defined: true + visible_to_authors: false diff --git a/openedx/features/content_tagging/migrations/0002_system_defined_taxonomies.py b/openedx/features/content_tagging/migrations/0002_system_defined_taxonomies.py new file mode 100644 index 000000000000..3ccca0cb1135 --- /dev/null +++ b/openedx/features/content_tagging/migrations/0002_system_defined_taxonomies.py @@ -0,0 +1,39 @@ +# Generated by Django 3.2.20 on 2023-07-11 22:57 + +from django.db import migrations +from django.core.management import call_command + +def load_system_defined_taxonomies(apps, schema_editor): + """ + Creates system defined taxonomies and loads tags + """ + + # Create system defined taxonomy instances + call_command('loaddata', '--app=oel_tagging', 'system_defined.yaml') + call_command('loaddata', '--app=content_tagging', 'system_defined.yaml') + + # Loads language tags + call_command('loaddata', '--app=oel_tagging', 'language_taxonomy.yaml') + + +def revert_system_defined_taxonomies(apps, schema_editor): + """ + Deletes all system defined taxonomies + """ + Taxonomy = apps.get_model('oel_tagging', 'Taxonomy') + Tag = apps.get_model('oel_tagging', 'Tag') + + # For some reason the tags are not deleted when deleting the taxonomy + Tag.objects.filter(taxonomy__system_defined=True).delete() + Taxonomy.objects.filter(system_defined=True).delete() + + +class Migration(migrations.Migration): + + dependencies = [ + ('content_tagging', '0001_initial'), + ] + + operations = [ + migrations.RunPython(load_system_defined_taxonomies, revert_system_defined_taxonomies), + ] diff --git a/openedx/features/content_tagging/system_defined_taxonomies/object_tags.py b/openedx/features/content_tagging/system_defined_taxonomies/object_tags.py new file mode 100644 index 000000000000..7bb339d40830 --- /dev/null +++ b/openedx/features/content_tagging/system_defined_taxonomies/object_tags.py @@ -0,0 +1,90 @@ +""" +ObjectTags for System-defined Taxonomies +""" +from openedx_tagging.core.tagging.system_defined_taxonomies.object_tags import ( + SystemDefinedIds as TaxonomyIds, + ModelObjectTag, + UserObjectTag, + LanguageObjectTag, +) +from openedx_tagging.core.tagging.registry import register_object_tag_class +from organizations.models import Organization + +from ..models import CourseObjectTagMixin, BlockObjectTagMixin + + +class SystemDefinedIds(TaxonomyIds): + """ + System-defined taxonomy IDs + """ + OrganizationTaxonomy = 2 + AuthorTaxonomy = 3 + + +class OrganizationObjectTag(ModelObjectTag): + """ + ObjectTag used on Organization system-defined taxonomy + """ + + system_defined_taxonomy_id = SystemDefinedIds.OrganizationTaxonomy.value + + class Meta: + proxy = True + + tag_class_model = Organization + + +class AuthorObjcetTag(UserObjectTag): + """ + ObjectTag used on Author system-defined taxonomy + """ + + system_defined_taxonomy_id = SystemDefinedIds.AuthorTaxonomy.value + + class Meta: + proxy = True + + +class OrganizationCourseObjectTag(OrganizationObjectTag, CourseObjectTagMixin): + """ + CourseObjectTag for use in the Organization system-defined taxonomy + """ + + +class OrganizationBlockObjectTag(OrganizationObjectTag, BlockObjectTagMixin): + """ + BlockObjectTag for use in the Organization system-defined taxonomy + """ + + +class LanguageCourseObjectTag(LanguageObjectTag, CourseObjectTagMixin): + """ + CourseObjectTag for use in the Language system-defined taxonomy + """ + + +class LanguageBlockObjectTag(LanguageObjectTag, BlockObjectTagMixin): + """ + BlockObjectTag for use in the Language system-defined taxonomy + """ + + +class AuthorCourseObjectTag(AuthorObjcetTag, CourseObjectTagMixin): + """ + CourseObjectTag for use in the Author system-defined taxonomy + """ + + +class AuthorBlockObjectTag(AuthorObjcetTag, BlockObjectTagMixin): + """ + BlockObjectTag for use in the Author system-defined taxonomy + """ + + +# Register the object tag classes in reverse order for how we want them considered +register_object_tag_class(OrganizationCourseObjectTag) +register_object_tag_class(OrganizationBlockObjectTag) +register_object_tag_class(LanguageCourseObjectTag) +register_object_tag_class(LanguageBlockObjectTag) +register_object_tag_class(AuthorCourseObjectTag) +register_object_tag_class(AuthorBlockObjectTag) diff --git a/requirements/edx-sandbox/py38.txt b/requirements/edx-sandbox/py38.txt index 75d319e57c13..b4d072b25845 100644 --- a/requirements/edx-sandbox/py38.txt +++ b/requirements/edx-sandbox/py38.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.8 +# This file is autogenerated by pip-compile with Python 3.10 # by the following command: # # make upgrade diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt index 67250d9d05ad..62253e512dcd 100644 --- a/requirements/edx/base.txt +++ b/requirements/edx/base.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.8 +# This file is autogenerated by pip-compile with Python 3.10 # by the following command: # # make upgrade @@ -819,8 +819,6 @@ pillow==9.5.0 # edx-enterprise # edx-organizations # edxval -pkgutil-resolve-name==1.3.10 - # via jsonschema polib==1.2.0 # via edx-i18n-tools prompt-toolkit==3.0.39 diff --git a/requirements/edx/coverage.txt b/requirements/edx/coverage.txt index c0b44e4fdd79..a04c6666a786 100644 --- a/requirements/edx/coverage.txt +++ b/requirements/edx/coverage.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.8 +# This file is autogenerated by pip-compile with Python 3.10 # by the following command: # # make upgrade diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt index 743938fb1773..afaf3b6a56ce 100644 --- a/requirements/edx/development.txt +++ b/requirements/edx/development.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.8 +# This file is autogenerated by pip-compile with Python 3.10 # by the following command: # # make upgrade @@ -2070,7 +2070,6 @@ typing-extensions==4.7.1 # pydantic # pydantic-core # pydata-sphinx-theme - # pylint # pylti1p3 # snowflake-connector-python # starlette diff --git a/requirements/edx/doc.txt b/requirements/edx/doc.txt index 3b584a4bee5e..394a175e9828 100644 --- a/requirements/edx/doc.txt +++ b/requirements/edx/doc.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.8 +# This file is autogenerated by pip-compile with Python 3.10 # by the following command: # # make upgrade @@ -707,6 +707,7 @@ idna==3.4 # yarl imagesize==1.4.1 # via sphinx +<<<<<<< HEAD importlib-metadata==6.8.0 # via # -r requirements/edx/base.txt @@ -735,6 +736,8 @@ itypes==1.2.0 # via # -r requirements/edx/base.txt # coreapi +======= +>>>>>>> 70004ccb4e (feat: System defined taxonomies) jinja2==3.1.2 # via # -r requirements/edx/base.txt @@ -1404,6 +1407,7 @@ urllib3==1.26.16 # elasticsearch # py2neo # requests +<<<<<<< HEAD # snowflake-connector-python user-util==1.0.0 # via -r requirements/edx/base.txt @@ -1498,3 +1502,5 @@ zipp==3.16.2 # The following packages are considered to be unsafe in a requirements file: # setuptools +======= +>>>>>>> 70004ccb4e (feat: System defined taxonomies) diff --git a/requirements/edx/paver.txt b/requirements/edx/paver.txt index ae5a7829252d..77551eaa59b2 100644 --- a/requirements/edx/paver.txt +++ b/requirements/edx/paver.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.8 +# This file is autogenerated by pip-compile with Python 3.10 # by the following command: # # make upgrade diff --git a/requirements/edx/testing.txt b/requirements/edx/testing.txt index 7165c677dc35..1184bfd12886 100644 --- a/requirements/edx/testing.txt +++ b/requirements/edx/testing.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.8 +# This file is autogenerated by pip-compile with Python 3.10 # by the following command: # # make upgrade diff --git a/requirements/pip-tools.txt b/requirements/pip-tools.txt index 1db6c3427e2c..a7104310df20 100644 --- a/requirements/pip-tools.txt +++ b/requirements/pip-tools.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.8 +# This file is autogenerated by pip-compile with Python 3.10 # by the following command: # # make upgrade diff --git a/requirements/pip.txt b/requirements/pip.txt index fb1908e60d73..9a5e0788e109 100644 --- a/requirements/pip.txt +++ b/requirements/pip.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.8 +# This file is autogenerated by pip-compile with Python 3.10 # by the following command: # # make upgrade diff --git a/scripts/xblock/requirements.txt b/scripts/xblock/requirements.txt index c7433da88f84..8348c1f1b4a8 100644 --- a/scripts/xblock/requirements.txt +++ b/scripts/xblock/requirements.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.8 +# This file is autogenerated by pip-compile with Python 3.10 # by the following command: # # make upgrade From 3cf4fff961583388c802b67d02a93ecc4a98ad80 Mon Sep 17 00:00:00 2001 From: XnpioChV Date: Fri, 21 Jul 2023 13:59:04 -0500 Subject: [PATCH 02/13] style: models.py moved to models/base.py --- .../content_tagging/fixtures/system_defined.yaml | 15 +++++++++++++-- .../features/content_tagging/models/__init__.py | 5 +++++ .../content_tagging/{models.py => models/base.py} | 6 ++++++ .../content_tagging/models/system_defined.py | 9 +++++++++ 4 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 openedx/features/content_tagging/models/__init__.py rename openedx/features/content_tagging/{models.py => models/base.py} (98%) create mode 100644 openedx/features/content_tagging/models/system_defined.py diff --git a/openedx/features/content_tagging/fixtures/system_defined.yaml b/openedx/features/content_tagging/fixtures/system_defined.yaml index c33f80a72950..6c3fd970a503 100644 --- a/openedx/features/content_tagging/fixtures/system_defined.yaml +++ b/openedx/features/content_tagging/fixtures/system_defined.yaml @@ -1,5 +1,16 @@ - model: oel_tagging.taxonomy - pk: 2 + pk: -1 + fields: + name: Languages + description: ISO 639-1 Languages. Allows tags for any language configured for use on the instance + enabled: true + required: true + allow_multiple: false + allow_free_text: false + system_defined: true + visible_to_authors: true +- model: oel_tagging.taxonomy + pk: -2 fields: name: Organizations description: Allows tags for any organization ID created on the instance. @@ -10,7 +21,7 @@ system_defined: true visible_to_authors: false - model: oel_tagging.taxonomy - pk: 3 + pk: -3 fields: name: Content Authors description: Allows tags for any user ID created on the instance. diff --git a/openedx/features/content_tagging/models/__init__.py b/openedx/features/content_tagging/models/__init__.py new file mode 100644 index 000000000000..e099dd487781 --- /dev/null +++ b/openedx/features/content_tagging/models/__init__.py @@ -0,0 +1,5 @@ +from .base import ( + TaxonomyOrg, + ContentTag, + ContentTaxonomy, +) diff --git a/openedx/features/content_tagging/models.py b/openedx/features/content_tagging/models/base.py similarity index 98% rename from openedx/features/content_tagging/models.py rename to openedx/features/content_tagging/models/base.py index a3b094a8e9ff..240446c1d680 100644 --- a/openedx/features/content_tagging/models.py +++ b/openedx/features/content_tagging/models/base.py @@ -10,6 +10,12 @@ from opaque_keys.edx.keys import LearningContextKey from opaque_keys.edx.locator import BlockUsageLocator from openedx_tagging.core.tagging.models import ObjectTag, Taxonomy + +from openedx_tagging.core.tagging.models import ( + ObjectTag, + Taxonomy, +) + from organizations.models import Organization diff --git a/openedx/features/content_tagging/models/system_defined.py b/openedx/features/content_tagging/models/system_defined.py new file mode 100644 index 000000000000..6313f0ab8769 --- /dev/null +++ b/openedx/features/content_tagging/models/system_defined.py @@ -0,0 +1,9 @@ +""" +System defined models +""" +from openedx_tagging.core.tagging.models import ( + ModelSystemDefinedTaxonomy, + ModelObjectTag, + UserSystemDefinedTaxonomy, + LanguageTaxonomy, +) From a6f67cb30253c23575dc3aa7c580768293405d38 Mon Sep 17 00:00:00 2001 From: XnpioChV Date: Fri, 21 Jul 2023 16:01:21 -0500 Subject: [PATCH 03/13] feat: New Content System defined models --- openedx-learning | 1 + .../fixtures/system_defined.yaml | 10 +- .../0002_system_defined_taxonomies.py | 7 +- .../content_tagging/models/__init__.py | 5 + .../content_tagging/models/system_defined.py | 99 +++++++++++++++++++ .../system_defined_taxonomies/object_tags.py | 90 ----------------- .../content_tagging/tests/test_rules.py | 9 +- 7 files changed, 118 insertions(+), 103 deletions(-) create mode 160000 openedx-learning delete mode 100644 openedx/features/content_tagging/system_defined_taxonomies/object_tags.py diff --git a/openedx-learning b/openedx-learning new file mode 160000 index 000000000000..fd8d3c3e1266 --- /dev/null +++ b/openedx-learning @@ -0,0 +1 @@ +Subproject commit fd8d3c3e12666c7df36f44e071751e39810c225f diff --git a/openedx/features/content_tagging/fixtures/system_defined.yaml b/openedx/features/content_tagging/fixtures/system_defined.yaml index 6c3fd970a503..552a3651b7bb 100644 --- a/openedx/features/content_tagging/fixtures/system_defined.yaml +++ b/openedx/features/content_tagging/fixtures/system_defined.yaml @@ -7,8 +7,8 @@ required: true allow_multiple: false allow_free_text: false - system_defined: true visible_to_authors: true + _taxonomy_class: openedx.features.content_tagging.models.ContentLanguageTaxonomy - model: oel_tagging.taxonomy pk: -2 fields: @@ -17,9 +17,9 @@ enabled: true required: true allow_multiple: false - allow_free_text: true - system_defined: true + allow_free_text: false visible_to_authors: false + _taxonomy_class: openedx.features.content_tagging.models.ContentAuthorTaxonomy - model: oel_tagging.taxonomy pk: -3 fields: @@ -28,6 +28,6 @@ enabled: true required: true allow_multiple: false - allow_free_text: true - system_defined: true + allow_free_text: false visible_to_authors: false + _taxonomy_class: openedx.features.content_tagging.models.ContentOrganizationTaxonomy diff --git a/openedx/features/content_tagging/migrations/0002_system_defined_taxonomies.py b/openedx/features/content_tagging/migrations/0002_system_defined_taxonomies.py index 3ccca0cb1135..77ba980e7673 100644 --- a/openedx/features/content_tagging/migrations/0002_system_defined_taxonomies.py +++ b/openedx/features/content_tagging/migrations/0002_system_defined_taxonomies.py @@ -9,7 +9,6 @@ def load_system_defined_taxonomies(apps, schema_editor): """ # Create system defined taxonomy instances - call_command('loaddata', '--app=oel_tagging', 'system_defined.yaml') call_command('loaddata', '--app=content_tagging', 'system_defined.yaml') # Loads language tags @@ -21,11 +20,7 @@ def revert_system_defined_taxonomies(apps, schema_editor): Deletes all system defined taxonomies """ Taxonomy = apps.get_model('oel_tagging', 'Taxonomy') - Tag = apps.get_model('oel_tagging', 'Tag') - - # For some reason the tags are not deleted when deleting the taxonomy - Tag.objects.filter(taxonomy__system_defined=True).delete() - Taxonomy.objects.filter(system_defined=True).delete() + Taxonomy.objects.filter(id__lt=0).delete() class Migration(migrations.Migration): diff --git a/openedx/features/content_tagging/models/__init__.py b/openedx/features/content_tagging/models/__init__.py index e099dd487781..37d9a4cad235 100644 --- a/openedx/features/content_tagging/models/__init__.py +++ b/openedx/features/content_tagging/models/__init__.py @@ -3,3 +3,8 @@ ContentTag, ContentTaxonomy, ) +from .system_defined import ( + ContentLanguageTaxonomy, + ContentAuthorTaxonomy, + ContentOrganizationTaxonomy, +) diff --git a/openedx/features/content_tagging/models/system_defined.py b/openedx/features/content_tagging/models/system_defined.py index 6313f0ab8769..ba166f4ee2ed 100644 --- a/openedx/features/content_tagging/models/system_defined.py +++ b/openedx/features/content_tagging/models/system_defined.py @@ -1,9 +1,108 @@ """ System defined models """ +from typing import Type + from openedx_tagging.core.tagging.models import ( + ObjectTag, ModelSystemDefinedTaxonomy, ModelObjectTag, UserSystemDefinedTaxonomy, LanguageTaxonomy, ) + +from organizations.models import Organization +from .base import ContentTaxonomy + + +class OrganizationModelObjectTag(ModelObjectTag): + """ + ObjectTags for the OrganizarionSystemDefinedTaxonomy. + """ + + class Meta: + proxy = True + + @property + def tag_class_model(self) -> Type: + """ + Associate the organization model + """ + return Organization + + @property + def tag_class_value(self) -> str: + """ + Returns the organization name to use it on Tag.value when creating Tags for this taxonomy. + """ + return "name" + + +class OrganizarionSystemDefinedTaxonomy(ModelSystemDefinedTaxonomy): + """ + Organization based system taxonomy class. + """ + + class Meta: + proxy = True + + @property + def object_tag_class(self) -> Type: + """ + Returns OrganizationModelObjectTag as ObjectTag subclass associated with this taxonomy. + """ + return OrganizationModelObjectTag + + +class ContentLanguageTaxonomy( + ContentTaxonomy, + LanguageTaxonomy +): + """ + Language system-defined taxonomy that accepts ContentTags + + Inherit `_check_object` and `_check_taxonomy` from ContentTaxonomy + and inherit `_check_tag` from LanguageTaxonomy + """ + + class Meta: + proxy = True + + def _check_tag(self, object_tag: ObjectTag) -> bool: + return super(LanguageTaxonomy, self)._check_tag(object_tag) + + +class ContentAuthorTaxonomy( + ContentTaxonomy, + UserSystemDefinedTaxonomy +): + """ + Author system-defined taxonomy that accepts Content Tags + + Inherit `_check_object` and `_check_taxonomy` from ContentTaxonomy + and inherit `_check_tag` from UserSystemDefinedTaxonomy + """ + + class Meta: + proxy = True + + def _check_tag(self, object_tag: ObjectTag) -> bool: + return super(UserSystemDefinedTaxonomy, self)._check_tag(object_tag) + + +class ContentOrganizationTaxonomy( + ContentTaxonomy, + OrganizarionSystemDefinedTaxonomy +): + """ + Organization system-defined taxonomy that accepts Content Tags + + Inherit `_check_object` and `_check_taxonomy` from ContentTaxonomy + and inherit `_check_tag` from OrganizarionSystemDefinedTaxonomy + """ + + class Meta: + proxy = True + + def _check_tag(self, object_tag: ObjectTag) -> bool: + return super(OrganizarionSystemDefinedTaxonomy, self)._check_tag(object_tag) diff --git a/openedx/features/content_tagging/system_defined_taxonomies/object_tags.py b/openedx/features/content_tagging/system_defined_taxonomies/object_tags.py deleted file mode 100644 index 7bb339d40830..000000000000 --- a/openedx/features/content_tagging/system_defined_taxonomies/object_tags.py +++ /dev/null @@ -1,90 +0,0 @@ -""" -ObjectTags for System-defined Taxonomies -""" -from openedx_tagging.core.tagging.system_defined_taxonomies.object_tags import ( - SystemDefinedIds as TaxonomyIds, - ModelObjectTag, - UserObjectTag, - LanguageObjectTag, -) -from openedx_tagging.core.tagging.registry import register_object_tag_class -from organizations.models import Organization - -from ..models import CourseObjectTagMixin, BlockObjectTagMixin - - -class SystemDefinedIds(TaxonomyIds): - """ - System-defined taxonomy IDs - """ - OrganizationTaxonomy = 2 - AuthorTaxonomy = 3 - - -class OrganizationObjectTag(ModelObjectTag): - """ - ObjectTag used on Organization system-defined taxonomy - """ - - system_defined_taxonomy_id = SystemDefinedIds.OrganizationTaxonomy.value - - class Meta: - proxy = True - - tag_class_model = Organization - - -class AuthorObjcetTag(UserObjectTag): - """ - ObjectTag used on Author system-defined taxonomy - """ - - system_defined_taxonomy_id = SystemDefinedIds.AuthorTaxonomy.value - - class Meta: - proxy = True - - -class OrganizationCourseObjectTag(OrganizationObjectTag, CourseObjectTagMixin): - """ - CourseObjectTag for use in the Organization system-defined taxonomy - """ - - -class OrganizationBlockObjectTag(OrganizationObjectTag, BlockObjectTagMixin): - """ - BlockObjectTag for use in the Organization system-defined taxonomy - """ - - -class LanguageCourseObjectTag(LanguageObjectTag, CourseObjectTagMixin): - """ - CourseObjectTag for use in the Language system-defined taxonomy - """ - - -class LanguageBlockObjectTag(LanguageObjectTag, BlockObjectTagMixin): - """ - BlockObjectTag for use in the Language system-defined taxonomy - """ - - -class AuthorCourseObjectTag(AuthorObjcetTag, CourseObjectTagMixin): - """ - CourseObjectTag for use in the Author system-defined taxonomy - """ - - -class AuthorBlockObjectTag(AuthorObjcetTag, BlockObjectTagMixin): - """ - BlockObjectTag for use in the Author system-defined taxonomy - """ - - -# Register the object tag classes in reverse order for how we want them considered -register_object_tag_class(OrganizationCourseObjectTag) -register_object_tag_class(OrganizationBlockObjectTag) -register_object_tag_class(LanguageCourseObjectTag) -register_object_tag_class(LanguageBlockObjectTag) -register_object_tag_class(AuthorCourseObjectTag) -register_object_tag_class(AuthorBlockObjectTag) diff --git a/openedx/features/content_tagging/tests/test_rules.py b/openedx/features/content_tagging/tests/test_rules.py index 029657e44f23..a3ee0e07a131 100644 --- a/openedx/features/content_tagging/tests/test_rules.py +++ b/openedx/features/content_tagging/tests/test_rules.py @@ -3,7 +3,11 @@ import ddt from django.contrib.auth import get_user_model from django.test.testcases import TestCase, override_settings -from openedx_tagging.core.tagging.models import ObjectTag, Tag +from openedx_tagging.core.tagging.models import ( + ObjectTag, + Tag, + UserSystemDefinedTaxonomy, +) from organizations.models import Organization from common.djangoapps.student.auth import add_users, update_org_role @@ -136,7 +140,8 @@ def test_system_taxonomy(self, perm): system_taxonomy = api.create_taxonomy( name="System Languages", ) - system_taxonomy.system_defined = True + system_taxonomy.taxonomy_class = UserSystemDefinedTaxonomy + system_taxonomy = system_taxonomy.cast() assert self.superuser.has_perm(perm, system_taxonomy) assert not self.staff.has_perm(perm, system_taxonomy) assert not self.user_all_orgs.has_perm(perm, system_taxonomy) From f98325f829dd0b138df9c3adadc3c14c37d56b7f Mon Sep 17 00:00:00 2001 From: XnpioChV Date: Fri, 21 Jul 2023 16:52:11 -0500 Subject: [PATCH 04/13] style: Lint and migration --- ...tiontaxonomy_organizarionsystemdefinedt.py | 69 +++++++++++++++++++ .../content_tagging/models/__init__.py | 3 + .../content_tagging/tests/test_rules.py | 2 +- 3 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 openedx/features/content_tagging/migrations/0003_contentauthortaxonomy_contentlanguagetaxonomy_contentorganizationtaxonomy_organizarionsystemdefinedt.py diff --git a/openedx/features/content_tagging/migrations/0003_contentauthortaxonomy_contentlanguagetaxonomy_contentorganizationtaxonomy_organizarionsystemdefinedt.py b/openedx/features/content_tagging/migrations/0003_contentauthortaxonomy_contentlanguagetaxonomy_contentorganizationtaxonomy_organizarionsystemdefinedt.py new file mode 100644 index 000000000000..031eac2d586d --- /dev/null +++ b/openedx/features/content_tagging/migrations/0003_contentauthortaxonomy_contentlanguagetaxonomy_contentorganizationtaxonomy_organizarionsystemdefinedt.py @@ -0,0 +1,69 @@ +# Generated by Django 3.2.20 on 2023-07-21 21:50 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('oel_tagging', '0003_auto_20230721_1238'), + ('content_tagging', '0002_system_defined_taxonomies'), + ] + + operations = [ + migrations.CreateModel( + name='ContentAuthorTaxonomy', + fields=[ + ], + options={ + 'proxy': True, + 'indexes': [], + 'constraints': [], + }, + bases=('content_tagging.contenttaxonomy', 'oel_tagging.usersystemdefinedtaxonomy'), + ), + migrations.CreateModel( + name='ContentLanguageTaxonomy', + fields=[ + ], + options={ + 'proxy': True, + 'indexes': [], + 'constraints': [], + }, + bases=('content_tagging.contenttaxonomy', 'oel_tagging.languagetaxonomy'), + ), + migrations.CreateModel( + name='OrganizarionSystemDefinedTaxonomy', + fields=[ + ], + options={ + 'proxy': True, + 'indexes': [], + 'constraints': [], + }, + bases=('oel_tagging.modelsystemdefinedtaxonomy',), + ), + migrations.CreateModel( + name='OrganizationModelObjectTag', + fields=[ + ], + options={ + 'proxy': True, + 'indexes': [], + 'constraints': [], + }, + bases=('oel_tagging.modelobjecttag',), + ), + migrations.CreateModel( + name='ContentOrganizationTaxonomy', + fields=[ + ], + options={ + 'proxy': True, + 'indexes': [], + 'constraints': [], + }, + bases=('content_tagging.contenttaxonomy', 'content_tagging.organizarionsystemdefinedtaxonomy'), + ), + ] diff --git a/openedx/features/content_tagging/models/__init__.py b/openedx/features/content_tagging/models/__init__.py index 37d9a4cad235..389781b1ee57 100644 --- a/openedx/features/content_tagging/models/__init__.py +++ b/openedx/features/content_tagging/models/__init__.py @@ -1,3 +1,6 @@ +""" +Content Tagging and System defined models +""" from .base import ( TaxonomyOrg, ContentTag, diff --git a/openedx/features/content_tagging/tests/test_rules.py b/openedx/features/content_tagging/tests/test_rules.py index a3ee0e07a131..77dcc2270b28 100644 --- a/openedx/features/content_tagging/tests/test_rules.py +++ b/openedx/features/content_tagging/tests/test_rules.py @@ -7,7 +7,7 @@ ObjectTag, Tag, UserSystemDefinedTaxonomy, -) +) from organizations.models import Organization from common.djangoapps.student.auth import add_users, update_org_role From 9ceac724a0d6730239647554c9f832ec1cdcf477 Mon Sep 17 00:00:00 2001 From: XnpioChV Date: Sat, 22 Jul 2023 13:34:24 -0500 Subject: [PATCH 05/13] fix: Fix migration error --- ...t.py => 0003_system_defined_taxonomies.py} | 8 +-- .../content_tagging/models/system_defined.py | 54 ++++++++++--------- 2 files changed, 34 insertions(+), 28 deletions(-) rename openedx/features/content_tagging/migrations/{0003_contentauthortaxonomy_contentlanguagetaxonomy_contentorganizationtaxonomy_organizarionsystemdefinedt.py => 0003_system_defined_taxonomies.py} (82%) diff --git a/openedx/features/content_tagging/migrations/0003_contentauthortaxonomy_contentlanguagetaxonomy_contentorganizationtaxonomy_organizarionsystemdefinedt.py b/openedx/features/content_tagging/migrations/0003_system_defined_taxonomies.py similarity index 82% rename from openedx/features/content_tagging/migrations/0003_contentauthortaxonomy_contentlanguagetaxonomy_contentorganizationtaxonomy_organizarionsystemdefinedt.py rename to openedx/features/content_tagging/migrations/0003_system_defined_taxonomies.py index 031eac2d586d..6bee20ff3e5f 100644 --- a/openedx/features/content_tagging/migrations/0003_contentauthortaxonomy_contentlanguagetaxonomy_contentorganizationtaxonomy_organizarionsystemdefinedt.py +++ b/openedx/features/content_tagging/migrations/0003_system_defined_taxonomies.py @@ -1,4 +1,4 @@ -# Generated by Django 3.2.20 on 2023-07-21 21:50 +# Generated by Django 3.2.20 on 2023-07-22 18:30 from django.db import migrations @@ -20,7 +20,7 @@ class Migration(migrations.Migration): 'indexes': [], 'constraints': [], }, - bases=('content_tagging.contenttaxonomy', 'oel_tagging.usersystemdefinedtaxonomy'), + bases=('oel_tagging.usersystemdefinedtaxonomy',), ), migrations.CreateModel( name='ContentLanguageTaxonomy', @@ -31,7 +31,7 @@ class Migration(migrations.Migration): 'indexes': [], 'constraints': [], }, - bases=('content_tagging.contenttaxonomy', 'oel_tagging.languagetaxonomy'), + bases=('oel_tagging.languagetaxonomy',), ), migrations.CreateModel( name='OrganizarionSystemDefinedTaxonomy', @@ -64,6 +64,6 @@ class Migration(migrations.Migration): 'indexes': [], 'constraints': [], }, - bases=('content_tagging.contenttaxonomy', 'content_tagging.organizarionsystemdefinedtaxonomy'), + bases=('content_tagging.organizarionsystemdefinedtaxonomy',), ), ] diff --git a/openedx/features/content_tagging/models/system_defined.py b/openedx/features/content_tagging/models/system_defined.py index ba166f4ee2ed..fbee3be5f75d 100644 --- a/openedx/features/content_tagging/models/system_defined.py +++ b/openedx/features/content_tagging/models/system_defined.py @@ -54,55 +54,61 @@ def object_tag_class(self) -> Type: return OrganizationModelObjectTag -class ContentLanguageTaxonomy( - ContentTaxonomy, - LanguageTaxonomy -): +class ContentLanguageTaxonomy(LanguageTaxonomy): """ Language system-defined taxonomy that accepts ContentTags - Inherit `_check_object` and `_check_taxonomy` from ContentTaxonomy - and inherit `_check_tag` from LanguageTaxonomy + Inherit `_check_tag` from LanguageTaxonomy and uses + `_check_object` and `_check_taxonomy` from ContentTaxonomy """ class Meta: proxy = True - def _check_tag(self, object_tag: ObjectTag) -> bool: - return super(LanguageTaxonomy, self)._check_tag(object_tag) + 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( - ContentTaxonomy, - UserSystemDefinedTaxonomy -): + +class ContentAuthorTaxonomy(UserSystemDefinedTaxonomy): """ Author system-defined taxonomy that accepts Content Tags - Inherit `_check_object` and `_check_taxonomy` from ContentTaxonomy - and inherit `_check_tag` from UserSystemDefinedTaxonomy + Inherit `_check_tag` from UserSystemDefinedTaxonomy and uses + `_check_object` and `_check_taxonomy` from ContentTaxonomy """ class Meta: proxy = True - def _check_tag(self, object_tag: ObjectTag) -> bool: - return super(UserSystemDefinedTaxonomy, self)._check_tag(object_tag) + 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( - ContentTaxonomy, - OrganizarionSystemDefinedTaxonomy -): +class ContentOrganizationTaxonomy(OrganizarionSystemDefinedTaxonomy): """ Organization system-defined taxonomy that accepts Content Tags - Inherit `_check_object` and `_check_taxonomy` from ContentTaxonomy - and inherit `_check_tag` from OrganizarionSystemDefinedTaxonomy + Inherit `_check_tag` from OrganizarionSystemDefinedTaxonomy and uses + `_check_object` and `_check_taxonomy` from ContentTaxonomy """ class Meta: proxy = True - def _check_tag(self, object_tag: ObjectTag) -> bool: - return super(OrganizarionSystemDefinedTaxonomy, self)._check_tag(object_tag) + 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 From 778bf06f257bbcad804bd330a8bfa7b32397a8cb Mon Sep 17 00:00:00 2001 From: XnpioChV Date: Thu, 27 Jul 2023 12:34:21 -0500 Subject: [PATCH 06/13] chore: Rebase and compile requirements --- requirements/common_constraints.txt | 12 ++++++++++++ requirements/edx-sandbox/py38.txt | 2 +- requirements/edx/base.txt | 4 +++- requirements/edx/coverage.txt | 2 +- requirements/edx/development.txt | 3 ++- requirements/edx/doc.txt | 8 +------- requirements/edx/kernel.in | 2 +- requirements/edx/paver.txt | 2 +- requirements/edx/testing.txt | 2 +- requirements/pip-tools.txt | 2 +- requirements/pip.txt | 2 +- scripts/xblock/requirements.txt | 2 +- 12 files changed, 26 insertions(+), 17 deletions(-) diff --git a/requirements/common_constraints.txt b/requirements/common_constraints.txt index 13f8f7538b24..61644ff667fc 100644 --- a/requirements/common_constraints.txt +++ b/requirements/common_constraints.txt @@ -2,6 +2,18 @@ # In edx-lint, until the pyjwt constraint in edx-lint has been removed. # See BOM-2721 for more details. # Below is the copied and edited version of common_constraints +# This is a temporary solution to override the real common_constraints.txt +# In edx-lint, until the pyjwt constraint in edx-lint has been removed. +# See BOM-2721 for more details. +# Below is the copied and edited version of common_constraints +# This is a temporary solution to override the real common_constraints.txt +# In edx-lint, until the pyjwt constraint in edx-lint has been removed. +# See BOM-2721 for more details. +# Below is the copied and edited version of common_constraints +# This is a temporary solution to override the real common_constraints.txt +# In edx-lint, until the pyjwt constraint in edx-lint has been removed. +# See BOM-2721 for more details. +# Below is the copied and edited version of common_constraints # A central location for most common version constraints # (across edx repos) for pip-installation. # diff --git a/requirements/edx-sandbox/py38.txt b/requirements/edx-sandbox/py38.txt index b4d072b25845..75d319e57c13 100644 --- a/requirements/edx-sandbox/py38.txt +++ b/requirements/edx-sandbox/py38.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.10 +# This file is autogenerated by pip-compile with Python 3.8 # by the following command: # # make upgrade diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt index 62253e512dcd..67250d9d05ad 100644 --- a/requirements/edx/base.txt +++ b/requirements/edx/base.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.10 +# This file is autogenerated by pip-compile with Python 3.8 # by the following command: # # make upgrade @@ -819,6 +819,8 @@ pillow==9.5.0 # edx-enterprise # edx-organizations # edxval +pkgutil-resolve-name==1.3.10 + # via jsonschema polib==1.2.0 # via edx-i18n-tools prompt-toolkit==3.0.39 diff --git a/requirements/edx/coverage.txt b/requirements/edx/coverage.txt index a04c6666a786..c0b44e4fdd79 100644 --- a/requirements/edx/coverage.txt +++ b/requirements/edx/coverage.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.10 +# This file is autogenerated by pip-compile with Python 3.8 # by the following command: # # make upgrade diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt index afaf3b6a56ce..743938fb1773 100644 --- a/requirements/edx/development.txt +++ b/requirements/edx/development.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.10 +# This file is autogenerated by pip-compile with Python 3.8 # by the following command: # # make upgrade @@ -2070,6 +2070,7 @@ typing-extensions==4.7.1 # pydantic # pydantic-core # pydata-sphinx-theme + # pylint # pylti1p3 # snowflake-connector-python # starlette diff --git a/requirements/edx/doc.txt b/requirements/edx/doc.txt index 394a175e9828..3b584a4bee5e 100644 --- a/requirements/edx/doc.txt +++ b/requirements/edx/doc.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.10 +# This file is autogenerated by pip-compile with Python 3.8 # by the following command: # # make upgrade @@ -707,7 +707,6 @@ idna==3.4 # yarl imagesize==1.4.1 # via sphinx -<<<<<<< HEAD importlib-metadata==6.8.0 # via # -r requirements/edx/base.txt @@ -736,8 +735,6 @@ itypes==1.2.0 # via # -r requirements/edx/base.txt # coreapi -======= ->>>>>>> 70004ccb4e (feat: System defined taxonomies) jinja2==3.1.2 # via # -r requirements/edx/base.txt @@ -1407,7 +1404,6 @@ urllib3==1.26.16 # elasticsearch # py2neo # requests -<<<<<<< HEAD # snowflake-connector-python user-util==1.0.0 # via -r requirements/edx/base.txt @@ -1502,5 +1498,3 @@ zipp==3.16.2 # The following packages are considered to be unsafe in a requirements file: # setuptools -======= ->>>>>>> 70004ccb4e (feat: System defined taxonomies) diff --git a/requirements/edx/kernel.in b/requirements/edx/kernel.in index 8929520ea819..ad4cf82bbf5e 100644 --- a/requirements/edx/kernel.in +++ b/requirements/edx/kernel.in @@ -115,7 +115,7 @@ openedx-calc # Library supporting mathematical calculatio openedx-django-require openedx-events>=8.3.0 # Open edX Events from Hooks Extension Framework (OEP-50) openedx-filters # Open edX Filters from Hooks Extension Framework (OEP-50) -openedx-learning<=0.1 +openedx-learning>=0.1.1 openedx-mongodbproxy openedx-django-wiki openedx-blockstore diff --git a/requirements/edx/paver.txt b/requirements/edx/paver.txt index 77551eaa59b2..ae5a7829252d 100644 --- a/requirements/edx/paver.txt +++ b/requirements/edx/paver.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.10 +# This file is autogenerated by pip-compile with Python 3.8 # by the following command: # # make upgrade diff --git a/requirements/edx/testing.txt b/requirements/edx/testing.txt index 1184bfd12886..7165c677dc35 100644 --- a/requirements/edx/testing.txt +++ b/requirements/edx/testing.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.10 +# This file is autogenerated by pip-compile with Python 3.8 # by the following command: # # make upgrade diff --git a/requirements/pip-tools.txt b/requirements/pip-tools.txt index a7104310df20..1db6c3427e2c 100644 --- a/requirements/pip-tools.txt +++ b/requirements/pip-tools.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.10 +# This file is autogenerated by pip-compile with Python 3.8 # by the following command: # # make upgrade diff --git a/requirements/pip.txt b/requirements/pip.txt index 9a5e0788e109..fb1908e60d73 100644 --- a/requirements/pip.txt +++ b/requirements/pip.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.10 +# This file is autogenerated by pip-compile with Python 3.8 # by the following command: # # make upgrade diff --git a/scripts/xblock/requirements.txt b/scripts/xblock/requirements.txt index 8348c1f1b4a8..c7433da88f84 100644 --- a/scripts/xblock/requirements.txt +++ b/scripts/xblock/requirements.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.10 +# This file is autogenerated by pip-compile with Python 3.8 # by the following command: # # make upgrade From 86191206e9a9ee262a7b66b6a7ed3a647528f80f Mon Sep 17 00:00:00 2001 From: Jillian Vogel Date: Mon, 24 Jul 2023 11:31:41 +0930 Subject: [PATCH 07/13] refactor: adds ContentTaxonomyMixin for use when creating content system taxonomies Pulls the ContentTaxonomy-specific logic into a mixin class to bring the Content-specific logic into other Taxonony subclasses. --- .../0003_system_defined_taxonomies.py | 19 ++++---- .../features/content_tagging/models/base.py | 24 +++++++++-- .../content_tagging/models/system_defined.py | 43 +++---------------- requirements/common_constraints.txt | 4 ++ requirements/edx/base.txt | 2 +- requirements/edx/development.txt | 2 +- requirements/edx/doc.txt | 2 +- requirements/edx/kernel.in | 2 +- requirements/edx/testing.txt | 2 +- 9 files changed, 45 insertions(+), 55 deletions(-) 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 240446c1d680..b84a3f11290c 100644 --- a/openedx/features/content_tagging/models/base.py +++ b/openedx/features/content_tagging/models/base.py @@ -13,6 +13,7 @@ from openedx_tagging.core.tagging.models import ( ObjectTag, + Taxonomy, ) @@ -110,15 +111,21 @@ def object_key(self) -> Union[BlockUsageLocator, LearningContextKey]: return BlockUsageLocator.from_string(str(self.object_id)) -class ContentTaxonomy(Taxonomy): +class ContentTaxonomyMixin: """ Taxonomy which can only tag Content objects (e.g. XBlocks or Courses) via ContentObjectTag. Also 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 ContentObjectTag @classmethod def taxonomies_for_org( @@ -128,7 +135,6 @@ def taxonomies_for_org( ) -> QuerySet: """ Filters the given QuerySet to those ContentTaxonomies which are available for the given organization. - If no `org` is provided, then only ContentTaxonomies available to all organizations are returned. If `org` is provided, then ContentTaxonomies available to this organizations are also returned. """ @@ -170,3 +176,13 @@ def _check_taxonomy(self, object_tag: ObjectTag) -> bool: ).exists(): return False return super()._check_taxonomy(content_tag) + + +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 diff --git a/requirements/common_constraints.txt b/requirements/common_constraints.txt index 61644ff667fc..9647d0f8017d 100644 --- a/requirements/common_constraints.txt +++ b/requirements/common_constraints.txt @@ -14,6 +14,10 @@ # In edx-lint, until the pyjwt constraint in edx-lint has been removed. # See BOM-2721 for more details. # Below is the copied and edited version of common_constraints +# This is a temporary solution to override the real common_constraints.txt +# In edx-lint, until the pyjwt constraint in edx-lint has been removed. +# See BOM-2721 for more details. +# Below is the copied and edited version of common_constraints # A central location for most common version constraints # (across edx repos) for pip-installation. # diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt index 67250d9d05ad..a3648d19f8a9 100644 --- a/requirements/edx/base.txt +++ b/requirements/edx/base.txt @@ -773,7 +773,7 @@ openedx-filters==1.4.0 # -r requirements/edx/kernel.in # lti-consumer-xblock # skill-tagging -openedx-learning==0.1.0 +openedx-learning @ git+https://github.com/open-craft/openedx-learning.git@chris/system-defined-taxonomies # via -r requirements/edx/kernel.in openedx-mongodbproxy==0.2.0 # via -r requirements/edx/kernel.in diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt index 743938fb1773..1a7ff004bf28 100644 --- a/requirements/edx/development.txt +++ b/requirements/edx/development.txt @@ -1307,7 +1307,7 @@ openedx-filters==1.4.0 # -r requirements/edx/testing.txt # lti-consumer-xblock # skill-tagging -openedx-learning==0.1.0 +openedx-learning @ git+https://github.com/open-craft/openedx-learning.git@chris/system-defined-taxonomies # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt diff --git a/requirements/edx/doc.txt b/requirements/edx/doc.txt index 3b584a4bee5e..9d3590d376f9 100644 --- a/requirements/edx/doc.txt +++ b/requirements/edx/doc.txt @@ -916,7 +916,7 @@ openedx-filters==1.4.0 # -r requirements/edx/base.txt # lti-consumer-xblock # skill-tagging -openedx-learning==0.1.0 +openedx-learning @ git+https://github.com/open-craft/openedx-learning.git@chris/system-defined-taxonomies # via -r requirements/edx/base.txt openedx-mongodbproxy==0.2.0 # via -r requirements/edx/base.txt diff --git a/requirements/edx/kernel.in b/requirements/edx/kernel.in index ad4cf82bbf5e..204eaabb3307 100644 --- a/requirements/edx/kernel.in +++ b/requirements/edx/kernel.in @@ -115,7 +115,7 @@ openedx-calc # Library supporting mathematical calculatio openedx-django-require openedx-events>=8.3.0 # Open edX Events from Hooks Extension Framework (OEP-50) openedx-filters # Open edX Filters from Hooks Extension Framework (OEP-50) -openedx-learning>=0.1.1 +git+https://github.com/open-craft/openedx-learning.git@chris/system-defined-taxonomies#egg=openedx-learning openedx-mongodbproxy openedx-django-wiki openedx-blockstore diff --git a/requirements/edx/testing.txt b/requirements/edx/testing.txt index 7165c677dc35..6950237c4a34 100644 --- a/requirements/edx/testing.txt +++ b/requirements/edx/testing.txt @@ -985,7 +985,7 @@ openedx-filters==1.4.0 # -r requirements/edx/base.txt # lti-consumer-xblock # skill-tagging -openedx-learning==0.1.0 +openedx-learning @ git+https://github.com/open-craft/openedx-learning.git@chris/system-defined-taxonomies # via -r requirements/edx/base.txt openedx-mongodbproxy==0.2.0 # via -r requirements/edx/base.txt From 8c6926a8a7892cd966e7367f5617f807f8d7da38 Mon Sep 17 00:00:00 2001 From: XnpioChV Date: Mon, 24 Jul 2023 13:52:34 -0500 Subject: [PATCH 08/13] fix: Tests --- openedx/features/content_tagging/models/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openedx/features/content_tagging/models/base.py b/openedx/features/content_tagging/models/base.py index b84a3f11290c..9901c63b7abd 100644 --- a/openedx/features/content_tagging/models/base.py +++ b/openedx/features/content_tagging/models/base.py @@ -1,7 +1,7 @@ """ Content Tagging models """ -from typing import List, Union +from typing import List, Union, Type from django.db import models from django.db.models import Exists, OuterRef, Q, QuerySet From 1061e42a3f65bb548e1f213eb69bd8f48bf1a984 Mon Sep 17 00:00:00 2001 From: XnpioChV Date: Mon, 24 Jul 2023 18:09:41 -0500 Subject: [PATCH 09/13] test: System defined model validations --- openedx-learning | 1 - .../content_tagging/models/__init__.py | 2 +- .../features/content_tagging/models/base.py | 19 +---- .../content_tagging/models/system_defined.py | 3 - .../content_tagging/tests/test_models.py | 71 +++++++++++++++++++ requirements/common_constraints.txt | 16 ----- 6 files changed, 74 insertions(+), 38 deletions(-) delete mode 160000 openedx-learning create mode 100644 openedx/features/content_tagging/tests/test_models.py diff --git a/openedx-learning b/openedx-learning deleted file mode 160000 index fd8d3c3e1266..000000000000 --- a/openedx-learning +++ /dev/null @@ -1 +0,0 @@ -Subproject commit fd8d3c3e12666c7df36f44e071751e39810c225f diff --git a/openedx/features/content_tagging/models/__init__.py b/openedx/features/content_tagging/models/__init__.py index 389781b1ee57..dc748c355b2d 100644 --- a/openedx/features/content_tagging/models/__init__.py +++ b/openedx/features/content_tagging/models/__init__.py @@ -3,7 +3,7 @@ """ from .base import ( TaxonomyOrg, - ContentTag, + ContentObjectTag, ContentTaxonomy, ) from .system_defined import ( diff --git a/openedx/features/content_tagging/models/base.py b/openedx/features/content_tagging/models/base.py index 9901c63b7abd..255d3852fa47 100644 --- a/openedx/features/content_tagging/models/base.py +++ b/openedx/features/content_tagging/models/base.py @@ -1,7 +1,7 @@ """ Content Tagging models """ -from typing import List, Union, Type +from typing import List, Union from django.db import models from django.db.models import Exists, OuterRef, Q, QuerySet @@ -10,13 +10,6 @@ from opaque_keys.edx.keys import LearningContextKey from opaque_keys.edx.locator import BlockUsageLocator from openedx_tagging.core.tagging.models import ObjectTag, Taxonomy - -from openedx_tagging.core.tagging.models import ( - ObjectTag, - - Taxonomy, -) - from organizations.models import Organization @@ -118,15 +111,6 @@ class ContentTaxonomyMixin: Also ensures a valid TaxonomyOrg owner relationship with the content object. """ - @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 ContentObjectTag - @classmethod def taxonomies_for_org( cls, @@ -135,6 +119,7 @@ def taxonomies_for_org( ) -> QuerySet: """ Filters the given QuerySet to those ContentTaxonomies which are available for the given organization. + If no `org` is provided, then only ContentTaxonomies available to all organizations are returned. If `org` is provided, then ContentTaxonomies available to this organizations are also returned. """ diff --git a/openedx/features/content_tagging/models/system_defined.py b/openedx/features/content_tagging/models/system_defined.py index 1b187aa0b7b5..86b430346abb 100644 --- a/openedx/features/content_tagging/models/system_defined.py +++ b/openedx/features/content_tagging/models/system_defined.py @@ -62,7 +62,6 @@ class Meta: proxy = True - class ContentAuthorTaxonomy(ContentTaxonomyMixin, UserSystemDefinedTaxonomy): """ Author system-defined taxonomy that accepts Content Tags @@ -72,7 +71,6 @@ class Meta: proxy = True - class ContentOrganizationTaxonomy(ContentTaxonomyMixin, OrganizationSystemDefinedTaxonomy): """ Organization system-defined taxonomy that accepts Content Tags @@ -80,4 +78,3 @@ class ContentOrganizationTaxonomy(ContentTaxonomyMixin, OrganizationSystemDefine class Meta: proxy = True - diff --git a/openedx/features/content_tagging/tests/test_models.py b/openedx/features/content_tagging/tests/test_models.py new file mode 100644 index 000000000000..d8a8730a5e98 --- /dev/null +++ b/openedx/features/content_tagging/tests/test_models.py @@ -0,0 +1,71 @@ +""" +Test for Content models +""" +import ddt +from django.test.testcases import TestCase + +from openedx_tagging.core.tagging.models import ( + ObjectTag, + Taxonomy, + Tag, +) +from ..models import ( + ContentLanguageTaxonomy, + ContentAuthorTaxonomy, + ContentOrganizationTaxonomy, +) + + +@ddt.ddt +class TestSystemDefinedModels(TestCase): + """ + Test for System defined models + """ + + @ddt.data( + (ContentLanguageTaxonomy, "taxonomy"), # Invalid object key + (ContentLanguageTaxonomy, "tag"), # Invalid external_id, invalid language + (ContentLanguageTaxonomy, "object"), # Invalid object key + (ContentAuthorTaxonomy, "taxonomy"), # Invalid object key + (ContentAuthorTaxonomy, "tag"), # Invalid external_id, User don't exits + (ContentAuthorTaxonomy, "object"), # Invalid object key + (ContentOrganizationTaxonomy, "taxonomy"), # Invalid object key + (ContentOrganizationTaxonomy, "tag"), # Invalid external_id, Organization don't exits + (ContentOrganizationTaxonomy, "object"), # Invalid object key + ) + @ddt.unpack + def test_validations( + self, + taxonomy_cls, + check, + ): + """ + Test that the respective validations are being called + """ + taxonomy = Taxonomy( + name='Test taxonomy' + ) + taxonomy.taxonomy_class = taxonomy_cls + taxonomy.save() + taxonomy = taxonomy.cast() + tag = Tag( + value="value", + external_id="external_id", + ) + tag.taxonomy = taxonomy + tag.save() + object_tag = ObjectTag( + object_id='object_id', + taxonomy=taxonomy, + tag=tag, + ) + + check_taxonomy = check == 'taxonomy' + check_object = check == 'object' + check_tag = check == 'tag' + assert not taxonomy.validate_object_tag( + object_tag=object_tag, + check_taxonomy=check_taxonomy, + check_object=check_object, + check_tag=check_tag, + ) diff --git a/requirements/common_constraints.txt b/requirements/common_constraints.txt index 9647d0f8017d..13f8f7538b24 100644 --- a/requirements/common_constraints.txt +++ b/requirements/common_constraints.txt @@ -2,22 +2,6 @@ # In edx-lint, until the pyjwt constraint in edx-lint has been removed. # See BOM-2721 for more details. # Below is the copied and edited version of common_constraints -# This is a temporary solution to override the real common_constraints.txt -# In edx-lint, until the pyjwt constraint in edx-lint has been removed. -# See BOM-2721 for more details. -# Below is the copied and edited version of common_constraints -# This is a temporary solution to override the real common_constraints.txt -# In edx-lint, until the pyjwt constraint in edx-lint has been removed. -# See BOM-2721 for more details. -# Below is the copied and edited version of common_constraints -# This is a temporary solution to override the real common_constraints.txt -# In edx-lint, until the pyjwt constraint in edx-lint has been removed. -# See BOM-2721 for more details. -# Below is the copied and edited version of common_constraints -# This is a temporary solution to override the real common_constraints.txt -# In edx-lint, until the pyjwt constraint in edx-lint has been removed. -# See BOM-2721 for more details. -# Below is the copied and edited version of common_constraints # A central location for most common version constraints # (across edx repos) for pip-installation. # From c96b78fd9f915396a016c16e32a39f2c0686af1c Mon Sep 17 00:00:00 2001 From: XnpioChV Date: Mon, 31 Jul 2023 16:02:49 -0500 Subject: [PATCH 10/13] fix: Move language taxonomy creation to openedx-learning --- .../fixtures/system_defined.yaml | 11 --- .../0002_system_defined_taxonomies.py | 80 ++++++++++++----- .../0003_system_defined_taxonomies.py | 85 ++++++------------- 3 files changed, 85 insertions(+), 91 deletions(-) diff --git a/openedx/features/content_tagging/fixtures/system_defined.yaml b/openedx/features/content_tagging/fixtures/system_defined.yaml index 552a3651b7bb..07445346272f 100644 --- a/openedx/features/content_tagging/fixtures/system_defined.yaml +++ b/openedx/features/content_tagging/fixtures/system_defined.yaml @@ -1,14 +1,3 @@ -- model: oel_tagging.taxonomy - pk: -1 - fields: - name: Languages - description: ISO 639-1 Languages. Allows tags for any language configured for use on the instance - enabled: true - required: true - allow_multiple: false - allow_free_text: false - visible_to_authors: true - _taxonomy_class: openedx.features.content_tagging.models.ContentLanguageTaxonomy - model: oel_tagging.taxonomy pk: -2 fields: diff --git a/openedx/features/content_tagging/migrations/0002_system_defined_taxonomies.py b/openedx/features/content_tagging/migrations/0002_system_defined_taxonomies.py index 77ba980e7673..6cb237252844 100644 --- a/openedx/features/content_tagging/migrations/0002_system_defined_taxonomies.py +++ b/openedx/features/content_tagging/migrations/0002_system_defined_taxonomies.py @@ -1,34 +1,70 @@ -# Generated by Django 3.2.20 on 2023-07-11 22:57 +# Generated by Django 3.2.20 on 2023-07-24 01:58 from django.db import migrations -from django.core.management import call_command - -def load_system_defined_taxonomies(apps, schema_editor): - """ - Creates system defined taxonomies and loads tags - """ - - # Create system defined taxonomy instances - call_command('loaddata', '--app=content_tagging', 'system_defined.yaml') - - # Loads language tags - call_command('loaddata', '--app=oel_tagging', 'language_taxonomy.yaml') - - -def revert_system_defined_taxonomies(apps, schema_editor): - """ - Deletes all system defined taxonomies - """ - Taxonomy = apps.get_model('oel_tagging', 'Taxonomy') - Taxonomy.objects.filter(id__lt=0).delete() +import openedx.features.content_tagging.models.base class Migration(migrations.Migration): dependencies = [ + ('oel_tagging', '__latest__'), ('content_tagging', '0001_initial'), ] operations = [ - migrations.RunPython(load_system_defined_taxonomies, revert_system_defined_taxonomies), + migrations.CreateModel( + name='ContentAuthorTaxonomy', + fields=[ + ], + options={ + 'proxy': True, + 'indexes': [], + 'constraints': [], + }, + bases=(openedx.features.content_tagging.models.base.ContentTaxonomyMixin, 'oel_tagging.usersystemdefinedtaxonomy'), + ), + migrations.CreateModel( + name='ContentLanguageTaxonomy', + fields=[ + ], + options={ + 'proxy': True, + 'indexes': [], + 'constraints': [], + }, + bases=(openedx.features.content_tagging.models.base.ContentTaxonomyMixin, 'oel_tagging.languagetaxonomy'), + ), + migrations.CreateModel( + name='OrganizationModelObjectTag', + fields=[ + ], + options={ + 'proxy': True, + 'indexes': [], + 'constraints': [], + }, + bases=('oel_tagging.modelobjecttag',), + ), + migrations.CreateModel( + name='OrganizationSystemDefinedTaxonomy', + fields=[ + ], + options={ + 'proxy': True, + 'indexes': [], + 'constraints': [], + }, + bases=('oel_tagging.modelsystemdefinedtaxonomy',), + ), + migrations.CreateModel( + name='ContentOrganizationTaxonomy', + fields=[ + ], + options={ + 'proxy': True, + 'indexes': [], + 'constraints': [], + }, + bases=(openedx.features.content_tagging.models.base.ContentTaxonomyMixin, 'content_tagging.organizationsystemdefinedtaxonomy'), + ), ] 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 53e0d7046466..c155b341518c 100644 --- a/openedx/features/content_tagging/migrations/0003_system_defined_taxonomies.py +++ b/openedx/features/content_tagging/migrations/0003_system_defined_taxonomies.py @@ -1,70 +1,39 @@ -# Generated by Django 3.2.20 on 2023-07-24 01:58 +# Generated by Django 3.2.20 on 2023-07-11 22:57 from django.db import migrations -import openedx.features.content_tagging.models.base +from django.core.management import call_command +from openedx.features.content_tagging.models import ContentLanguageTaxonomy + + +def load_system_defined_taxonomies(apps, schema_editor): + """ + Creates system defined taxonomies + """ + + # Create system defined taxonomy instances + call_command('loaddata', '--app=content_tagging', 'system_defined.yaml') + + # Adding taxonomy class to the language taxonomy + Taxonomy = apps.get_model('oel_tagging', 'Taxonomy') + language_taxonomy = Taxonomy.objects.get(id=-1) + language_taxonomy.taxonomy_class = ContentLanguageTaxonomy + + +def revert_system_defined_taxonomies(apps, schema_editor): + """ + Deletes all system defined taxonomies + """ + Taxonomy = apps.get_model('oel_tagging', 'Taxonomy') + Taxonomy.objects.get(id=-2).delete() + Taxonomy.objects.get(id=-3).delete() class Migration(migrations.Migration): dependencies = [ - ('oel_tagging', '__latest__'), ('content_tagging', '0002_system_defined_taxonomies'), ] operations = [ - migrations.CreateModel( - name='ContentAuthorTaxonomy', - fields=[ - ], - options={ - 'proxy': True, - 'indexes': [], - 'constraints': [], - }, - bases=(openedx.features.content_tagging.models.base.ContentTaxonomyMixin, 'oel_tagging.usersystemdefinedtaxonomy'), - ), - migrations.CreateModel( - name='ContentLanguageTaxonomy', - fields=[ - ], - options={ - 'proxy': True, - 'indexes': [], - 'constraints': [], - }, - bases=(openedx.features.content_tagging.models.base.ContentTaxonomyMixin, 'oel_tagging.languagetaxonomy'), - ), - migrations.CreateModel( - name='OrganizationModelObjectTag', - fields=[ - ], - options={ - 'proxy': True, - 'indexes': [], - 'constraints': [], - }, - bases=('oel_tagging.modelobjecttag',), - ), - migrations.CreateModel( - name='OrganizationSystemDefinedTaxonomy', - fields=[ - ], - options={ - 'proxy': True, - 'indexes': [], - 'constraints': [], - }, - bases=('oel_tagging.modelsystemdefinedtaxonomy',), - ), - migrations.CreateModel( - name='ContentOrganizationTaxonomy', - fields=[ - ], - options={ - 'proxy': True, - 'indexes': [], - 'constraints': [], - }, - bases=(openedx.features.content_tagging.models.base.ContentTaxonomyMixin, 'content_tagging.organizationsystemdefinedtaxonomy'), - ), + migrations.RunPython(load_system_defined_taxonomies, revert_system_defined_taxonomies), ] From 4e8af725b00ed98dcfadc2543989d6193a0f70a0 Mon Sep 17 00:00:00 2001 From: XnpioChV Date: Mon, 31 Jul 2023 16:26:47 -0500 Subject: [PATCH 11/13] style: Rename of OrganizationSystemDefinedTaxonomy --- .../0002_system_defined_taxonomies.py | 23 +++++-------------- ...mies.py => 0003_system_defined_fixture.py} | 0 .../content_tagging/models/system_defined.py | 19 ++++++--------- 3 files changed, 13 insertions(+), 29 deletions(-) rename openedx/features/content_tagging/migrations/{0003_system_defined_taxonomies.py => 0003_system_defined_fixture.py} (100%) diff --git a/openedx/features/content_tagging/migrations/0002_system_defined_taxonomies.py b/openedx/features/content_tagging/migrations/0002_system_defined_taxonomies.py index 6cb237252844..c743a70ce24c 100644 --- a/openedx/features/content_tagging/migrations/0002_system_defined_taxonomies.py +++ b/openedx/features/content_tagging/migrations/0002_system_defined_taxonomies.py @@ -1,4 +1,4 @@ -# Generated by Django 3.2.20 on 2023-07-24 01:58 +# Generated by Django 3.2.20 on 2023-07-31 21:07 from django.db import migrations import openedx.features.content_tagging.models.base @@ -7,7 +7,7 @@ class Migration(migrations.Migration): dependencies = [ - ('oel_tagging', '__latest__'), + ('oel_tagging', '0005_language_taxonomy'), ('content_tagging', '0001_initial'), ] @@ -35,18 +35,7 @@ class Migration(migrations.Migration): bases=(openedx.features.content_tagging.models.base.ContentTaxonomyMixin, 'oel_tagging.languagetaxonomy'), ), migrations.CreateModel( - name='OrganizationModelObjectTag', - fields=[ - ], - options={ - 'proxy': True, - 'indexes': [], - 'constraints': [], - }, - bases=('oel_tagging.modelobjecttag',), - ), - migrations.CreateModel( - name='OrganizationSystemDefinedTaxonomy', + name='ContentOrganizationTaxonomy', fields=[ ], options={ @@ -54,10 +43,10 @@ class Migration(migrations.Migration): 'indexes': [], 'constraints': [], }, - bases=('oel_tagging.modelsystemdefinedtaxonomy',), + bases=(openedx.features.content_tagging.models.base.ContentTaxonomyMixin, 'oel_tagging.modelsystemdefinedtaxonomy'), ), migrations.CreateModel( - name='ContentOrganizationTaxonomy', + name='OrganizationModelObjectTag', fields=[ ], options={ @@ -65,6 +54,6 @@ class Migration(migrations.Migration): 'indexes': [], 'constraints': [], }, - bases=(openedx.features.content_tagging.models.base.ContentTaxonomyMixin, 'content_tagging.organizationsystemdefinedtaxonomy'), + bases=('oel_tagging.modelobjecttag',), ), ] diff --git a/openedx/features/content_tagging/migrations/0003_system_defined_taxonomies.py b/openedx/features/content_tagging/migrations/0003_system_defined_fixture.py similarity index 100% rename from openedx/features/content_tagging/migrations/0003_system_defined_taxonomies.py rename to openedx/features/content_tagging/migrations/0003_system_defined_fixture.py diff --git a/openedx/features/content_tagging/models/system_defined.py b/openedx/features/content_tagging/models/system_defined.py index 86b430346abb..d9dbf7c04e9a 100644 --- a/openedx/features/content_tagging/models/system_defined.py +++ b/openedx/features/content_tagging/models/system_defined.py @@ -37,9 +37,13 @@ def tag_class_value(self) -> str: return "name" -class OrganizationSystemDefinedTaxonomy(ModelSystemDefinedTaxonomy): +class ContentOrganizationTaxonomy(ContentTaxonomyMixin, ModelSystemDefinedTaxonomy): """ - Organization based system taxonomy class. + Organization system-defined taxonomy that accepts ContentTags + + Side note: The organizatiob of an object is already encoded in its usage ID, + but a Taxonomy with Organization as Tags is being used so that the objects can be + indexed and can be filtered in the same tagging system, without any special casing. """ class Meta: @@ -64,16 +68,7 @@ class Meta: class ContentAuthorTaxonomy(ContentTaxonomyMixin, UserSystemDefinedTaxonomy): """ - Author system-defined taxonomy that accepts Content Tags - """ - - class Meta: - proxy = True - - -class ContentOrganizationTaxonomy(ContentTaxonomyMixin, OrganizationSystemDefinedTaxonomy): - """ - Organization system-defined taxonomy that accepts Content Tags + Author system-defined taxonomy that accepts ContentTags """ class Meta: From 51f2fc5eb78c3626a37f46498eab14982b2263db Mon Sep 17 00:00:00 2001 From: XnpioChV Date: Tue, 1 Aug 2023 14:15:17 -0500 Subject: [PATCH 12/13] style: nits --- .../content_tagging/models/system_defined.py | 2 +- .../features/content_tagging/tests/test_models.py | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/openedx/features/content_tagging/models/system_defined.py b/openedx/features/content_tagging/models/system_defined.py index d9dbf7c04e9a..642e1c08b03d 100644 --- a/openedx/features/content_tagging/models/system_defined.py +++ b/openedx/features/content_tagging/models/system_defined.py @@ -41,7 +41,7 @@ class ContentOrganizationTaxonomy(ContentTaxonomyMixin, ModelSystemDefinedTaxono """ Organization system-defined taxonomy that accepts ContentTags - Side note: The organizatiob of an object is already encoded in its usage ID, + Side note: The organization of an object is already encoded in its usage ID, but a Taxonomy with Organization as Tags is being used so that the objects can be indexed and can be filtered in the same tagging system, without any special casing. """ diff --git a/openedx/features/content_tagging/tests/test_models.py b/openedx/features/content_tagging/tests/test_models.py index d8a8730a5e98..a0b358ea3131 100644 --- a/openedx/features/content_tagging/tests/test_models.py +++ b/openedx/features/content_tagging/tests/test_models.py @@ -6,9 +6,9 @@ from openedx_tagging.core.tagging.models import ( ObjectTag, - Taxonomy, Tag, ) +from openedx_tagging.core.tagging.api import create_taxonomy from ..models import ( ContentLanguageTaxonomy, ContentAuthorTaxonomy, @@ -42,18 +42,18 @@ def test_validations( """ Test that the respective validations are being called """ - taxonomy = Taxonomy( - name='Test taxonomy' + taxonomy = create_taxonomy( + name='Test taxonomy', + taxonomy_class=taxonomy_cls, ) - taxonomy.taxonomy_class = taxonomy_cls - taxonomy.save() - taxonomy = taxonomy.cast() + tag = Tag( value="value", external_id="external_id", + taxonomy=taxonomy, ) - tag.taxonomy = taxonomy tag.save() + object_tag = ObjectTag( object_id='object_id', taxonomy=taxonomy, From 9bf369867f06410cb1eb7423df4282db73576585 Mon Sep 17 00:00:00 2001 From: XnpioChV Date: Wed, 2 Aug 2023 13:16:06 -0500 Subject: [PATCH 13/13] chore: Update openedx-learning dependency --- requirements/edx/base.txt | 2 +- requirements/edx/development.txt | 3 ++- requirements/edx/doc.txt | 4 ++-- requirements/edx/kernel.in | 2 +- requirements/edx/testing.txt | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt index a3648d19f8a9..3a051ffb1613 100644 --- a/requirements/edx/base.txt +++ b/requirements/edx/base.txt @@ -773,7 +773,7 @@ openedx-filters==1.4.0 # -r requirements/edx/kernel.in # lti-consumer-xblock # skill-tagging -openedx-learning @ git+https://github.com/open-craft/openedx-learning.git@chris/system-defined-taxonomies +openedx-learning==0.1.1 # via -r requirements/edx/kernel.in openedx-mongodbproxy==0.2.0 # via -r requirements/edx/kernel.in diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt index 1a7ff004bf28..6283b5cebe6a 100644 --- a/requirements/edx/development.txt +++ b/requirements/edx/development.txt @@ -1307,7 +1307,7 @@ openedx-filters==1.4.0 # -r requirements/edx/testing.txt # lti-consumer-xblock # skill-tagging -openedx-learning @ git+https://github.com/open-craft/openedx-learning.git@chris/system-defined-taxonomies +openedx-learning==0.1.1 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt @@ -2138,6 +2138,7 @@ walrus==0.9.3 # edx-event-bus-redis watchdog==3.0.0 # via + # -r requirements/edx/development.in # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt wcwidth==0.2.6 diff --git a/requirements/edx/doc.txt b/requirements/edx/doc.txt index 9d3590d376f9..fb7ae3c8901b 100644 --- a/requirements/edx/doc.txt +++ b/requirements/edx/doc.txt @@ -556,7 +556,7 @@ edx-drf-extensions==8.8.0 # edx-rbac # edx-when # edxval -edx-enterprise==4.0.6 +edx-enterprise==4.0.7 # via # -c requirements/edx/../constraints.txt # -r requirements/edx/base.txt @@ -916,7 +916,7 @@ openedx-filters==1.4.0 # -r requirements/edx/base.txt # lti-consumer-xblock # skill-tagging -openedx-learning @ git+https://github.com/open-craft/openedx-learning.git@chris/system-defined-taxonomies +openedx-learning==0.1.1 # via -r requirements/edx/base.txt openedx-mongodbproxy==0.2.0 # via -r requirements/edx/base.txt diff --git a/requirements/edx/kernel.in b/requirements/edx/kernel.in index 204eaabb3307..8c0258f55f94 100644 --- a/requirements/edx/kernel.in +++ b/requirements/edx/kernel.in @@ -115,7 +115,7 @@ openedx-calc # Library supporting mathematical calculatio openedx-django-require openedx-events>=8.3.0 # Open edX Events from Hooks Extension Framework (OEP-50) openedx-filters # Open edX Filters from Hooks Extension Framework (OEP-50) -git+https://github.com/open-craft/openedx-learning.git@chris/system-defined-taxonomies#egg=openedx-learning +openedx-learning # Open edX Learning core (experimental) openedx-mongodbproxy openedx-django-wiki openedx-blockstore diff --git a/requirements/edx/testing.txt b/requirements/edx/testing.txt index 6950237c4a34..707f40ca759c 100644 --- a/requirements/edx/testing.txt +++ b/requirements/edx/testing.txt @@ -985,7 +985,7 @@ openedx-filters==1.4.0 # -r requirements/edx/base.txt # lti-consumer-xblock # skill-tagging -openedx-learning @ git+https://github.com/open-craft/openedx-learning.git@chris/system-defined-taxonomies +openedx-learning==0.1.1 # via -r requirements/edx/base.txt openedx-mongodbproxy==0.2.0 # via -r requirements/edx/base.txt