From d9109dab4114b7ecb5d256cdf2effdfd380c3035 Mon Sep 17 00:00:00 2001 From: Jonas Heinrich Date: Thu, 21 Aug 2025 10:15:41 +0200 Subject: [PATCH 01/10] update module --- flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index a1fa7bc..b3ba7e1 100644 --- a/flake.nix +++ b/flake.nix @@ -30,7 +30,7 @@ installPhase = '' mkdir -p $out/share # Project code - cp -r ${./fragdenrat} $out/share/fragdenrat + cp -r ${./fragdenrat/.} $out/share/fragdenrat/ # Django manage helper install -Dm755 ${./manage.py} $out/bin/fragdenrat-manage # Templates and static assets From a4d0d9491ca4df9ee711bb611526a14386ca1587 Mon Sep 17 00:00:00 2001 From: Jonas Heinrich Date: Thu, 21 Aug 2025 10:19:17 +0200 Subject: [PATCH 02/10] update module --- flake.nix | 4 ++-- result | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/flake.nix b/flake.nix index b3ba7e1..5cf142e 100644 --- a/flake.nix +++ b/flake.nix @@ -28,9 +28,9 @@ dependencies = with python3Packages; [ django requests jinja2 ]; installPhase = '' - mkdir -p $out/share + mkdir -p $out/share/fragdenrat # Project code - cp -r ${./fragdenrat/.} $out/share/fragdenrat/ + cp -r "${./fragdenrat}/." $out/share/fragdenrat/ # Django manage helper install -Dm755 ${./manage.py} $out/bin/fragdenrat-manage # Templates and static assets diff --git a/result b/result index 8440bcc..d20d10b 120000 --- a/result +++ b/result @@ -1 +1 @@ -/nix/store/wqsr5qqw8lj49hrags3pzairq70fwwb6-fragdenrat-0.1.0 \ No newline at end of file +/nix/store/kd30zy3wz9a81qh1iwpqxwky7y6gbnzd-fragdenrat-0.1.0 \ No newline at end of file From abc7d20fff2f988332e6a267e7890cdaed7f32ad Mon Sep 17 00:00:00 2001 From: Jonas Heinrich Date: Thu, 21 Aug 2025 10:21:22 +0200 Subject: [PATCH 03/10] update module --- module.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module.nix b/module.nix index 390bfaa..53e78bc 100644 --- a/module.nix +++ b/module.nix @@ -33,7 +33,7 @@ in chdir = "${pkgs.fragdenrat}/share/fragdenrat"; # Use absolute wsgi entrypoint to avoid module resolution issues - wsgi-file = "${pkgs.fragdenrat}/share/fragdenrat/fragdenrat/wsgi.py"; + wsgi-file = "${pkgs.fragdenrat}/share/fragdenrat/wsgi.py"; callable = "application"; socket = "${config.services.uwsgi.runDir}/fragdenrat.sock"; From 41e8bce03c666a7a1dcf22f5e07b8b1d1511beb1 Mon Sep 17 00:00:00 2001 From: Jonas Heinrich Date: Thu, 21 Aug 2025 10:27:38 +0200 Subject: [PATCH 04/10] update module --- module.nix | 9 +++++---- result | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/module.nix b/module.nix index 53e78bc..7803b2c 100644 --- a/module.nix +++ b/module.nix @@ -32,7 +32,7 @@ in type = "normal"; chdir = "${pkgs.fragdenrat}/share/fragdenrat"; - # Use absolute wsgi entrypoint to avoid module resolution issues + # Absolute WSGI entrypoint wsgi-file = "${pkgs.fragdenrat}/share/fragdenrat/wsgi.py"; callable = "application"; @@ -50,14 +50,15 @@ in "no-orphans" = true; env = [ - # Ensure python sees the app and dependencies - "PYTHONPATH=${pkgs.fragdenrat}/share/fragdenrat:${pkgs.fragdenrat.pythonPath}" + # Parent dir must be on sys.path so `import fragdenrat` resolves + "PYTHONPATH=${pkgs.fragdenrat}/share:${pkgs.fragdenrat.pythonPath}" "DJANGO_SETTINGS_MODULE=fragdenrat.settings" ]; settings = { "static-map" = "/static=${pkgs.fragdenrat}/share/fragdenrat/assets"; - pythonpath = "${pkgs.fragdenrat}/share/fragdenrat"; + # Mirror PYTHONPATH for uWSGI setting + pythonpath = "${pkgs.fragdenrat}/share"; }; }; }; diff --git a/result b/result index d20d10b..430629b 120000 --- a/result +++ b/result @@ -1 +1 @@ -/nix/store/kd30zy3wz9a81qh1iwpqxwky7y6gbnzd-fragdenrat-0.1.0 \ No newline at end of file +/nix/store/jsjajfw1bbm7h28fh8q64zignm6z09yn-fragdenrat-0.1.0 \ No newline at end of file From 08bf161f0937c8503e928cf14496b1b9b346a20b Mon Sep 17 00:00:00 2001 From: Jonas Heinrich Date: Thu, 21 Aug 2025 10:43:39 +0200 Subject: [PATCH 05/10] update module --- council/models.py | 5 ++ council/urls.py | 1 + council/views.py | 31 ++++++++++++- flake.nix | 2 + fragdenrat/urls.py | 3 ++ templates/base.html | 10 ++++ templates/council/member_detail.html | 68 ++++++++++++++++++++++++++-- 7 files changed, 114 insertions(+), 6 deletions(-) diff --git a/council/models.py b/council/models.py index 40aa047..0ecbc6e 100644 --- a/council/models.py +++ b/council/models.py @@ -55,6 +55,11 @@ class Question(models.Model): body = models.TextField() member = models.ForeignKey(Member, related_name="questions", on_delete=models.CASCADE) created_at = models.DateTimeField(auto_now_add=True) + # asker metadata + asker_first_name = models.CharField(max_length=150, blank=True) + asker_last_name = models.CharField(max_length=150, blank=True) + asker_city = models.CharField(max_length=150, blank=True) + asker_email = models.EmailField(blank=True) class Meta: verbose_name = "Frage" diff --git a/council/urls.py b/council/urls.py index b97155f..798a6a7 100644 --- a/council/urls.py +++ b/council/urls.py @@ -7,6 +7,7 @@ urlpatterns = [ path("gemeinden//", views.public_body_detail, name="public_body_detail"), path("mitglieder/", views.members, name="members"), path("mitglieder//", views.member_detail, name="member_detail"), + path("mitglieder//frage/stellen", views.ask_question, name="ask_question"), path("parteien/", views.parties, name="parties"), path("parteien//", views.party_detail, name="party_detail"), path("fragen/", views.questions, name="questions"), diff --git a/council/views.py b/council/views.py index 0161474..644bf8b 100644 --- a/council/views.py +++ b/council/views.py @@ -1,4 +1,5 @@ -from django.shortcuts import render, get_object_or_404 +from django.shortcuts import render, get_object_or_404, redirect +from django.contrib import messages from .models import PublicBody, Party, Member, Question, Vote @@ -39,6 +40,34 @@ def member_detail(request, pk: int): ) +def ask_question(request, pk: int): + member = get_object_or_404(Member, pk=pk) + if request.method != "POST": + return redirect("member_detail", pk=member.pk) + + title = request.POST.get("title", "").strip() + asker_first_name = request.POST.get("asker_first_name", "").strip() + asker_last_name = request.POST.get("asker_last_name", "").strip() + asker_city = request.POST.get("asker_city", "").strip() + asker_email = request.POST.get("asker_email", "").strip() + + if not title or not asker_first_name or not asker_last_name or not asker_city or not asker_email: + messages.error(request, "Bitte alle Pflichtfelder ausfüllen.") + return redirect("member_detail", pk=member.pk) + + Question.objects.create( + title=title, + body=title, + member=member, + asker_first_name=asker_first_name, + asker_last_name=asker_last_name, + asker_city=asker_city, + asker_email=asker_email, + ) + messages.success(request, "Frage wurde eingereicht.") + return redirect("member_detail", pk=member.pk) + + def parties(request): items = Party.objects.all() return render(request, "council/parties.html", {"items": items}) diff --git a/flake.nix b/flake.nix index 5cf142e..b00c55a 100644 --- a/flake.nix +++ b/flake.nix @@ -31,6 +31,8 @@ mkdir -p $out/share/fragdenrat # Project code cp -r "${./fragdenrat}/." $out/share/fragdenrat/ + # Django app: council + cp -r ${./council} $out/share/fragdenrat/council # Django manage helper install -Dm755 ${./manage.py} $out/bin/fragdenrat-manage # Templates and static assets diff --git a/fragdenrat/urls.py b/fragdenrat/urls.py index de090f4..264b370 100644 --- a/fragdenrat/urls.py +++ b/fragdenrat/urls.py @@ -1,7 +1,10 @@ from django.contrib import admin from django.urls import path, include +from django.views.generic import TemplateView urlpatterns = [ path("admin/", admin.site.urls), + path("impressum", TemplateView.as_view(template_name="impressum.html"), name="impressum"), + path("datenschutz", TemplateView.as_view(template_name="datenschutz.html"), name="datenschutz"), path("", include("council.urls")), ] \ No newline at end of file diff --git a/templates/base.html b/templates/base.html index 2e3eaca..33758b5 100644 --- a/templates/base.html +++ b/templates/base.html @@ -39,6 +39,16 @@ {% block content %}{% endblock %} + + {% block extra_js %}{% endblock %} diff --git a/templates/council/member_detail.html b/templates/council/member_detail.html index 4d78d99..16b1645 100644 --- a/templates/council/member_detail.html +++ b/templates/council/member_detail.html @@ -1,11 +1,26 @@ {% extends "base.html" %} {% block title %}{{ member }} – Stadträt:in{% endblock %} {% block content %} -

