diff --git a/dokumente/templates/standards/standard_detail.html b/dokumente/templates/standards/standard_detail.html
index 41c1386..e4ff3da 100644
--- a/dokumente/templates/standards/standard_detail.html
+++ b/dokumente/templates/standards/standard_detail.html
@@ -9,6 +9,7 @@
Autoren: {{ standard.autoren.all|join:", " }}
Prüfende: {{ standard.pruefende.all|join:", " }}
Gültigkeit: {{ standard.gueltigkeit_von }} bis {{ standard.gueltigkeit_bis|default_if_none:"auf weiteres" }}
+JSON herunterladen
{% if standard.einleitung_html %}
diff --git a/dokumente/urls.py b/dokumente/urls.py
index 54d6370..a2db977 100644
--- a/dokumente/urls.py
+++ b/dokumente/urls.py
@@ -7,6 +7,7 @@ urlpatterns = [
path('/', views.standard_detail, name='standard_detail'),
path('/history//', views.standard_detail),
path('/history/', views.standard_detail, {"check_date":"today"}, name='standard_history'),
- path('/checkliste/', views.standard_checkliste, name='standard_checkliste')
+ path('/checkliste/', views.standard_checkliste, name='standard_checkliste'),
+ path('/json/', views.standard_json, name='standard_json')
]
diff --git a/dokumente/views.py b/dokumente/views.py
index d0ac07d..0c6df0a 100644
--- a/dokumente/views.py
+++ b/dokumente/views.py
@@ -1,5 +1,8 @@
from django.shortcuts import render, get_object_or_404
from django.contrib.auth.decorators import login_required, user_passes_test
+from django.http import JsonResponse
+from django.core.serializers.json import DjangoJSONEncoder
+import json
from .models import Dokument, Vorgabe, VorgabeKurztext, VorgabeLangtext, Checklistenfrage
from abschnitte.utils import render_textabschnitte
@@ -102,3 +105,135 @@ def incomplete_vorgaben(request):
return render(request, 'standards/incomplete_vorgaben.html', {
'vorgaben_data': vorgaben_data,
})
+
+
+def standard_json(request, nummer):
+ """
+ Export a single Dokument as JSON
+ """
+ # Get the document with all related data
+ dokument = get_object_or_404(
+ Dokument.objects.prefetch_related(
+ 'autoren', 'pruefende', 'vorgaben__thema',
+ 'vorgaben__referenzen', 'vorgaben__stichworte',
+ 'vorgaben__checklistenfragen', 'vorgaben__vorgabekurztext_set',
+ 'vorgaben__vorgabelangtext_set', 'geltungsbereich_set',
+ 'einleitung_set', 'changelog__autoren'
+ ),
+ nummer=nummer
+ )
+
+ # Build document structure (reusing logic from export_json command)
+ doc_data = {
+ "Typ": dokument.dokumententyp.name if dokument.dokumententyp else "",
+ "Nummer": dokument.nummer,
+ "Name": dokument.name,
+ "Autoren": [autor.name for autor in dokument.autoren.all()],
+ "Pruefende": [pruefender.name for pruefender in dokument.pruefende.all()],
+ "Gueltigkeit": {
+ "Von": dokument.gueltigkeit_von.strftime("%Y-%m-%d") if dokument.gueltigkeit_von else "",
+ "Bis": dokument.gueltigkeit_bis.strftime("%Y-%m-%d") if dokument.gueltigkeit_bis else None
+ },
+ "SignaturCSO": dokument.signatur_cso,
+ "Geltungsbereich": {},
+ "Einleitung": {},
+ "Ziel": "",
+ "Grundlagen": "",
+ "Changelog": [],
+ "Anhänge": dokument.anhaenge,
+ "Verantwortlich": "Information Security Management BIT",
+ "Klassifizierung": None,
+ "Glossar": {},
+ "Vorgaben": []
+ }
+
+ # Process Geltungsbereich sections
+ geltungsbereich_sections = []
+ for gb in dokument.geltungsbereich_set.all().order_by('order'):
+ geltungsbereich_sections.append({
+ "typ": gb.abschnitttyp.abschnitttyp if gb.abschnitttyp else "text",
+ "inhalt": gb.inhalt
+ })
+
+ if geltungsbereich_sections:
+ doc_data["Geltungsbereich"] = {
+ "Abschnitt": geltungsbereich_sections
+ }
+
+ # Process Einleitung sections
+ einleitung_sections = []
+ for ei in dokument.einleitung_set.all().order_by('order'):
+ einleitung_sections.append({
+ "typ": ei.abschnitttyp.abschnitttyp if ei.abschnitttyp else "text",
+ "inhalt": ei.inhalt
+ })
+
+ if einleitung_sections:
+ doc_data["Einleitung"] = {
+ "Abschnitt": einleitung_sections
+ }
+
+ # Process Changelog entries
+ changelog_entries = []
+ for cl in dokument.changelog.all().order_by('-datum'):
+ changelog_entries.append({
+ "Datum": cl.datum.strftime("%Y-%m-%d"),
+ "Autoren": [autor.name for autor in cl.autoren.all()],
+ "Aenderung": cl.aenderung
+ })
+
+ doc_data["Changelog"] = changelog_entries
+
+ # Process Vorgaben for this document
+ vorgaben = dokument.vorgaben.all().order_by('order')
+
+ for vorgabe in vorgaben:
+ # Get Kurztext and Langtext sections
+ kurztext_sections = []
+ for kt in vorgabe.vorgabekurztext_set.all().order_by('order'):
+ kurztext_sections.append({
+ "typ": kt.abschnitttyp.abschnitttyp if kt.abschnitttyp else "text",
+ "inhalt": kt.inhalt
+ })
+
+ langtext_sections = []
+ for lt in vorgabe.vorgabelangtext_set.all().order_by('order'):
+ langtext_sections.append({
+ "typ": lt.abschnitttyp.abschnitttyp if lt.abschnitttyp else "text",
+ "inhalt": lt.inhalt
+ })
+
+ # Build text structures following Langtext pattern
+ kurztext = {
+ "Abschnitt": kurztext_sections if kurztext_sections else []
+ } if kurztext_sections else {}
+ langtext = {
+ "Abschnitt": langtext_sections if langtext_sections else []
+ } if langtext_sections else {}
+
+ # Get references and keywords
+ referenzen = [f"{ref.name_nummer}: {ref.name_text}" if ref.name_text else ref.name_nummer for ref in vorgabe.referenzen.all()]
+ stichworte = [stw.stichwort for stw in vorgabe.stichworte.all()]
+
+ # Get checklist questions
+ checklistenfragen = [cf.frage for cf in vorgabe.checklistenfragen.all()]
+
+ vorgabe_data = {
+ "Nummer": str(vorgabe.nummer),
+ "Titel": vorgabe.titel,
+ "Thema": vorgabe.thema.name if vorgabe.thema else "",
+ "Kurztext": kurztext,
+ "Langtext": langtext,
+ "Referenz": referenzen,
+ "Gueltigkeit": {
+ "Von": vorgabe.gueltigkeit_von.strftime("%Y-%m-%d") if vorgabe.gueltigkeit_von else "",
+ "Bis": vorgabe.gueltigkeit_bis.strftime("%Y-%m-%d") if vorgabe.gueltigkeit_bis else None
+ },
+ "Checklistenfragen": checklistenfragen,
+ "Stichworte": stichworte
+ }
+
+ doc_data["Vorgaben"].append(vorgabe_data)
+
+ # Return JSON response
+ return JsonResponse(doc_data, json_dumps_params={'indent': 2, 'ensure_ascii': False}, encoder=DjangoJSONEncoder)