Skip to content
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
8 changes: 8 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
Version 0.3.9 (01.09.2025)
*****************************
- Set default value zero in tolerance field
- Include profile type when querying single profile
- Change return value of glossary entries end point to enable use of multiple tabs inside glossary
- Introduce new database field and set default to glossary
- Have number and name of tabs configured by importing back end

Version 0.3.8 (17.06.2025)
*****************************
- Manage searchable_fields provided by backends
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "solid-backend"
version = "0.3.8"
version = "0.3.9"

description = "Clean Django app for e-learning application with..."
authors = [
Expand Down
7 changes: 6 additions & 1 deletion solid_backend/content/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,9 @@ def detail_content_item(self, request, related_name, *args, **kwargs):
self.check_related_name_exists()
obj = self.get_object()
serializer = self.get_serializer(obj)
return Response(data=serializer.data)
data = serializer.data
data["def_type"] = self.related_name
return Response(data=data)

@action(
detail=False,
Expand Down Expand Up @@ -245,9 +247,12 @@ def get_optimized_queryset(self, model):

def list(self, request):
response_data = []
filter_param = request.query_params.get("node_id")
for profile_type in SERIALIZERS.keys():
model = SERIALIZERS[profile_type].Meta.model
profile_results = self.get_optimized_queryset(model)
if filter_param:
profile_results = profile_results.filter(tree_node__id=filter_param)
# serializer_class = self.get_serializer_for_model(profile_type)
# Batch serialize all results for this profile type
serialized = SERIALIZERS[profile_type](
Expand Down
8 changes: 7 additions & 1 deletion solid_backend/glossary/admin.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django.contrib import admin

from django import forms
from django.conf import settings
from .forms import GlossaryEntryAdminForm
from .models import GlossaryEntry

Expand All @@ -8,5 +9,10 @@ class GlossaryEntryAdmin(admin.ModelAdmin):
form = GlossaryEntryAdminForm
list_display = ["id", "term"]

def get_exclude(self, request, obj=None):
if not GlossaryEntryAdminForm.should_show_tags(self):
return ("tags",)
return []


admin.site.register(GlossaryEntry, GlossaryEntryAdmin)
27 changes: 26 additions & 1 deletion solid_backend/glossary/forms.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,40 @@
from django import forms
from django.forms import ModelForm, ValidationError
from django.utils.translation import ugettext_lazy as _
from .models import GlossaryEntry
from django.conf import settings


class GlossaryEntryAdminForm(ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if self.should_show_tags():
self.fields["tags"].widget = forms.Select(choices=settings.GLOSSARY_TABS)
self.fields["tags"].help_text = "Select applicable tags"

def should_show_tags(self):
return hasattr(settings, "GLOSSARY_TABS")

def clean(self):
data = super(GlossaryEntryAdminForm, self).clean()

data = super().clean()

if not (data.get("text", None) or data.get("links", None)):
raise ValidationError(
_(
"Es muss entweder ein Text oder eine Verknüpfung zu einem anderen Eintrag angegeben werden."
)
)

# Handle regular fields
for field_name, value in self.data.items():
if field_name in self.fields and field_name != "links": # exclude M2M
data[field_name] = value

# Handle M2M field separately
if "links" in self.data:
# necessary to save multiple links
links_data = self.data.getlist("links")
data["links"] = links_data

return data
18 changes: 18 additions & 0 deletions solid_backend/glossary/migrations/0007_glossaryentry_tags.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 3.2.20 on 2025-08-27 14:25

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('glossary', '0006_auto_20220217_1858'),
]

operations = [
migrations.AddField(
model_name='glossaryentry',
name='tags',
field=models.CharField(default='Glossar', max_length=100),
),
]
1 change: 1 addition & 0 deletions solid_backend/glossary/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class GlossaryEntry(models.Model):
term = models.CharField(max_length=100)
text = models.TextField(null=True, blank=True, verbose_name="text (Markdown)")
links = models.ManyToManyField("self", symmetrical=False, blank=True, null=True)
tags = models.CharField(max_length=100, default="Glossar")

def __str__(self):
return self.term
Expand Down
2 changes: 1 addition & 1 deletion solid_backend/glossary/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@

app_name = "glossary"
router = SimpleRouter()
router.register(r"glossaryentries", GlossaryEntryEndpoint)
router.register(r"glossaryentries", GlossaryEntryEndpoint, basename="glossaryentry")
urlpatterns = []
urlpatterns += router.urls
26 changes: 22 additions & 4 deletions solid_backend/glossary/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,33 @@

from .models import GlossaryEntry
from .serializers import GlossaryEntrySerializer
import logging
from collections import defaultdict
from rest_framework.response import Response

logger = logging.getLogger(__name__)


class GlossaryEntryEndpoint(ReadOnlyModelViewSet):
"""
Endpoint that provides the database table of all glossary entries.
Endpoint that provides glossary entries and optionally content of other tabs
"""

queryset = GlossaryEntry.objects.all().prefetch_related(
Prefetch("links", queryset=GlossaryEntry.objects.order_by("term"))
)
def get_queryset(self):
return GlossaryEntry.objects.all().prefetch_related(
Prefetch("links", queryset=GlossaryEntry.objects.order_by("term"))
)

def list(self, request):
response_data = defaultdict(list)
queryset = self.get_queryset()

serialized = GlossaryEntrySerializer(
queryset, many=True, context={"request": request}
).data
for item in serialized:
response_data[item["tags"]].append(item)
return Response(response_data)

serializer_class = GlossaryEntrySerializer
name = "glossaryentry"
2 changes: 1 addition & 1 deletion solid_backend/quiz/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class QuizAnswer(models.Model):
range_min = models.FloatField(null=True, blank=True)
unit = models.CharField(max_length=400, null=True, blank=True)
range_step = models.FloatField(null=True, blank=True)
tolerance = models.FloatField(null=True, blank=True)
tolerance = models.FloatField(null=True, blank=True, default=0)


@receiver(post_delete, sender=TaggedItem)
Expand Down