Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minor fixes for tagging django admin [FC-0036] #114

Merged
merged 3 commits into from
Nov 10, 2023
Merged
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
38 changes: 36 additions & 2 deletions openedx_tagging/core/tagging/admin.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,44 @@
"""
Tagging app admin
"""
from __future__ import annotations

from django.contrib import admin

from .models import ObjectTag, Tag, Taxonomy

admin.site.register(Taxonomy)
admin.site.register(Tag)
admin.site.register(ObjectTag)


@admin.register(Tag)
class TagAdmin(admin.ModelAdmin):
"""
Admin definition for Tag model
"""
autocomplete_fields = ["parent"]
search_fields = ["value", "external_id"]
list_display = ["__str__", "taxonomy", "external_id"]
list_filter = ["taxonomy"]

def has_add_permission(self, request):
"""
Don't create Tags using the django admin. Use the API or UI.
"""
return False


@admin.register(ObjectTag)
class ObjectTagAdmin(admin.ModelAdmin):
"""
Admin definition for ObjectTag model
"""
fields = ["object_id", "taxonomy", "tag", "_value"]
autocomplete_fields = ["tag"]
list_display = ["object_id", "name", "value"]
readonly_fields = ["object_id"]

def has_add_permission(self, request):
"""
Don't create ObjectTags using the django admin. Use the API or UI.
"""
return False
36 changes: 36 additions & 0 deletions openedx_tagging/core/tagging/migrations/0014_minor_fixes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Generated by Django 3.2.22 on 2023-11-08 22:37

from django.db import migrations, models

import openedx_learning.lib.fields


def fix_language_taxonomy(apps, schema_editor):
"""
Ensure that the language taxonomy has the correct taxonomy_class. Some
previous versions of this app's migration history allowed it to be created
without the right taxonomy_class.
"""
Taxonomy = apps.get_model("oel_tagging", "Taxonomy")
correct_class = "openedx_tagging.core.tagging.models.system_defined.LanguageTaxonomy"
lang_taxonomy = Taxonomy.objects.get(pk=-1)
if lang_taxonomy._taxonomy_class != correct_class:
lang_taxonomy._taxonomy_class = correct_class
lang_taxonomy.save(update_fields=["_taxonomy_class"])


class Migration(migrations.Migration):

dependencies = [
('oel_tagging', '0013_tag_parent_blank'),
]

operations = [
# Allow taxonomy_class to be blank:
migrations.AlterField(
model_name='taxonomy',
name='_taxonomy_class',
field=models.CharField(blank=True, help_text='Taxonomy subclass used to instantiate this instance; must be a fully-qualified module and class name. If the module/class cannot be imported, an error is logged and the base Taxonomy class is used instead.', max_length=255, null=True),
),
migrations.RunPython(fix_language_taxonomy, None),
]
1 change: 1 addition & 0 deletions openedx_tagging/core/tagging/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ class Taxonomy(models.Model):
"Taxonomy subclass used to instantiate this instance; must be a fully-qualified module and class name."
" If the module/class cannot be imported, an error is logged and the base Taxonomy class is used instead."
),
blank=True,
)

class Meta:
Expand Down
3 changes: 2 additions & 1 deletion openedx_tagging/core/tagging/rest_api/v1/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,8 @@ class TaxonomyView(ModelViewSet):

"""

lookup_value_regex = r"\d+"
# System taxonomies use negative numbers for their primary keys
lookup_value_regex = r'-?\d+'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this fix - looks good! 👍🏻

serializer_class = TaxonomySerializer
permission_classes = [TaxonomyObjectPermissions]

Expand Down
25 changes: 25 additions & 0 deletions tests/openedx_tagging/core/tagging/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,24 @@ def test_list_invalid_page(self) -> None:

assert response.status_code == status.HTTP_404_NOT_FOUND

def test_language_taxonomy(self):
"""
Test the "Language" taxonomy that's included.
"""
self.client.force_authenticate(user=self.user)
response = self.client.get(TAXONOMY_LIST_URL)
assert response.status_code == status.HTTP_200_OK
taxonomy_list = response.data["results"]
assert len(taxonomy_list) == 1
check_taxonomy(
taxonomy_list[0],
taxonomy_id=LANGUAGE_TAXONOMY_ID,
name="Languages",
description="Languages that are enabled on this system.",
allow_multiple=False, # We may change this in the future to allow multiple language tags
system_defined=True,
)

@ddt.data(
(None, {"enabled": True}, status.HTTP_401_UNAUTHORIZED),
(None, {"enabled": False}, status.HTTP_401_UNAUTHORIZED),
Expand All @@ -193,6 +211,13 @@ def test_detail_taxonomy(self, user_attr: str | None, taxonomy_data: dict[str, b
if status.is_success(expected_status):
check_taxonomy(response.data, taxonomy.pk, **create_data)

def test_detail_system_taxonomy(self):
url = TAXONOMY_DETAIL_URL.format(pk=LANGUAGE_TAXONOMY_ID)
self.client.force_authenticate(user=self.user)

response = self.client.get(url)
assert response.status_code == status.HTTP_200_OK

def test_detail_taxonomy_404(self) -> None:
url = TAXONOMY_DETAIL_URL.format(pk=123123)

Expand Down
Loading