From 5e0de3014e0f50ba3a9c328ce78e5dd34ca10c6e Mon Sep 17 00:00:00 2001 From: Tim Leikauf Date: Wed, 6 May 2026 21:44:53 +0200 Subject: [PATCH] =?UTF-8?q?feat(setup):=20/api/setup-words-pictures=20?= =?UTF-8?q?=E2=80=93=20M2M-Relation=20words=E2=86=94pictures=20einrichten?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Einmaliger Setup-Endpoint: setzt special=m2m auf Alias-Felder, erstellt Relations für words_pictures Junction in Directus. Co-Authored-By: Claude Sonnet 4.6 --- app.py | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/app.py b/app.py index b096ba6..fd46837 100644 --- a/app.py +++ b/app.py @@ -1575,6 +1575,64 @@ def setup_directus_schema(): "failed": len(failed), "results": results}) +@app.route("/api/setup-words-pictures", methods=["POST"]) +def setup_words_pictures(): + """ + Einmalig ausführen: Konfiguriert die M2M-Relation words ↔ pictures + via words_pictures Junction in Directus. + Idempotent – bereits vorhandene Felder/Relationen werden übersprungen. + """ + token = request.headers.get("Authorization", "") + results = [] + + def do(label, method, path, body=None): + data, status = _directus(method, path, token, body) + ok = status in (200, 201, 204) + results.append({"label": label, "status": status, "ok": ok, + "err": None if ok else (data.get("errors") or data)}) + return ok + + # Sicherstellen dass Junction-Collection existiert + _ensure_junction("words_pictures", "words_id", "pictures_id", token) + + # special=m2m auf Alias-Felder setzen (idempotent) + do("patch pictures.linked_words special", "PATCH", "/fields/pictures/linked_words", { + "type": "alias", + "meta": {"special": ["m2m"], "interface": "list-m2m", + "options": {"template": "{{words_id.title_de}}"}, + "note": "Verknüpfte Safe Words"}, + }) + do("patch words.linked_pictures special", "PATCH", "/fields/words/linked_pictures", { + "type": "alias", + "meta": {"special": ["m2m"], "interface": "list-m2m", + "options": {"template": "{{pictures_id.media}}"}, + "note": "Verknüpfte Bilder"}, + }) + + # Relation words_pictures.words_id → words + do("relation words_pictures.words_id→words", "POST", "/relations", { + "collection": "words_pictures", "field": "words_id", + "related_collection": "words", + "schema": {"on_delete": "CASCADE"}, + "meta": {"junction_field": "pictures_id", + "one_field": "linked_pictures", + "one_deselect_action": "nullify"}, + }) + # Relation words_pictures.pictures_id → pictures + do("relation words_pictures.pictures_id→pictures", "POST", "/relations", { + "collection": "words_pictures", "field": "pictures_id", + "related_collection": "pictures", + "schema": {"on_delete": "CASCADE"}, + "meta": {"junction_field": "words_id", + "one_field": "linked_words", + "one_deselect_action": "nullify"}, + }) + + failed = [r for r in results if not r["ok"]] + return jsonify({"ok": len(failed) == 0, "total": len(results), + "failed": len(failed), "results": results}) + + if __name__ == "__main__": app.run(host="0.0.0.0", port=8000, debug=True)