Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lx_pathway_plugin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
Django plugin application for exporting LabXchange data from Open edX
"""

__version__ = '3.0.3'
__version__ = '3.0.5'

default_app_config = 'lx_pathway_plugin.apps.LxPathwayPluginAppConfig' # pylint: disable=invalid-name
17 changes: 0 additions & 17 deletions lx_pathway_plugin/admin.py
Original file line number Diff line number Diff line change
@@ -1,17 +0,0 @@
"""
Admin site for LabXchange pathways
"""
from django.contrib import admin

from .models import Pathway


@admin.register(Pathway)
class PathwayAdmin(admin.ModelAdmin):
"""
Definition of django admin UI for Pathways
"""
fields = ("id", "uuid", "owner_user", "owner_group", "draft_data", "published_data")
list_display = ("title", "uuid")
raw_id_fields = ("owner_user", "owner_group")
readonly_fields = ["id", "uuid"]
16 changes: 16 additions & 0 deletions lx_pathway_plugin/migrations/0002_delete_pathway.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Generated by Django 3.2.20 on 2023-10-03 10:33

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('lx_pathway_plugin', '0001_initial'),
]

operations = [
migrations.DeleteModel(
name='Pathway',
),
]
75 changes: 0 additions & 75 deletions lx_pathway_plugin/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,81 +19,6 @@
log = getLogger(__name__)
User = get_user_model()


class Pathway(models.Model):
"""
Model for representing a LabXchange pathway
"""
# edX models are required to have an integer primary key; we don't use it.
id = models.AutoField(primary_key=True)
# UUID of the pathway
uuid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
# Every pathway is owned either by a user or by a group
owner_user = models.ForeignKey(User, null=True, blank=True, on_delete=models.CASCADE)
owner_group = models.ForeignKey(Group, null=True, blank=True, on_delete=models.CASCADE)
# The actual pathway data (draft and published version)
# Contains the list of items, original XBlock IDs, notes, etc.
# The format of these *_data fields is defined and enforced by PathwayDataSerializer (see below)
draft_data = JSONField(null=False, blank=True, default=dict)
published_data = JSONField(null=False, blank=True, default=dict)

def __str__(self):
return "<Pathway: {uuid} >".format(uuid=self.uuid) # xss-lint: disable=python-wrap-html

@property
def title(self):
"""
Get the title of this pathway.
"""
title = self.published_data.get("title", "")
if not title:
title = self.draft_data.get("title", "")
if not title:
title = "Pathway {}".format(self.uuid)
return title

@property
def key(self):
"""
Get the opaque key (LearningContextKey) for this pathway
"""
return PathwayLocator(uuid=self.uuid)

def save(self, *args, **kwargs): # pylint: disable=arguments-differ
"""
Validate and clean before saving.
"""
# if both owner_user and owner_group are nonexistent or both are existing, error:
if (not self.owner_user) == (not self.owner_group):
# We can remove this check and replace it with a proper database constraint
# once Open edX is upgraded to Django 2.2+
raise serializers.ValidationError("One and only one of 'user' and 'group' must be set.")
for data_set in ('draft_data', 'published_data'):
serializer = PathwayDataSerializer(data=getattr(self, data_set))
serializer.is_valid(raise_exception=True)
items = serializer.validated_data["items"]
num_items = len(items)
if num_items > 100:
raise serializers.ValidationError("Too many items in the pathway.")
id_set = set(item["id"] for item in items)
if len(id_set) != num_items:
raise serializers.ValidationError("Some item IDs are not unique.")
for item in items:
try:
UsageKey.from_string(item["original_usage_id"])
except InvalidKeyError as exc:
raise serializers.ValidationError("Invalid item ID: {}".format(item["original_usage_id"])) from exc
if item.get("version") is not None:
raise serializers.ValidationError("Pinning the version of pathway items is no longer supported.")
if "usage_id" in item:
del item["usage_id"] # This field is only added in the REST API response, never saved to DB
# Replace the current value of draft_data or published_data with the cleaned version
setattr(self, data_set, serializer.validated_data)
return super().save(*args, **kwargs)

# Serializers


def make_random_id():
"""
Generate a short, random string that's likely to be unique within the
Expand Down
2 changes: 1 addition & 1 deletion lx_pathway_plugin/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from rest_framework.views import APIView

from lx_pathway_plugin.keys import PathwayLocator
from lx_pathway_plugin.models import Pathway, PathwaySerializer
from lx_pathway_plugin.models import PathwaySerializer

User = get_user_model()

Expand Down