Skip to content

Commit

Permalink
feat: taxonomy org api
Browse files Browse the repository at this point in the history
  • Loading branch information
rpenido committed Jul 27, 2023
1 parent b94b0a8 commit b6a9173
Show file tree
Hide file tree
Showing 17 changed files with 819 additions and 14 deletions.
5 changes: 5 additions & 0 deletions cms/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -332,3 +332,8 @@
urlpatterns += [
path('api/contentstore/', include('cms.djangoapps.contentstore.rest_api.urls'))
]

# Content tagging
urlpatterns += [
path('api/content_tagging/', include(('openedx.features.content_tagging.urls', 'content_tagging'), namespace='content_tagging')),
]
5 changes: 5 additions & 0 deletions lms/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -1049,3 +1049,8 @@
urlpatterns += [
path('api/notifications/', include('openedx.core.djangoapps.notifications.urls')),
]

# Content tagging
urlpatterns += [
path('api/content_tagging/', include(('openedx.features.content_tagging.urls', 'content_tagging'), namespace='content_tagging')),
]
2 changes: 2 additions & 0 deletions openedx/features/content_tagging/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ def set_taxonomy_orgs(
def get_taxonomies_for_org(
enabled=True,
org_owner: Organization = None,
only_without_org=True,
) -> QuerySet:
"""
Generates a list of the enabled Taxonomies available for the given org, sorted by name.
Expand All @@ -97,6 +98,7 @@ def get_taxonomies_for_org(
return ContentTaxonomy.taxonomies_for_org(
org=org_owner,
queryset=taxonomies,
only_without_org=only_without_org,
)


Expand Down
21 changes: 16 additions & 5 deletions openedx/features/content_tagging/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,33 +49,42 @@ class Meta:

@classmethod
def get_relationships(
cls, taxonomy: Taxonomy, rel_type: RelType, org_short_name: str = None
cls,
taxonomy: Taxonomy,
rel_type: RelType,
org_short_name: Union[str, None] = None,
only_without_org: bool = True,
) -> QuerySet:
"""
Returns the relationships of the given rel_type and taxonomy where:
* the relationship is available for all organizations, OR
* (if provided) the relationship is available to the org with the given org_short_name
"""
# A relationship with org=None means all Organizations
org_filter = Q(org=None)
if org_short_name is not None:
org_filter |= Q(org__short_name=org_short_name)
org_filter = Q(org__short_name=org_short_name) | Q(org=None)
elif only_without_org:
org_filter = Q(org=None)
else:
org_filter = Q() # no filter
return cls.objects.filter(
taxonomy=taxonomy,
rel_type=rel_type,
).filter(org_filter)

@classmethod
def get_organizations(
cls, taxonomy: Taxonomy, rel_type: RelType
cls, taxonomy: Union[Taxonomy, None], rel_type: RelType
) -> List[Organization]:
"""
Returns the list of Organizations which have the given relationship to the taxonomy.
If no taxonomy is provided, returns all Organizations that have a relationship with some taxonomy.
"""
rels = cls.objects.filter(
taxonomy=taxonomy,
rel_type=rel_type,
)
if taxonomy:
rels = rels.filter(taxonomy=taxonomy)
# A relationship with org=None means all Organizations
if rels.filter(org=None).exists():
return list(Organization.objects.all())
Expand Down Expand Up @@ -119,6 +128,7 @@ def taxonomies_for_org(
cls,
queryset: QuerySet,
org: Organization = None,
only_without_org=True,
) -> QuerySet:
"""
Filters the given QuerySet to those ContentTaxonomies which are available for the given organization.
Expand All @@ -133,6 +143,7 @@ def taxonomies_for_org(
taxonomy=OuterRef("pk"),
rel_type=TaxonomyOrg.RelType.OWNER,
org_short_name=org_short_name,
only_without_org=only_without_org,
)
)
)
Expand Down
9 changes: 9 additions & 0 deletions openedx/features/content_tagging/rest_api/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"""
Taxonomies API URLs.
"""

from django.urls import path, include

from .v1 import urls as v1_urls

urlpatterns = [path("v1/", include(v1_urls))]
Empty file.
45 changes: 45 additions & 0 deletions openedx/features/content_tagging/rest_api/v1/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
"""
API Serializers for taxonomies org
"""

from rest_framework import serializers

from openedx_tagging.core.tagging.models import Taxonomy
from openedx_tagging.core.tagging.rest_api.v1.serializers import TaxonomyListQueryParamsSerializer

from organizations.models import Organization


class OrganizationField(serializers.Field):
def to_representation(self, value):
return value.short_name

def to_internal_value(self, data):
try:
return Organization.objects.get(short_name=data)
except Organization.DoesNotExist:
raise serializers.ValidationError("Invalid organization short name")

class TaxonomyOrgListQueryParamsSerializer(TaxonomyListQueryParamsSerializer):
"""
Serializer for the query params for the GET view
"""

org = OrganizationField(required=False)

# class TaxonomySerializer(serializers.ModelSerializer):
# class Meta:
# model = Taxonomy
# fields = [
# "id",
# "name",
# "description",
# "enabled",
# "required",
# "allow_multiple",
# "allow_free_text",
# "system_defined",
# "visible_to_authors",
# ]


Loading

0 comments on commit b6a9173

Please sign in to comment.