{{ member.first_name }} {{ member.last_name }}

-

- {% if member.public_body %}in {{ member.public_body.name }}{% endif %} - {% if member.party %} • {{ member.party }} (Profil){% endif %} -

+
+
+

{{ member.first_name }} {{ member.last_name }}

+

+ {% if member.public_body %}in {{ member.public_body.name }}{% endif %} + {% if member.party %} • {{ member.party }} (Profil){% endif %} +

+
+
+ +
+
+ +{% if messages %} +
+ {% for message in messages %} +
{{ message }}
+ {% endfor %} +
+{% endif %}

Fragen an {{ member.first_name }}

    @@ -33,4 +48,47 @@
  • Keine Abstimmungen.
  • {% endfor %}
+ + + {% endblock %} \ No newline at end of file From d46510191371a4f59338ec57323ad8f04ac950aa Mon Sep 17 00:00:00 2001 From: Jonas Heinrich Date: Thu, 21 Aug 2025 10:49:18 +0200 Subject: [PATCH 06/10] update module --- flake.nix | 8 ++------ fragdenrat/settings.py | 11 +++++++++-- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/flake.nix b/flake.nix index b00c55a..4f8a751 100644 --- a/flake.nix +++ b/flake.nix @@ -36,12 +36,8 @@ # Django manage helper install -Dm755 ${./manage.py} $out/bin/fragdenrat-manage # Templates and static assets - if [ -d ./templates ]; then - cp -r ./templates $out/share/fragdenrat/ - fi - if [ -d ./assets ]; then - cp -r ./assets $out/share/fragdenrat/ - fi + cp -r ./templates $out/share/fragdenrat/ + cp -r ./assets $out/share/fragdenrat/ ''; passthru.pythonPath = python3Packages.makePythonPath dependencies; diff --git a/fragdenrat/settings.py b/fragdenrat/settings.py index fd08fb6..c1525c0 100644 --- a/fragdenrat/settings.py +++ b/fragdenrat/settings.py @@ -2,6 +2,7 @@ from pathlib import Path import os BASE_DIR = Path(__file__).resolve().parent.parent +PROJECT_DIR = Path(__file__).resolve().parent DATA_DIR = Path(os.environ.get("FRAGDENRAT_DATA_DIR", str(BASE_DIR))) SECRET_KEY = os.environ.get("SECRET_KEY", "dev-secret-key-change-me") @@ -33,7 +34,10 @@ ROOT_URLCONF = "fragdenrat.urls" TEMPLATES = [ { "BACKEND": "django.template.backends.django.DjangoTemplates", - "DIRS": [BASE_DIR / "templates"], + "DIRS": [ + BASE_DIR / "templates", + PROJECT_DIR / "templates", + ], "APP_DIRS": True, "OPTIONS": { "context_processors": [ @@ -61,6 +65,9 @@ USE_I18N = True USE_TZ = True STATIC_URL = "/static/" -STATICFILES_DIRS = [BASE_DIR / "assets"] +STATICFILES_DIRS = [ + BASE_DIR / "assets", + PROJECT_DIR / "assets", +] STATIC_ROOT = DATA_DIR / "staticfiles" DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" \ No newline at end of file From 8b6da2d7a20d3cab15140d333d0dbd64ff4ec704 Mon Sep 17 00:00:00 2001 From: Jonas Heinrich Date: Thu, 21 Aug 2025 11:04:07 +0200 Subject: [PATCH 07/10] update module --- module.nix | 60 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 15 deletions(-) diff --git a/module.nix b/module.nix index 7803b2c..33b863d 100644 --- a/module.nix +++ b/module.nix @@ -5,34 +5,67 @@ ... }: let - cfg = config.services.fragdenrat; - + dataDir = "/var/lib/fragdenrat"; + manageCmd = "${pkgs.fragdenrat}/bin/fragdenrat-manage"; + pythonPath = "${pkgs.fragdenrat}/share:${pkgs.fragdenrat.pythonPath}"; + envVars = [ + "PYTHONPATH=${pythonPath}" + "DJANGO_SETTINGS_MODULE=fragdenrat.settings" + "FRAGDENRAT_DATA_DIR=${dataDir}" + ]; in { - options = { services.fragdenrat = { - enable = lib.mkEnableOption "FragDenRat web app"; - }; }; config = lib.mkIf cfg.enable { + # Ensure data dir exists with proper perms + systemd.tmpfiles.rules = [ + "d ${dataDir} 0750 fragdenrat fragdenrat -" + "d ${dataDir}/staticfiles 0750 fragdenrat fragdenrat -" + ]; + + # One-shot setup: migrate DB and collect static into dataDir + systemd.services.fragdenrat-setup = { + description = "Initialize FragDenRat database and static files"; + wantedBy = [ "multi-user.target" ]; + after = [ "network-online.target" ]; + serviceConfig = { + Type = "oneshot"; + User = "fragdenrat"; + Group = "fragdenrat"; + WorkingDirectory = dataDir; + Environment = envVars; + }; + script = '' + set -euo pipefail + ${manageCmd} migrate --noinput + ${manageCmd} collectstatic --noinput + ''; + }; + + # uWSGI app services.uwsgi = { enable = true; plugins = [ "python3" ]; - + postActivation = '' + # Ensure setup runs before uwsgi serves + ${config.systemd.package}/bin/systemctl start fragdenrat-setup.service + ''; instance = { type = "emperor"; vassals = { fragdenrat = { type = "normal"; - chdir = "${pkgs.fragdenrat}/share/fragdenrat"; + # Use data dir as working directory + chdir = dataDir; - # Absolute WSGI entrypoint + # Absolute WSGI entrypoint in Nix store wsgi-file = "${pkgs.fragdenrat}/share/fragdenrat/wsgi.py"; callable = "application"; @@ -49,15 +82,12 @@ in need-app = true; "no-orphans" = true; - env = [ - # Parent dir must be on sys.path so `import fragdenrat` resolves - "PYTHONPATH=${pkgs.fragdenrat}/share:${pkgs.fragdenrat.pythonPath}" - "DJANGO_SETTINGS_MODULE=fragdenrat.settings" - ]; + env = envVars; settings = { - "static-map" = "/static=${pkgs.fragdenrat}/share/fragdenrat/assets"; - # Mirror PYTHONPATH for uWSGI setting + # Serve collected static files from dataDir + "static-map" = "/static=${dataDir}/staticfiles"; + # Python import path for the app and its deps pythonpath = "${pkgs.fragdenrat}/share"; }; }; From a3cbd290a73742c0d1922e98bd09aadf717a9083 Mon Sep 17 00:00:00 2001 From: Jonas Heinrich Date: Thu, 21 Aug 2025 11:07:01 +0200 Subject: [PATCH 08/10] update module --- module.nix | 4 ---- 1 file changed, 4 deletions(-) diff --git a/module.nix b/module.nix index 33b863d..6e95863 100644 --- a/module.nix +++ b/module.nix @@ -53,10 +53,6 @@ in services.uwsgi = { enable = true; plugins = [ "python3" ]; - postActivation = '' - # Ensure setup runs before uwsgi serves - ${config.systemd.package}/bin/systemctl start fragdenrat-setup.service - ''; instance = { type = "emperor"; vassals = { From 47b18c8014608ce3d3db3c1276ff26d4e4492801 Mon Sep 17 00:00:00 2001 From: Jonas Heinrich Date: Thu, 21 Aug 2025 11:12:44 +0200 Subject: [PATCH 09/10] update module --- council/__pycache__/models.cpython-312.pyc | Bin 6349 -> 6666 bytes council/__pycache__/urls.cpython-312.pyc | Bin 971 -> 1084 bytes council/__pycache__/views.cpython-312.pyc | Bin 3920 -> 5552 bytes db.sqlite3 | Bin 217088 -> 221184 bytes .../__pycache__/settings.cpython-312.pyc | Bin 2454 -> 2595 bytes fragdenrat/__pycache__/urls.cpython-312.pyc | Bin 431 -> 745 bytes 6 files changed, 0 insertions(+), 0 deletions(-) diff --git a/council/__pycache__/models.cpython-312.pyc b/council/__pycache__/models.cpython-312.pyc index 347678779d2a6babb5d2aacfbe5a04c3e7358025..ba5165b43349b5b66b592d542f87c7e8380c3c5b 100644 GIT binary patch delta 950 zcmX?W*k!_ZnwOW0fq{Wx#jRx-+I$=Ntl1b>PWEEk%4oWYorRIxl7WHY7He{TPJYp3 zLvi`ddK^tmZ0-yU3`K5}w{e9tx=!Zfp2P_eU|?XF?7%NJc|UhJOoiGrd`WsH;K8Pz7==MbD+!`nPLm{**iJ%x1*$7&{!ix?Q9_$CMP zN}`GJgT&aO>L#;_Dl)Q8Ru?t2;Rq~EEiTE-&nsdBS!D-uIAhvek# zVoLQfAT638<5`mOQ!0!6Kzxv&Zm~N%20J^txZYyRP0dY8Eh^FmN$G%;3M3Y1rxwMh zWfm2e#OEdErrzR*h~y-~1h^mq$(bdUMLr-s+z^4(+{DbBB3Y18x}YGo78m6Y0`WkE zDFXvT@zzNK!8s4a)hCo)7gxV1uD-!|N6Hm(=L;+%H^kH?q+J(NyC|l%L3u~W6)~p< z{~Lme6U43yDqa*+ToJs3<%*zfgVzlqDC~;-AwC9cNll4Qsw@HpaZ%jlKw%xO zG>|e7;W@coxQP|S0wti$$|4SoYM_`7DFP+pTdZaIC8@>bJdrbZzrUpsb_8@oi7l5QdLxn_1ARPd|?n|l=`AEd6k4R0A<4T AEdT%j delta 674 zcmeA&IcvywnwOW00R+x2%TVOq$Y;&Qs5#k-Z7ZY6CUzD^ZVLtmhFh%3`8oMTlMe{U zZ`R{zVq$Y+U|=Y6oxF`JoY7@6ANM4fz%uRv7*mGFh|ztrKaU=pHAu1b<7`2$;w*%U6|ZC}asUZCGB7ZNOui#zGue#al{J)sfx&um1OF6J zkmP3`1_p)(h8z6C{Z*Y+7dRv*+p)+@7T{qMiw0@c1ewT^l%G;r<@Y zo<9)81reqU3=G9-livvhPYz&ZnLI^Mf-!LNJPygt#{_v8*@HoL7uip~DOAsz!oa}b zH91yzI%D+YufiIP{*&cI>;Sf>;ioaW|W%(tk#YG@zXfhQ!fpl>* zFfeE`6*){kCRW54G5H~z9BUo}14H!W81W3osL4mg)z}h1>S88;6jzmp2Sbq-ND%B= zRuBv9TKCDO5^9jRv;(<|KN}!t!n8PMFKczG$)vl;~@0_U+_6zTmeGKTA(b&jG?h6^0xFI~ zrHHLzTg?m+Nau{=trXXknB2p-&Ok9Yvm`wyGc_f(NZ%$iuf(b#+fF~NC^0=%zqlkd zCnq)U7EfYvc6?!JYH>+se%@qDCLcz=$!$z7Ohp2dk23{vi7_xRFfuSO6mOoa%$y@| lfm3Hi>UBMbi+TaMVaP3~bf;TGoNXKLgw5@BFq008qXG^PLm delta 105 zcmdnPahhHIG%qg~0|NsC``Kj~&P)spk3k$5=7BOkCu~%YW#mZbh~lXf)fAh&g>l{F w$xPmiyp!)UxlGnz_U961U|?WmU|=X-Fu9RAXA+Acw;(4!QzLhgFarYv09-W`_5c6? diff --git a/council/__pycache__/views.cpython-312.pyc b/council/__pycache__/views.cpython-312.pyc index c138571c86c4e42acc44ffb3cf28c23902f56503..d85b83db61d866c3b072c7253e524647e3b84a33 100644 GIT binary patch delta 2471 zcmca0w?UilG%qg~0|NuY*;~spDtIRHN!0f-FfdGKNMT4}%wfo7jAG1Xiek!Tj$&p6 zi81A{~&0pOlrFToRvO6mMc+a*LxVH6^nsHMvBS z@fJsJYH@L5dTQ~+1IJkf7#JAXCigJzb>U!OV7SE&(N=tmIWZ@vh?#+bVI@-$9|HqJ zkuU=TLopKr1A~G>5kE*NZ$W8NPG)j^QhrKiYH^V`0|NusdGIL5&i*9kG zWEPiX<|UUD$%EuT?$Km}xJLpcAOj*m1{TSISRh5kY+yGkD8Sq)1a~KYN@aXXYDr>d zPLVPL0|WnL0oGm>wnBnGwuqzD}B znye6Ss)3|5K?GP4NWPdA=0j*iIWmudfuVun4zJvtviWs0C-34& zWfYt&!zIb2!93ZVOP!e^i)FGRvxr5uIRitHcnLcw6@hRHa}84#D5^jlB)o=kH7NcW z7#M;XY8bM(CI_+$GxAPWWESRSNnwS_W${n8XO>|>Q^1Cz;5`?H0(KMy=P^y-Kv7`N zEX~S>W(Oy_ihA}M<|2+7mLj$q)*_Y~wj!n)_F~-h%f>X#taM$RT6GRiRq~d<)uX_ zsS2r?dFiP|sUQROH2DyD=N4OTYDq?ZN)ae46oK=IF34}p>8T~RSc^-FG7E}8<-jf0 z`qZML{GuXmkolnKxy6=Tl$uzQdW*fdG&wo7xLA_|J)?mgiN$HfpgaL8S3nq&^>`AC zv*Qa(Q;SP7^YeNdFDVCQSEYpk0gc8Oj74!`&e{uOTP zJy&{O;WxX$VfKJWxZkJK=Q@wfMIMHP^+} zFN&*Q(6HL!bXnZ~y145_ao5Y@?iW}@ZivZF&zYEWT}ki+TedfP-42wM49V?iWdbH7wBwYx-4jXUC{EPpyg#j>jtkILXy*UChA-lQo1Ol zw7_q6ESg{&_N**17TS9uV7oxxsvk=x6uU_qasilJ=qLgGP4xHYY9lDfxS=$R|g=% zeez3ABSyi^GF%fG*+A*PNOkgNZgob@$+x)`>p__eTy}%2uOd(ptH}*XW?*Z;RSTj5 z03`rOrJx8(Pf8#HoU%ZUfK^Q3)QH7kjEae;KrpeW1YRZCGcYjtOzz=X%qTe7fOj^d z=HxTHGO+3hYzrv;60D9uegJzUVzM%yJv*qd^V1ZcoXICs56&&O_)@YG^V0M6lJoOQ ziZYWR`GhSuKP5G%xCrb+u-Cy=6xdoGkT*f?1aKhTVlFNz0@t75fV;(hqA{u1? delta 1119 zcmdm>eL;@zG%qg~0|Ntt@Y!V<5*!oxB88M6u+uMzQ9yMX}|wN3rK}L~$@Oq_DIwL~*9DwlG9-rLd)Pr!l3lx3EOgmQch-ad{TZ&W@>Sf zC<6ln=j8oNCS3d=S(f6Q()7uG0%DtmnN1iO#U^{O34>(VL4*)Unk_9erzExL7Dq~EaY<%ga!HXaNRF9-fkBh42<#p)kbo4302x>$ z17d*`6@x5M00W3Sh2ZYwPpOPgNi9jt%qdc2U|`^z?8Ms4$UoViUvlz&)`^S~lMC6T ztU>(j~#bz_60B zNM*7GhiN^?ahe=OEFcLq(=|Y1U@Jh1ia_>gvO>J60+Lb(5nx3i`C?XZEGWPuA~!WR zDYXdZHBANv26>Pp^B5Qy8W`^I%FQX8UpI5|8;(@4XD6G1y~t7o4{k{4gKWk09XMP; zgw|vU0V78K&E5hN8QIi84pN@{NKlv1zQ6OAEb~3 z#ZeJBbU`jHQUDpp2_is_fWsSoNh+&=r!Nj5xc--nSFfiy(-YvA4k$-Z$@N7o) z$-jkVVDSpJ1#B~+cm??Z>=En9K_d3-pj7RrDLi?Gh)n%0w%q)b)STiXus^^a1ji`Y za8Q;m0%aj^mbk@STv7y1Zs6d##hjT}QUr=3NQwoy6>P~$h9Zy+kR;1tlbfGXnv-f* zWXiz6zzB*=e+CAI56p~=jQ1JLCP#?s%YG7LVsvHvz{SbPHY52n11BTfX9*@ocSf)= E0LI_XtN;K2 diff --git a/db.sqlite3 b/db.sqlite3 index 7ed9b0fb4fd16300a1bc2bc6aea3928bfeebc035..ac4eee1d94b9027ecce122a1f0f04a2406948b7c 100644 GIT binary patch delta 445 zcmZozz}s+ucY?H_9s>h|85A=zFfc?<)G=n%+nBI~pIMZvcQU(xCKFfh#>Qx_xEN7Z z2I)%2vo6H`4)Q&Te&!_BXyBw3}n_)VDkU-EnM@8&P#@8+MyAJ4yn z{|dheztqM?F@8~DL1tYJr~}{@P4?8^#wglku+4yx#ei9mId40A0;4h0#t9~j+w+nc zC!JyB+RV6tSz$X%0MlQ6Z3YGgLB=l(yiPpc+M)%$$W%A zmTwE=7p@ityN!(}7`d8#eb~iybs5`yr@JIEs!pHR&crdjER~UedP5T9TV5RnC4}dv z^JFqgu|fFL)iN37IU(${%%bUnDU6CRDgG2j1xC&7QyQ2$S+}dUFEh rnbyuEwtZ_m({<+UTl$!M7#BS-SayJE!o&b>MwQKi4e$9U2CxDEsIP@H delta 258 zcmZoTz}v8ZcY?H_E&~IDDFXs{Pt-AH)ZLh{gr8Z2>-A)I0nLq#ySX;MmXc%@Fr%i_KaH76T6wjw%_eyy3WkPz`(4ru~CJ2`<6Z?A4W#5&5RHJ>n}UNGywqQ C97e$a diff --git a/fragdenrat/__pycache__/settings.cpython-312.pyc b/fragdenrat/__pycache__/settings.cpython-312.pyc index b3ae2f5932c16f5268fd925c571c77a5f75a755f..84fad05e123b2e6d7554184709bef8da4f4d9bf5 100644 GIT binary patch delta 550 zcmbOxyjXhxU@|HZfBq4?%lPPQ|>@dT#q$dVQ$)#|VF+}m6(yb`9VL+> z7$un^7$ub=6D6I>mLdyMo60T$VWcxf$)s|p$bkf-WK-m$4w LL8!=#fq?-4{iSTA delta 468 zcmZ21GEJE8G%qg~0|Ntt!=+^z8`&rFNib?mR4)=|%HjiwqT(#Ui66vGIaAqIGeRU* zGeK!6KZ+|AhsMb^jPjP;xMU%wAd@L}i6NCUl`BO8q!Q-K6v;VEnT%1QDN<2lDbi8mDS}ZFDS}awDKb$~ zscb2-Ahqd?QPQbgDRNcZ91ILmGAZ&=vYQt$Rk1M2O_pZ2*qp#_&&XxYz`y_ssA8wd zD>-y0zvJlFydfw#!~3G3`UL@v8zK@9coaS{uqyL?U}hKL`pC({%JzYokC&-|^Mk_V tO`J~3H$-G+R9qBMzaXq}fkEH~pV$o9i+pMg+&4r`E;0xenKCdi008f8SJ?mn diff --git a/fragdenrat/__pycache__/urls.cpython-312.pyc b/fragdenrat/__pycache__/urls.cpython-312.pyc index 8c58cdfac033535f70c429f3a4b2b175c8f8bfe2..6cafa8bbf8c918aa4143f889f904e0e0f2e271cb 100644 GIT binary patch literal 745 zcmX@j%ge>Uz`)RdYgxt&Mh1q*APx+3LK&YwFfcGoXGmd4Va#F3WsG8E1hJWNm~xq; zm~&a8SipSd9M)X6C^kk0CWchz6qZ!REIz1yBq~b)i34S>W`Z!l`dFD5QrWVEAR@?Q z3fmg?)r=646xKBytC=Beur5xVy10;ZaiZzsW@1QXN#TK+3Ufy~OB7cnuO{D1kOi8I zw^$QXax?QZnQpNZB$i~{V$aM=&M8ev)nvTI6Ox)+kds)F8kU(_Ud0Ahr+Ma(KhFk23#ql5|x427-atablN>YpRidQmx z28F{fL;Z~W+*JMiyu3>Nf};Ga)Z~(4{j{RQ^pw=RqQnwpCde?og34PQHo5sJr8%i~ zMPdvL44}9xE?{6__`uA_$at4Q;XZ@vT?XBcYz(ZN9TF2vr&~?5nr=VQ{xXa5O%{$0 z=?h|76LPMLX*!yNzs delta 264 zcmaFKx}I76G%qg~0|Ntt_pxOe%NQ6K9)mbA%noIIu9&E<7{kPn%ACTS%9sV#0F{DL zSv*h%61AEM!U5}JVPZ&SNnu^h2oZzHr87mbSF&lcPnKbnm#$(C%v?=mRd zXHfmf#=y$iAu+*py46Ih>Gl)tFS97$WZ~!#>I|O{cbQk^GK=a5R%U*tM(!eB1_lNI DD}OVI From f5d9873de7aa25abb60f86cf2f6ec8f9bdb5c9a9 Mon Sep 17 00:00:00 2001 From: Jonas Heinrich Date: Thu, 21 Aug 2025 11:15:19 +0200 Subject: [PATCH 10/10] update module --- templates/base.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/base.html b/templates/base.html index 33758b5..327f623 100644 --- a/templates/base.html +++ b/templates/base.html @@ -13,7 +13,7 @@ .navbar-brand img { height: 36px; } - + -
+
{% block content %}{% endblock %}
-