Compare commits
8 Commits
feature/li
...
improvemen
| Author | SHA1 | Date | |
|---|---|---|---|
| 8520412867 | |||
| e94f61a697 | |||
| 0cd09d0878 | |||
| 994ba5d797 | |||
| af636fe6ea | |||
| 3ccb32e8e1 | |||
| af4e1c61aa | |||
| 8153aa56ce |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -8,10 +8,11 @@ include/
|
|||||||
keys/
|
keys/
|
||||||
.venv/
|
.venv/
|
||||||
.idea/
|
.idea/
|
||||||
|
|
||||||
*.kate-swp
|
*.kate-swp
|
||||||
node_modules/
|
node_modules/
|
||||||
package-lock.json
|
package-lock.json
|
||||||
package.json
|
package.json
|
||||||
# Diagram cache directory
|
# Diagram cache directory
|
||||||
media/diagram_cache/
|
media/diagram_cache/
|
||||||
|
.env
|
||||||
|
data/db.sqlite3
|
||||||
|
|||||||
1599
R0066.json
Normal file
1599
R0066.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -25,7 +25,7 @@ spec:
|
|||||||
mountPath: /data
|
mountPath: /data
|
||||||
containers:
|
containers:
|
||||||
- name: web
|
- name: web
|
||||||
image: git.baumann.gr/adebaumann/vui:0.942
|
image: git.baumann.gr/adebaumann/vui:0.943
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 8000
|
- containerPort: 8000
|
||||||
|
|||||||
BIN
data/db.sqlite3
BIN
data/db.sqlite3
Binary file not shown.
@@ -2,6 +2,7 @@ from django.contrib import admin
|
|||||||
#from nested_inline.admin import NestedStackedInline, NestedModelAdmin
|
#from nested_inline.admin import NestedStackedInline, NestedModelAdmin
|
||||||
from nested_admin import NestedStackedInline, NestedModelAdmin, NestedTabularInline
|
from nested_admin import NestedStackedInline, NestedModelAdmin, NestedTabularInline
|
||||||
from django import forms
|
from django import forms
|
||||||
|
from django.utils.html import format_html
|
||||||
from mptt.forms import TreeNodeMultipleChoiceField
|
from mptt.forms import TreeNodeMultipleChoiceField
|
||||||
from mptt.admin import DraggableMPTTAdmin
|
from mptt.admin import DraggableMPTTAdmin
|
||||||
from adminsortable2.admin import SortableInlineAdminMixin, SortableAdminBase
|
from adminsortable2.admin import SortableInlineAdminMixin, SortableAdminBase
|
||||||
@@ -132,9 +133,57 @@ class StichworterklaerungInline(NestedTabularInline):
|
|||||||
|
|
||||||
@admin.register(Stichwort)
|
@admin.register(Stichwort)
|
||||||
class StichwortAdmin(NestedModelAdmin):
|
class StichwortAdmin(NestedModelAdmin):
|
||||||
|
list_display = ('stichwort', 'vorgaben_count')
|
||||||
search_fields = ('stichwort',)
|
search_fields = ('stichwort',)
|
||||||
ordering=('stichwort',)
|
ordering=('stichwort',)
|
||||||
inlines=[StichworterklaerungInline]
|
inlines=[StichworterklaerungInline]
|
||||||
|
readonly_fields = ('vorgaben_list',)
|
||||||
|
fieldsets = (
|
||||||
|
(None, {
|
||||||
|
'fields': ('stichwort', 'vorgaben_list')
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
def vorgaben_count(self, obj):
|
||||||
|
"""Count the number of Vorgaben that have this Stichwort"""
|
||||||
|
count = obj.vorgabe_set.count()
|
||||||
|
return f"{count} Vorgabe{'n' if count != 1 else ''}"
|
||||||
|
vorgaben_count.short_description = "Anzahl Vorgaben"
|
||||||
|
|
||||||
|
def vorgaben_list(self, obj):
|
||||||
|
"""Display list of Vorgaben that use this Stichwort"""
|
||||||
|
vorgaben = obj.vorgabe_set.select_related('dokument', 'thema').order_by('dokument__nummer', 'nummer')
|
||||||
|
vorgaben_list = list(vorgaben) # Evaluate queryset once
|
||||||
|
count = len(vorgaben_list)
|
||||||
|
|
||||||
|
if count == 0:
|
||||||
|
return format_html("<em>Keine Vorgaben gefunden</em><p><strong>Gesamt: 0 Vorgaben</strong></p>")
|
||||||
|
|
||||||
|
html = "<div style='max-height: 300px; overflow-y: auto;'>"
|
||||||
|
html += "<table style='width: 100%; border-collapse: collapse;'>"
|
||||||
|
html += "<thead><tr style='background-color: #f5f5f5;'>"
|
||||||
|
html += "<th style='padding: 8px; border: 1px solid #ddd; text-align: left;'>Vorgabe</th>"
|
||||||
|
html += "<th style='padding: 8px; border: 1px solid #ddd; text-align: left;'>Titel</th>"
|
||||||
|
html += "<th style='padding: 8px; border: 1px solid #ddd; text-align: left;'>Dokument</th>"
|
||||||
|
html += "</tr></thead>"
|
||||||
|
html += "<tbody>"
|
||||||
|
|
||||||
|
for vorgabe in vorgaben_list:
|
||||||
|
html += "<tr>"
|
||||||
|
html += f"<td style='padding: 6px; border: 1px solid #ddd;'>{vorgabe.Vorgabennummer()}</td>"
|
||||||
|
html += f"<td style='padding: 6px; border: 1px solid #ddd;'>{vorgabe.titel}</td>"
|
||||||
|
html += f"<td style='padding: 6px; border: 1px solid #ddd;'>{vorgabe.dokument.nummer} – {vorgabe.dokument.name}</td>"
|
||||||
|
html += "</tr>"
|
||||||
|
|
||||||
|
html += "</tbody></table>"
|
||||||
|
html += f"</div><p><strong>Gesamt: {count} Vorgabe{'n' if count != 1 else ''}</strong></p>"
|
||||||
|
|
||||||
|
return format_html(html)
|
||||||
|
vorgaben_list.short_description = "Zugeordnete Vorgaben"
|
||||||
|
|
||||||
|
def get_queryset(self, request):
|
||||||
|
"""Optimize queryset with related data"""
|
||||||
|
return super().get_queryset(request).prefetch_related('vorgabe_set')
|
||||||
|
|
||||||
@admin.register(Person)
|
@admin.register(Person)
|
||||||
class PersonAdmin(admin.ModelAdmin):
|
class PersonAdmin(admin.ModelAdmin):
|
||||||
|
|||||||
174
dokumente/management/commands/export_json.py
Normal file
174
dokumente/management/commands/export_json.py
Normal file
@@ -0,0 +1,174 @@
|
|||||||
|
from django.core.management.base import BaseCommand
|
||||||
|
from django.core.serializers.json import DjangoJSONEncoder
|
||||||
|
import json
|
||||||
|
from datetime import datetime
|
||||||
|
from dokumente.models import Dokument, Vorgabe, VorgabeKurztext, VorgabeLangtext, Checklistenfrage
|
||||||
|
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
help = 'Export all dokumente as JSON using R0066.json format as reference'
|
||||||
|
|
||||||
|
def add_arguments(self, parser):
|
||||||
|
parser.add_argument(
|
||||||
|
'--output',
|
||||||
|
type=str,
|
||||||
|
help='Output file path (default: stdout)',
|
||||||
|
)
|
||||||
|
|
||||||
|
def handle(self, *args, **options):
|
||||||
|
# Get all active documents
|
||||||
|
dokumente = Dokument.objects.filter(aktiv=True).prefetch_related(
|
||||||
|
'autoren', 'pruefende', 'vorgaben__thema',
|
||||||
|
'vorgaben__referenzen', 'vorgaben__stichworte',
|
||||||
|
'vorgaben__checklistenfragen', 'vorgaben__vorgabekurztext_set',
|
||||||
|
'vorgaben__vorgabelangtext_set', 'geltungsbereich_set',
|
||||||
|
'einleitung_set', 'changelog__autoren'
|
||||||
|
).order_by('nummer')
|
||||||
|
|
||||||
|
result = {
|
||||||
|
"Vorgabendokument": {
|
||||||
|
"Typ": "Standard IT-Sicherheit",
|
||||||
|
"Nummer": "", # Will be set per document
|
||||||
|
"Name": "", # Will be set per document
|
||||||
|
"Autoren": [], # Will be set per document
|
||||||
|
"Pruefende": [], # Will be set per document
|
||||||
|
"Geltungsbereich": {
|
||||||
|
"Abschnitt": []
|
||||||
|
},
|
||||||
|
"Ziel": "",
|
||||||
|
"Grundlagen": "",
|
||||||
|
"Changelog": [],
|
||||||
|
"Anhänge": [],
|
||||||
|
"Verantwortlich": "Information Security Management BIT",
|
||||||
|
"Klassifizierung": None,
|
||||||
|
"Glossar": {},
|
||||||
|
"Vorgaben": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output_data = []
|
||||||
|
|
||||||
|
for dokument in dokumente:
|
||||||
|
# Build document structure
|
||||||
|
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
|
||||||
|
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)
|
||||||
|
|
||||||
|
output_data.append(doc_data)
|
||||||
|
|
||||||
|
# Output the data
|
||||||
|
json_output = json.dumps(output_data, cls=DjangoJSONEncoder, indent=2, ensure_ascii=False)
|
||||||
|
|
||||||
|
if options['output']:
|
||||||
|
with open(options['output'], 'w', encoding='utf-8') as f:
|
||||||
|
f.write(json_output)
|
||||||
|
self.stdout.write(self.style.SUCCESS(f'JSON exported to {options["output"]}'))
|
||||||
|
else:
|
||||||
|
self.stdout.write(json_output)
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
<p><strong>Autoren:</strong> {{ standard.autoren.all|join:", " }}</p>
|
<p><strong>Autoren:</strong> {{ standard.autoren.all|join:", " }}</p>
|
||||||
<p><strong>Prüfende:</strong> {{ standard.pruefende.all|join:", " }}</p>
|
<p><strong>Prüfende:</strong> {{ standard.pruefende.all|join:", " }}</p>
|
||||||
<p><strong>Gültigkeit:</strong> {{ standard.gueltigkeit_von }} bis {{ standard.gueltigkeit_bis|default_if_none:"auf weiteres" }}</p>
|
<p><strong>Gültigkeit:</strong> {{ standard.gueltigkeit_von }} bis {{ standard.gueltigkeit_bis|default_if_none:"auf weiteres" }}</p>
|
||||||
|
<p><a href="{% url 'standard_json' standard.nummer %}" class="button" download="{{ standard.nummer }}.json">JSON herunterladen</a></p>
|
||||||
|
|
||||||
<!-- Start Einleitung -->
|
<!-- Start Einleitung -->
|
||||||
{% if standard.einleitung_html %}
|
{% if standard.einleitung_html %}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ urlpatterns = [
|
|||||||
path('<str:nummer>/', views.standard_detail, name='standard_detail'),
|
path('<str:nummer>/', views.standard_detail, name='standard_detail'),
|
||||||
path('<str:nummer>/history/<str:check_date>/', views.standard_detail),
|
path('<str:nummer>/history/<str:check_date>/', views.standard_detail),
|
||||||
path('<str:nummer>/history/', views.standard_detail, {"check_date":"today"}, name='standard_history'),
|
path('<str:nummer>/history/', views.standard_detail, {"check_date":"today"}, name='standard_history'),
|
||||||
path('<str:nummer>/checkliste/', views.standard_checkliste, name='standard_checkliste')
|
path('<str:nummer>/checkliste/', views.standard_checkliste, name='standard_checkliste'),
|
||||||
|
path('<str:nummer>/json/', views.standard_json, name='standard_json')
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
from django.shortcuts import render, get_object_or_404
|
from django.shortcuts import render, get_object_or_404
|
||||||
from django.contrib.auth.decorators import login_required, user_passes_test
|
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 .models import Dokument, Vorgabe, VorgabeKurztext, VorgabeLangtext, Checklistenfrage
|
||||||
from abschnitte.utils import render_textabschnitte
|
from abschnitte.utils import render_textabschnitte
|
||||||
|
|
||||||
@@ -102,3 +105,135 @@ def incomplete_vorgaben(request):
|
|||||||
return render(request, 'standards/incomplete_vorgaben.html', {
|
return render(request, 'standards/incomplete_vorgaben.html', {
|
||||||
'vorgaben_data': vorgaben_data,
|
'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)
|
||||||
|
|||||||
@@ -31,6 +31,6 @@
|
|||||||
<div class="flex-fill">{% block content %}Main Content{% endblock %}</div>
|
<div class="flex-fill">{% block content %}Main Content{% endblock %}</div>
|
||||||
<div class="col-md-2">{% block sidebar_right %}{% endblock %}</div>
|
<div class="col-md-2">{% block sidebar_right %}{% endblock %}</div>
|
||||||
</div>
|
</div>
|
||||||
<div>VorgabenUI v0.942</div>
|
<div>VorgabenUI v0.943</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user