diff --git a/opaque_keys/edx/django/models.py b/opaque_keys/edx/django/models.py index d9ed737..7c747b3 100644 --- a/opaque_keys/edx/django/models.py +++ b/opaque_keys/edx/django/models.py @@ -3,6 +3,7 @@ If Django is unavailable, none of the classes below will work as intended. """ from __future__ import annotations + import logging import warnings @@ -17,8 +18,7 @@ IsNull = object from opaque_keys import OpaqueKey -from opaque_keys.edx.keys import BlockTypeKey, CourseKey, LearningContextKey, UsageKey - +from opaque_keys.edx.keys import BlockTypeKey, CourseKey, LearningContextKey, LibraryItemKey, UsageKey log = logging.getLogger(__name__) @@ -224,6 +224,17 @@ class UsageKeyField(OpaqueKeyField): _pyi_private_get_type: UsageKey | None +class LibraryItemField(OpaqueKeyField): + """ + A django Field that stores a LibraryItemKey object as a string. + """ + description = "A Location object, saved to the DB in the form of a string" + KEY_CLASS = LibraryItemKey + # Declare the field types for the django-stubs mypy type hint plugin: + _pyi_private_set_type: LibraryItemKey | str | None + _pyi_private_get_type: LibraryItemKey | None + + class LocationKeyField(UsageKeyField): """ A django Field that stores a UsageKey object as a string. diff --git a/opaque_keys/edx/keys.py b/opaque_keys/edx/keys.py index 2e0da97..41486ae 100644 --- a/opaque_keys/edx/keys.py +++ b/opaque_keys/edx/keys.py @@ -114,6 +114,15 @@ def org(self) -> str | None: # pragma: no cover def library_key(self): return self.lib_key + @property + @abstractmethod + def context_key(self) -> LearningContextKey: + """ + Get the learning context key (LearningContextKey) for this XBlock usage. + May be a course key, library key, or some other LearningContextKey type. + """ + raise NotImplementedError() + class DefinitionKey(OpaqueKey): """ diff --git a/opaque_keys/edx/locator.py b/opaque_keys/edx/locator.py index d139a71..5ebd1a7 100644 --- a/opaque_keys/edx/locator.py +++ b/opaque_keys/edx/locator.py @@ -1675,6 +1675,10 @@ def _from_string(cls, serialized: str) -> Self: except (ValueError, TypeError) as error: raise InvalidKeyError(cls, serialized) from error + @property + def context_key(self) -> LibraryLocatorV2: + return self.lib_key + class LibraryContainerLocator(CheckFieldMixin, LibraryItemKey): """ @@ -1714,6 +1718,10 @@ def org(self) -> str | None: # pragma: no cover """ return self.lib_key.org + @property + def context_key(self) -> LibraryLocatorV2: + return self.lib_key + def _to_string(self) -> str: """ Serialize this key as a string