diff --git a/.gitignore b/.gitignore index 888019d47..0fc03c7df 100644 --- a/.gitignore +++ b/.gitignore @@ -64,6 +64,7 @@ requirements/private.txt dev.db* .vscode +venv/ # Media files (for uploads) media/ diff --git a/openedx_learning/contrib/tagging/__init__.py b/openedx_learning/contrib/tagging/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/openedx_learning/contrib/tagging/admin.py b/openedx_learning/contrib/tagging/admin.py new file mode 100644 index 000000000..2e59ec267 --- /dev/null +++ b/openedx_learning/contrib/tagging/admin.py @@ -0,0 +1,5 @@ +""" Tagging app admin """ +from django.contrib import admin +from .models import TagContent + +admin.site.register(TagContent) diff --git a/openedx_learning/contrib/tagging/apps.py b/openedx_learning/contrib/tagging/apps.py new file mode 100644 index 000000000..46f97d066 --- /dev/null +++ b/openedx_learning/contrib/tagging/apps.py @@ -0,0 +1,16 @@ +""" +tagging Django application initialization. +""" + +from django.apps import AppConfig + + +class TaggingConfig(AppConfig): + """ + Configuration for the tagging Django application. + """ + + name = "openedx_learning.contrib.tagging" + verbose_name = "Tagging" + default_auto_field = 'django.db.models.BigAutoField' + label = "oel_tagging" diff --git a/openedx_learning/contrib/tagging/migrations/0001_initial.py b/openedx_learning/contrib/tagging/migrations/0001_initial.py new file mode 100644 index 000000000..f3b336ef3 --- /dev/null +++ b/openedx_learning/contrib/tagging/migrations/0001_initial.py @@ -0,0 +1,23 @@ +# Generated by Django 3.2.19 on 2023-05-25 21:08 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='TagContent', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('content_id', models.CharField(max_length=255)), + ('name', models.CharField(max_length=255)), + ('value', models.CharField(max_length=765)), + ], + ), + ] diff --git a/openedx_learning/contrib/tagging/migrations/__init__.py b/openedx_learning/contrib/tagging/migrations/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/openedx_learning/contrib/tagging/models.py b/openedx_learning/contrib/tagging/models.py new file mode 100644 index 000000000..9f3a30d6f --- /dev/null +++ b/openedx_learning/contrib/tagging/models.py @@ -0,0 +1,38 @@ +""" Tagging app data models """ +from django.db import models + +class TagContent(models.Model): + """ + TODO: This is a basic representation of TagContent, it may change + depending on the discovery in: + https://docs.google.com/document/d/13zfsGDfomSTCp_G-_ncevQHAb4Y4UW0d_6N8R2PdHlA/edit#heading=h.o6fm1hktwp7b + + This is the representation of a tag that is linked to a content + + Name-Value pair + ----------------- + + We use a Field-Value Pair representation, where `name` functions + as the constant that defines the field data set, and `value` functions + as the variable tag lineage that belong to the set. + + Value lineage + --------------- + + `value` are stored as null character-delimited strings to preserve the tag's lineage. + We use the null character to avoid choosing a character that may exist in a tag's name. + We don't use the Taxonomy's user-facing delimiter so that this delimiter can be changed + without disrupting stored tags. + """ + + # Content id to which this tag is associated + content_id = models.CharField(max_length=255) + + # It's not usually large + name = models.CharField(max_length=255) + + # Tag lineage value. + # + # The lineage can be large. + # TODO: The length is under discussion + value = models.CharField(max_length=765) diff --git a/openedx_learning/contrib/tagging/readme.rst b/openedx_learning/contrib/tagging/readme.rst new file mode 100644 index 000000000..5ce22340d --- /dev/null +++ b/openedx_learning/contrib/tagging/readme.rst @@ -0,0 +1,26 @@ +Tagging App +============== + +The ``tagging`` app will enable content authors to tag pieces of content and quickly +filter for ease of re-use. + +Motivation +---------- + +Tagging content is central to enable content re-use, facilitate the implementation +of flexible content structures different from the current implementation and +allow adaptive learning in the Open edX platform. + +This service has been implemented as pluggable django app. Since it is necessary for +it to work independently of the content to which it links to. + +Setup +--------- + +**TODO:** We need to wait the discussion of the `Taxonomy discovery `_. +to build a proper setup for linking different pieces of content. + +The current approach is to save the id of the content through a generic string, +so that the tag can be linked to any type of content, no matter what type of ID have. +For example, with this approach we can link standalone blocks and library blocks, +both on Denver (v3) and Blockstore Content Libraries (v2). diff --git a/projects/dev.py b/projects/dev.py index 7be663f44..2d50a6119 100644 --- a/projects/dev.py +++ b/projects/dev.py @@ -35,6 +35,7 @@ "openedx_learning.core.publishing.apps.PublishingConfig", # Learning Contrib Apps "openedx_learning.contrib.media_server.apps.MediaServerConfig", + "openedx_learning.contrib.tagging.apps.TaggingConfig", # Apps that don't belong in this repo in the long term, but are here to make # testing/iteration easier until the APIs stabilize. "olx_importer.apps.OLXImporterConfig",