Add choices API endpoint and OpenAPI client setup

Introduces a new /api/choices/ endpoint for fetching model choices with multilingual labels. Updates Django models to use 'cz#' prefix for Czech labels. Adds OpenAPI client generation via orval, refactors frontend API structure, and provides documentation and helper scripts for dynamic choices and OpenAPI usage.
This commit is contained in:
David Bruno Vontor
2025-12-04 17:35:47 +01:00
parent ebab304b75
commit d94ad93222
24 changed files with 281 additions and 76 deletions

View File

@@ -16,6 +16,7 @@ Including another URLconf
"""
from django.contrib import admin
from django.urls import path, include
from .views import choices
from drf_spectacular.views import (
SpectacularAPIView,
@@ -31,6 +32,7 @@ urlpatterns = [
path('admin/', admin.site.urls),
path("api/choices/", choices, name="choices"),
path('api/account/', include('account.urls')),
path('api/commerce/', include('commerce.urls')),
#path('api/advertisments/', include('advertisements.urls')),

View File

@@ -0,0 +1,85 @@
import json
from django.apps import apps
from rest_framework.decorators import api_view
from rest_framework.response import Response
from drf_spectacular.utils import extend_schema, OpenApiParameter
from rest_framework.permissions import AllowAny
@extend_schema(
description="Vrátí všechny možné hodnoty pro ChoiceField s podporou vícejazyčných labelů. "
"Umožňuje načíst více modelů a polí najednou.",
parameters=[
OpenApiParameter(
name="fields",
description=(
"JSON pole objektů {model: 'ModelName', field: 'field_name'} "
"např. '[{\"model\": \"User\", \"field\": \"role\"}, {\"model\": \"Carrier\", \"field\": \"shipping_method\"}]'"
),
required=True,
type=str,
),
OpenApiParameter(
name="lang",
description="Jazyk pro labely (např. 'cz', 'en')",
required=False,
type=str,
),
],
responses={
200: {
"type": "object",
"additionalProperties": {
"type": "array",
"items": {
"type": "object",
"properties": {
"value": {"type": "string", "description": "Logická hodnota pro backend"},
"label": {"type": "string", "description": "Human-readable label podle zvoleného jazyka"}
}
}
}
}
}
)
@api_view(["GET"])
def choices(request):
"""
Endpoint pro získání choices pro dropdowny s podporou vícejazyčných labelů.
Formát labelu v modelu: 'lang#Label', např. 'cz#Administrátor'.
Podporuje více modelů a polí najednou.
"""
permission_classes = [AllowAny]
fields_param = request.query_params.get("fields")
lang = request.query_params.get("lang", None)
try:
fields_list = json.loads(fields_param)
except Exception:
return Response({"error": "Invalid 'fields' parameter, must be valid JSON"}, status=400)
result = {}
for item in fields_list:
model_name = item.get("model")
field_name = item.get("field")
if not model_name or not field_name:
continue
model = apps.get_model("app_name", model_name)
field = model._meta.get_field(field_name)
choices_data = []
for value, label in field.choices:
if "#" in label and lang:
label_parts = label.split("#", 1)
if label_parts[0] == lang:
label = label_parts[1]
else:
label = label_parts[1] # fallback na defaultní text (po #)
elif "#" in label:
label = label.split("#", 1)[1]
choices_data.append({"value": value, "label": label})
result[f"{model_name}.{field_name}"] = choices_data
return Response(result)