Phase 3: Django-natives DMS – Paperless-NGX durch DokumentDatei ersetzt

- Neues Modell DokumentDatei mit PostgreSQL FTS (SearchVectorField, GinIndex)
- Upload-Pfad: dokumente/YYYY/MM/<uuid>/dateiname
- 7 DMS-Views: list, detail, download, upload (HTMX Drag&Drop), delete, edit, search_api
- Templates: list, detail, edit, upload mit Drag&Drop-Zone, Partials
- URLs: /dms/ komplett verdrahtet
- Sidebar: DMS als Primäreintrag, Paperless als Legacy
- Migrationsskript: manage.py migrate_paperless_dokumente (DokumentLink → DokumentDatei)
- compose.yml: paperless-Dienst deaktiviert (Legacy-Kommentarblock)
- Migration 0048 angewendet

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
SysAdmin Agent
2026-03-11 11:10:08 +00:00
parent ee2c827d85
commit a79a0989d6
16 changed files with 1219 additions and 35 deletions

View File

@@ -0,0 +1,119 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}{{ dok.titel }} DMS Stiftungsverwaltung{% endblock %}
{% block content %}
<div class="row">
<div class="col-lg-8">
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="h3">
{% if dok.is_pdf %}
<i class="fas fa-file-pdf text-danger me-2"></i>
{% else %}
<i class="fas fa-file text-primary me-2"></i>
{% endif %}
{{ dok.titel }}
</h1>
<div class="d-flex gap-2">
<a href="{% url 'stiftung:dms_download' pk=dok.pk %}" class="btn btn-outline-success">
<i class="fas fa-download me-2"></i>Herunterladen
</a>
<a href="{% url 'stiftung:dms_edit' pk=dok.pk %}" class="btn btn-outline-secondary">
<i class="fas fa-edit me-2"></i>Bearbeiten
</a>
<a href="{% url 'stiftung:dms_list' %}" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-2"></i>Zurück
</a>
</div>
</div>
<!-- Metadaten -->
<div class="card shadow mb-4">
<div class="card-header bg-dark text-white py-2">
<span class="small fw-bold"><i class="fas fa-info-circle me-2"></i>Dokument-Informationen</span>
</div>
<div class="card-body">
<dl class="row mb-0">
<dt class="col-sm-4 text-muted small">Typ</dt>
<dd class="col-sm-8"><span class="badge bg-secondary">{{ dok.get_kontext_display }}</span></dd>
{% if dok.beschreibung %}
<dt class="col-sm-4 text-muted small">Beschreibung</dt>
<dd class="col-sm-8">{{ dok.beschreibung }}</dd>
{% endif %}
<dt class="col-sm-4 text-muted small">Dateiname</dt>
<dd class="col-sm-8 font-monospace small">{{ dok.dateiname_original|default:dok.datei.name }}</dd>
<dt class="col-sm-4 text-muted small">Dateigröße</dt>
<dd class="col-sm-8">{{ dok.get_human_size }}</dd>
<dt class="col-sm-4 text-muted small">Hochgeladen am</dt>
<dd class="col-sm-8">{{ dok.erstellt_am|date:"d.m.Y H:i" }} Uhr</dd>
{% if dok.erstellt_von %}
<dt class="col-sm-4 text-muted small">Hochgeladen von</dt>
<dd class="col-sm-8">{{ dok.erstellt_von.get_full_name|default:dok.erstellt_von.username }}</dd>
{% endif %}
</dl>
</div>
</div>
<!-- Zuordnungen -->
{% if dok.destinataer or dok.land or dok.paechter or dok.verpachtung %}
<div class="card shadow mb-4">
<div class="card-header bg-dark text-white py-2">
<span class="small fw-bold"><i class="fas fa-link me-2"></i>Zuordnungen</span>
</div>
<div class="card-body">
{% if dok.destinataer %}
<div class="mb-2">
<span class="text-muted small"><i class="fas fa-user me-1"></i>Destinatär:</span>
<a href="{% url 'stiftung:destinataer_detail' pk=dok.destinataer.pk %}" class="ms-2">
{{ dok.destinataer.get_full_name }}
</a>
</div>
{% endif %}
{% if dok.land %}
<div class="mb-2">
<span class="text-muted small"><i class="fas fa-map me-1"></i>Länderei:</span>
<a href="{% url 'stiftung:land_detail' pk=dok.land.pk %}" class="ms-2">
{{ dok.land.lfd_nr }}{% if dok.land.gemeinde %} {{ dok.land.gemeinde }}{% endif %}
</a>
</div>
{% endif %}
{% if dok.paechter %}
<div class="mb-2">
<span class="text-muted small"><i class="fas fa-user-tie me-1"></i>Pächter:</span>
<a href="{% url 'stiftung:paechter_detail' pk=dok.paechter.pk %}" class="ms-2">
{{ dok.paechter.get_full_name }}
</a>
</div>
{% endif %}
{% if dok.verpachtung %}
<div class="mb-2">
<span class="text-muted small"><i class="fas fa-handshake me-1"></i>Verpachtung:</span>
<a href="{% url 'stiftung:land_verpachtung_detail' pk=dok.verpachtung.pk %}" class="ms-2">
Vertrag #{{ dok.verpachtung.pk|stringformat:'s'|slice:':8' }}
</a>
</div>
{% endif %}
</div>
</div>
{% endif %}
<!-- Aktionen -->
<div class="d-flex gap-2 mt-2">
<form method="post" action="{% url 'stiftung:dms_delete' pk=dok.pk %}"
class="d-inline" onsubmit="return confirm('Dokument „{{ dok.titel }}" unwiderruflich löschen?')">
{% csrf_token %}
<input type="hidden" name="next" value="{% url 'stiftung:dms_list' %}">
<button type="submit" class="btn btn-outline-danger btn-sm">
<i class="fas fa-trash me-2"></i>Dokument löschen
</button>
</form>
</div>
</div>
</div>
{% endblock %}