Skip to content

Commit

Permalink
chore: get API tests passing
Browse files Browse the repository at this point in the history
  • Loading branch information
bradenmacdonald committed Oct 18, 2023
1 parent 61499c1 commit c46edaa
Show file tree
Hide file tree
Showing 4 changed files with 228 additions and 66 deletions.
11 changes: 6 additions & 5 deletions openedx_tagging/core/tagging/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def get_root_tags(taxonomy: Taxonomy) -> QuerySet[TagData]:
return taxonomy.cast().get_filtered_tags(depth=1)


def search_tags(taxonomy: Taxonomy, search_term: str, exclude_object_id: int | None = None) -> QuerySet[TagData]:
def search_tags(taxonomy: Taxonomy, search_term: str, exclude_object_id: str | None = None) -> QuerySet[TagData]:
"""
Returns a list of all tags that contains `search_term` of the given
taxonomy, as well as their ancestors (so they can be displayed in a tree).
Expand All @@ -99,15 +99,16 @@ def search_tags(taxonomy: Taxonomy, search_term: str, exclude_object_id: int | N
excluded from the results, e.g. to power an autocomplete search when adding
additional tags to an object.
"""
qs = taxonomy.cast().get_filtered_tags(search_term=search_term)
excluded_values = None
if exclude_object_id:
# Fetch tags that the object already has to exclude them from the result
# Fetch tags that the object already has to exclude them from the result.
# Note: this adds a fair bit of complexity. In the future, maybe we can just do this filtering on the frontend?
excluded_values = list(
taxonomy.objecttag_set.filter(object_id=exclude_object_id).values_list(
"_value", flat=True
)
)
qs = qs.exclude(value__in=excluded_values)
qs = taxonomy.cast().get_filtered_tags(search_term=search_term, excluded_values=excluded_values)
return qs


Expand All @@ -120,7 +121,7 @@ def get_children_tags(
Note that if the taxonomy allows free-text tags, then the returned list will be empty.
"""
return taxonomy.cast().get_filtered_tags(parent_tag_value=parent_tag_value)
return taxonomy.cast().get_filtered_tags(parent_tag_value=parent_tag_value, depth=1)


def resync_object_tags(object_tags: QuerySet | None = None) -> int:
Expand Down
2 changes: 1 addition & 1 deletion openedx_tagging/core/tagging/import_export/parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ def _load_tags_for_export(cls, taxonomy: Taxonomy) -> list[dict]:
The tags are ordered by hierarchy, first, parents and then children.
`get_tags` is in charge of returning this in a hierarchical way.
"""
tags = Taxonomy.get_filtered_tags().all()
tags = taxonomy.get_filtered_tags().all()
result = []
for tag in tags:
result_tag = {
Expand Down
19 changes: 17 additions & 2 deletions openedx_tagging/core/tagging/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ def get_filtered_tags(
parent_tag_value: str | None = None,
search_term: str | None = None,
include_counts: bool = True,
excluded_values: list[str] | None = None,
) -> models.QuerySet[TagData]:
"""
Returns a filtered QuerySet of tag values.
Expand All @@ -316,24 +317,35 @@ def get_filtered_tags(
Use `search_term` to filter the results by values that contains `search_term`.
Use `excluded_values` to exclude tags with that value (and their parents, if applicable) from the results.
Note: This is mostly an 'internal' API and generally code outside of openedx_tagging
should use the APIs in openedx_tagging.api which in turn use this.
"""
if self.allow_free_text:
if parent_tag_value is not None:
raise ValueError("Cannot specify a parent tag ID for free text taxonomies")
return self._get_filtered_tags_free_text(search_term=search_term, include_counts=include_counts)
result = self._get_filtered_tags_free_text(search_term=search_term, include_counts=include_counts)
if excluded_values:
return result.exclude(value__in=excluded_values)
else:
return result
elif depth == 1:
return self._get_filtered_tags_one_level(
result = self._get_filtered_tags_one_level(
parent_tag_value=parent_tag_value,
search_term=search_term,
include_counts=include_counts,
)
if excluded_values:
return result.exclude(value__in=excluded_values)
else:
return result
elif depth is None or depth == TAXONOMY_MAX_DEPTH:
return self._get_filtered_tags_deep(
parent_tag_value=parent_tag_value,
search_term=search_term,
include_counts=include_counts,
excluded_values=excluded_values,
)
else:
raise ValueError("Unsupported depth value for get_filtered_tags()")
Expand Down Expand Up @@ -409,6 +421,7 @@ def _get_filtered_tags_deep(
parent_tag_value: str | None,
search_term: str | None,
include_counts: bool,
excluded_values: list[str] | None,
) -> models.QuerySet[TagData]:
"""
Implementation of get_filtered_tags() for closed taxonomies, where
Expand All @@ -433,6 +446,8 @@ def _get_filtered_tags_deep(
matching_tags = qs.filter(value__icontains=search_term).values(
'id', 'parent_id', 'parent__parent_id', 'parent__parent__parent_id'
)
if excluded_values:
matching_tags = matching_tags.exclude(value__in=excluded_values)
matching_ids = []
for row in matching_tags:
for pk in row.values():
Expand Down
Loading

0 comments on commit c46edaa

Please sign in to comment.