From 05da0c94acd5db7fca625c1358818c82c423f40e Mon Sep 17 00:00:00 2001 From: Matthias Nagel Date: Wed, 1 Oct 2025 08:19:05 +0200 Subject: [PATCH] feat: Implementierung von Phase 3 und Profilbearbeitung --- accounts/__pycache__/forms.cpython-313.pyc | Bin 2251 -> 2827 bytes accounts/__pycache__/models.cpython-313.pyc | Bin 2540 -> 2703 bytes accounts/__pycache__/urls.cpython-313.pyc | Bin 795 -> 876 bytes accounts/__pycache__/views.cpython-313.pyc | Bin 2284 -> 2980 bytes accounts/forms.py | 6 ++ accounts/migrations/0002_customuser_team.py | 20 +++++ .../0002_customuser_team.cpython-313.pyc | Bin 0 -> 1051 bytes accounts/models.py | 1 + accounts/templates/accounts/edit_profile.html | 10 +++ accounts/urls.py | 1 + accounts/views.py | 16 +++- clubs/__pycache__/admin.cpython-313.pyc | Bin 201 -> 417 bytes clubs/__pycache__/models.cpython-313.pyc | Bin 198 -> 1973 bytes clubs/admin.py | 4 +- clubs/migrations/0001_initial.py | 37 ++++++++++ .../__pycache__/0001_initial.cpython-313.pyc | Bin 0 -> 2452 bytes clubs/models.py | 19 ++++- db.sqlite3 | Bin 143360 -> 204800 bytes docs/phase3.md | 27 +++++++ docs/traceback/trace1.log | 69 ++++++++++++++++++ 20 files changed, 206 insertions(+), 4 deletions(-) create mode 100644 accounts/migrations/0002_customuser_team.py create mode 100644 accounts/migrations/__pycache__/0002_customuser_team.cpython-313.pyc create mode 100644 accounts/templates/accounts/edit_profile.html create mode 100644 clubs/migrations/0001_initial.py create mode 100644 clubs/migrations/__pycache__/0001_initial.cpython-313.pyc create mode 100644 docs/phase3.md create mode 100644 docs/traceback/trace1.log diff --git a/accounts/__pycache__/forms.cpython-313.pyc b/accounts/__pycache__/forms.cpython-313.pyc index 29c917aa423116406d8cf7bf5b385a5a432f3fd7..90fb9f64f6c4733d5e2872abad5743aac89d569a 100644 GIT binary patch delta 593 zcmX>t*e%BQnU|M~0SJT??qqysnaC%>IB%kQDVGF;5<@VD6hkoQ#2R^4&U7wK?u`q& zSw(+wsHW(t=IW_Nu4KH$mX=?Xn^>}PvIE-@#+8#<*t*rANi853VY zX0~JuX0c={Vh1~n73eTFQznSwB9378BF=OUP0m{)&ZWgA`MIIRsYT8iiFxU%Za@dV zlmMzLQU?(lAVO<$5SvZCBsQgbzNsaNFQtI0G}(*vL5dAPgdvD90uf+$n*dq2SV~e8 zbBm;bOur&CkQ9hnqy!?s_E~~hjz9urS}_lhXk)k`Al1QoLolP8t*9QX608Vph9*~$ z3`mD8h>!yj@*sj4L|B6e8xR2rHV{h@M4(w|2NDAjAO{p{0STa$f@0I9?_`{0p2#P`STa$)lqH=*lXK&#ZdTDM4%HMr)m%N*NKM9D zY-#yLxrrs3le5^4FltWLXLr%o0_qh3;$j{k(Z+B?K&pfFhG0%NTagk_pvV+NNCOE! zP2R}{?4px5vr94>O+L#m#byAOpTs3GnUy1o*-w*maw3=YiZs)5wngPX>Kq01&2)97Y5%x)-A zDt-eS=Fpx!dr*4t8jkeg4lJkG)E015Hynx<04B zZ|wKA14UwAbPZnjf0XepAyJs-j7XJ#aDM3jpGJso(U7hQNUcTYRMTRpooMS$QIQ}5jB0&#x_=>!IiRlkUOoaQiZ#&33 sQ%wktc;e)Ts;&EVz!01eTzhyVZp delta 508 zcmZ9IJxC)_5XX1Se!WfB_<@OTj4=>Aw(}4nqKM=$g`y%J+Q>;X?^IZ`@=k>mil7Kq zx(s4-aP9S}?Jci42#cUtTNvWicW)xs=yhmnQ^-Wd)gv2Kh={xu5VV8P6%I_1+YgzA=G<}Qc?{R9%jB8fL< zZY@KBn8c}4kM~|xFRQ=I{`VfK+eNoW3`#4~gdqY|2vs6vpLR;3xXZn=$dhjseZhCP zEAzaHjOAv=C>SgFzQ;?I_q&x^a(f%FUCDzuDYq7fD)Ls4d8G uyjE6Qd1y}U`Q<~8Pm5VxvNBl)$8bIPrjUJ0#9`oi^>#g2|D#CRn)4rK3Ud_z diff --git a/accounts/__pycache__/urls.cpython-313.pyc b/accounts/__pycache__/urls.cpython-313.pyc index a3046a622944ce33bc0c074055db14a01c05d817..c024d90841d468ca5e629bfb5f42c1a982aa7ac2 100644 GIT binary patch delta 183 zcmbQu_J&R4GcPX}0}#BByOZ&Xk%8echyw#)86f8~5936QXIe3gN({mLG0Z_?Fa-!Y zSRk0ql3Aa%h$mf8Q)sdn;~eQKj)J26w9K4T{aZY#DVZhlP_CaQ@8qqF^+2US?UPNI xVz{J$44~Z%#od!8>)Den=6$&C7N6$Wt9?p_Fj_GB@5CJ<_?cRXOk)0 zU|uQDIslPbH5Z)W&ah#YzR1;=`K`dYa1%q+#Z;UNM0k`RNQRXpFuQ1wB{;`yRUe}6 zAM}lmz^ZC_Cn4fL{mMXTr}V*j9>!II zJ#?O_hv=I-@MPstVPzw->u#t7n_k>_J@#^JtMgOO$DWn z_2ISQr=yi{Y-4;k+_tT@9lDSj`>CK%^P8J*XEtYcg59f9#aH#LbvxF%)$+M{tA5uv zv@H!m9jiC418WL9-UvsXSXM5tWvex&rXl%JPDhCOLYtclD>SDa*9Mm`fz{ zb~ceFDGQRe1r+$t27IZVU2uBaL{6oXg;9D~wtSBC0dJX4m0o4)P{bG?po<4c-$D95 iYTQR%M=g>EkKv<83=iVNZX|?$2nrs?$Kr43B>n|a;pc1s delta 394 zcmZ1?{zj1RGcPX}0}%L2-O1=8h#kmgm0~F32xbG4 zoayYE91}a_8JQ-o&=JyPyv664SC(0lSdy8a=bWFCx|xr$n30idaubsk8z0czBJRnD zm=ah;flSuT>deN>ygWdrCSwsdNRn%EI-7+PNS&rYkr0r&#hjj6Qp5t1;{b8l^OLet zlS_(=1VB6sl zR9*zKxCrbfMIft~6-X$6K#>SY3vW?sI?&YAqWH4R)bb)_pqRksBz6x*W-o6rX->TXz8$6cnN&OTu2ZXySpyn0P1$K%!e9A=xmQ-43PDZP)441TUJH zc=p2opf^vR_2kv%vYUyC2T$CVtlpirR7hZwnRy?-c{A_#-V9461MtCSe(ueP0Q^pr zd?;taaG487zy`Lk3W&gWaaCNAh_oUT`5u@8_kk_l2DaRg>S?q*K(;@UvYjZdP*qM6 zWxXmgqwTo_Q7;T4rnW-|`%xZ?1J%3vaddJh3)1QwyDcDyI^a!zNFa3l4J^`WM3mAZn0Wo`m;RC zlL9}+^VU$S6~+OLSaET2@d5M#k9x@G9;M~S&4}n6$Bb4S(Xbsym@t`Q)ZSo)j*kv8 ziC!Biu9jG<3R9Xs3J#bY#J?4XD7@#(0A`Pn&=RDy#v&gAk+4ZpR zeBu=uWg1L95HbToj*NZGye21UVwuzaXYw!0|y5!4@V>^HPfCt z&T9sh zrNnE-6h{z}q#{E;0oyY7!ZtSB0dlc#J}2QmKA_laq6jyU@57L|DDWagLt^Hno9A6; za{3>_bDm*BXsvTdR31ECl8U8G`5p{ZpwIWU*?}TWsBhN>MWB!OwCQ7Qx<5JBzdqS7 zPxZ=k$K|}SIeT`(P8MoD0cwx4IzAx_Tow3? i?($_I34$Edit Profile +
+ {% csrf_token %} + {{ form.as_p }} + +
+{% endblock %} diff --git a/accounts/urls.py b/accounts/urls.py index af5d7a2..ab96f4f 100644 --- a/accounts/urls.py +++ b/accounts/urls.py @@ -7,4 +7,5 @@ urlpatterns = [ path('register/', views.register_view, name='register'), path('login/', auth_views.LoginView.as_view(template_name='accounts/login.html'), name='login'), path('logout/', auth_views.LogoutView.as_view(), name='logout'), + path('profile/', views.edit_profile, name='edit_profile'), ] \ No newline at end of file diff --git a/accounts/views.py b/accounts/views.py index a7cbea1..b15b898 100644 --- a/accounts/views.py +++ b/accounts/views.py @@ -1,6 +1,7 @@ from django.shortcuts import render, redirect -from .forms import InvitationCodeForm, CustomUserCreationForm +from .forms import InvitationCodeForm, CustomUserCreationForm, CustomUserChangeForm from .models import InvitationCode +from django.contrib.auth.decorators import login_required def invitation_code_view(request): if request.method == 'POST': @@ -40,4 +41,15 @@ def register_view(request): return redirect('login') # Or wherever you want to redirect after registration else: form = CustomUserCreationForm() - return render(request, 'accounts/register.html', {'form': form}) \ No newline at end of file + return render(request, 'accounts/register.html', {'form': form}) + +@login_required +def edit_profile(request): + if request.method == 'POST': + form = CustomUserChangeForm(request.POST, instance=request.user) + if form.is_valid(): + form.save() + return redirect('edit_profile') # Or wherever you want to redirect + else: + form = CustomUserChangeForm(instance=request.user) + return render(request, 'accounts/edit_profile.html', {'form': form}) \ No newline at end of file diff --git a/clubs/__pycache__/admin.cpython-313.pyc b/clubs/__pycache__/admin.cpython-313.pyc index 65bf394c62b9c899cb82b352b5ba79a5f30c7a80..fe41b54019f83e4dd2c20936634fd8a13fd5bd0c 100644 GIT binary patch literal 417 zcmb79u}T9$5S_i-i{bFnqzZ^!drh{o5X45S1VnO{0ohBI%f-7}nY|R2RyGzkeuSSR zM3hBQv`Q!354f8cB&Ac#%zNcS?(c*nDn7Xkc1FB zvD5CkBh8aSjWiG^eCSt znw|+>oJ3o?HJu<_DblSPB3D delta 163 zcmZ3;e3G&LGcPX}0}z-?-pQ~B(vLwL7+``jJ_`UDQyGF8f*HLTycmlZ6&TW)G?`z5 zq%|3Du_mVEX6E^6GTq`!$x6&i&(}-N&nqd)Oe$gqDp<+z8Kmx(rG7?!ZmNE6USfJ` mj($K diff --git a/clubs/__pycache__/models.cpython-313.pyc b/clubs/__pycache__/models.cpython-313.pyc index ed0905076fe4d89b7156fd2d3b95c6e783c5ddd0..8e522ed17caa9ed5cce50c64e09cde10758a361e 100644 GIT binary patch literal 1973 zcmb_dJ!~UI6rQ!$_SzfUu@iI752uivKvqt1#fjWSCq;3RQ~nNlofCz*)!LrezN~k{ z>;~cjoh!sq5Sk#$lt~3tv`~@Kc4KSARaEH?IakAbyD=mo0SPh1x9`n+^X9#o_s#ag z;ShmwGX6{DOD`e6qS7C}bD_5b!U0i;BCL`Xfe8~RdsaOwUgn)3Nisz$P0~`xHRMYlUof>7kl7q5*1zj_?d0Z>isz%kaDWfH| z2#c`h0Y-Jrh6zKf(V}o+SCsK+d!qmcWRqks82jQK*lz>26mdCzEvj!>xO9TwPgl$u zP1g*qO!f5p%zQ?-ZJI7<7A;R272l>J&q$>PNepjv0a$Rn@I3vuwR; zP{UMJhBflwLPcXsRjQX*40UNUyXL4o@ChwgRh#nYx@OdKCZg+zN6w@3o4H5orm~n- z*B@sV*Lb9V%nS>&SOUEgSb%0%i>hYZtXkN$sRdh)fQ=;)h7tUIz{u7^fX_%*j&UC z^-@FkIn=uc_w@fXbpD1`b{gHwLN^g1FK4m*D+9c-=dKKBe;|M&&H7jbJZ@hxgE~pB zkEaA-WoXvR25-tkk^f;&ARO!&Q^G*IxDsJQ>H=L;G$XXWDfbLI=56sp{v} z|H4)l#k~d*@a1ut>UN*gr~_D4pKiD#yM^HND0b^cYM9~OurY*jgf|h8L=3OQrB7(d zWVBi~R%zYoY93gaR~F_oi(EveGi-1+3BV;~F{f^9uC4J>84GxeY~_29>ke}4Yc^X7+Ivs!ya$fv@Z=Ql#)>z>9+H+j30oM|U#j`lj~ zu!pP_M_UB&Aoe>bv2Bp6Knt7%Q6kd<*_1bX~JIz07;8*{Y5tYKa*zg>MJgtQ zLE(&m1H%FiZU^PA7SM}1?QgDWsOU?IPx)p&>0^>bY+EymRuZvDSu0Z2)=a}e=CN1ToVUX-S&H?`T zabUYc9&CGtFv3AB;!q|qi?9TI!)^J(IFj)JM+b0>wBTz@e$7oxQuJ%6Q?hKkm zsQ`{;(1||8|3e>oPP7o=QzzKioAHD9eIS`==i7E%o;XgI``ggYwV_QOr{R7)fCoLT zLnmp4yF;(2d8&=(;S*x;S|$iF82O*AIgLlLr#U6^3`rr{kH_dhF_9c+;k8z+J(a+b z4Hj6?t2u_W!V*ItEG7dis#a}N$y1`*q`*2VR4c1=PuV4VENl^~sk(NTu;?v9bEZWU zLoE{);N#Q30T4<%QdaLMIx&iNiG^;HoTb?W$ibYh8oR7ZEtEAwvuvn%lUl5&wI`Gm zlsp*2TSAl)o$GJHBil?O%8QwaI~vgo77J_;wantGWdW3G*h=11^Ce;dzDEL48#t__ zpYjr?1AO2G%>rBp3woz_Bc8%(J|_JvY#Iu5A7Yc2_#-8vf?*t@!V7t7Eu)Fe^s5pI;to)tE$c;3%hPb z+0m$F>zY9f69^#)q79cp1Kg=z>$X~{s5y`?(^s=g=Tt9Shz~ukp4^dH-k8_q5_XRauCB6(Ss|^y-=`>WkG7Uq zRNJOnu4)rYQRwSn&>{QUU22Fz_>?Q1uS@5@mE6gT&g8|P zr1^#)^@{ga8xiktv@VSv#0Q?l`|jUz2d3%+Q;z~aPSieDY6f)%tXj;5(+B6^=6UEZH?M&7K&-a3enKYYVIo2j48)Gl4CT`#%U?>O)~yH|_d zZG?lpUC)A2IMV2O6`d0gcieMx^>cHNXKPzKwO#8kLC}4R=-Kn>d=@nXA-;r;Y@VtQ zP3>>}aP|AEZaV9vvu=9bNw2%yT&O25 zJPLrl_^OMy9lY)0yo2*D)*Y<7xa#04KxL84#XdrL4mDozFbHaNhIrf}5VyX*9`W;K z`cCVnlM)+hCgyY@H{JZom~Le!o#iRkade(Hjh$xggr7@zW#-jKGkJJoHo@n(s5IBC v+jr?j*z!*d>kJGHzt8786b0Y-uR`KCVe$|0v`@SrabpusY~oJ=HXg=5#2ZN( literal 0 HcmV?d00001 diff --git a/clubs/models.py b/clubs/models.py index 71a8362..940cd6c 100644 --- a/clubs/models.py +++ b/clubs/models.py @@ -1,3 +1,20 @@ from django.db import models +from django.conf import settings -# Create your models here. +class Club(models.Model): + name = models.CharField(max_length=255) + website = models.URLField(blank=True) + administrators = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='administered_clubs') + + def __str__(self): + return self.name + +class Team(models.Model): + name = models.CharField(max_length=255) + club = models.ForeignKey(Club, on_delete=models.CASCADE, related_name='teams') + head_coach = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True, related_name='coached_teams') + assistant_coaches = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='assisted_teams', blank=True) + parent_team = models.ForeignKey('self', on_delete=models.SET_NULL, null=True, blank=True, related_name='child_teams') + + def __str__(self): + return self.name \ No newline at end of file diff --git a/db.sqlite3 b/db.sqlite3 index e3016ee9044cf9f87e74f41595f54374c088371c..985bf467237844bce8c56f20a3f595a64fe2c72b 100644 GIT binary patch delta 5152 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 diff --git a/docs/phase3.md b/docs/phase3.md new file mode 100644 index 0000000..c63bacd --- /dev/null +++ b/docs/phase3.md @@ -0,0 +1,27 @@ +## Phase 3: Organisationsstruktur + +Diese Phase befasst sich mit den Modellen für Clubs, Mannschaften und Teams. + + Schritt 1: Club-Modell erstellen + + Navigiere in das clubs-Verzeichnis und öffne models.py. + + Erstelle ein Club-Modell mit den Feldern name und website. + + Verknüpfe den Club mit dem User-Modell, um Administratoren zuzuweisen. + + Schritt 2: Mannschafts- und Team-Modelle erstellen + + Erstelle ein Team-Modell, das die Mannschaft repräsentiert, da in der Projektbeschreibung die Mannschaft als Team behandelt werden kann. Ein is_team Feld könnte hier nützlich sein, ist aber nicht notwendig, da die Beziehungen zu parent_team die Hierarchie festlegen. + + Ein Team-Modell hat die Felder: name, head_coach (Fremdschlüssel zu User), assistant_coaches (ManyToMany-Feld zu User), und parent_team (Fremdschlüssel zu sich selbst für die Untergliederung). + + Ein Team gehört zu einem Club. + + Schritt 3: Benutzerbeziehungen implementieren + + Stelle sicher, dass die Beziehungen zwischen User und Team korrekt definiert sind: + + Ein User kann Player sein und einem Team zugewiesen werden. + + Ein User kann HeadCoach oder AssistantCoach eines Team sein. diff --git a/docs/traceback/trace1.log b/docs/traceback/trace1.log new file mode 100644 index 0000000..c12817e --- /dev/null +++ b/docs/traceback/trace1.log @@ -0,0 +1,69 @@ +Traceback (most recent call last): + File "/usr/lib64/python3.13/threading.py", line 1043, in _bootstrap_inner + self.run() + ~~~~~~~~^^ + File "/usr/lib64/python3.13/threading.py", line 994, in run + self._target(*self._args, **self._kwargs) + ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/utils/autoreload.py", line 64, in wrapper + fn(*args, **kwargs) + ~~^^^^^^^^^^^^^^^^^ + File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/core/management/commands/runserver.py", line 134, in inner_run + self.check(**check_kwargs) + ~~~~~~~~~~^^^^^^^^^^^^^^^^ + File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/core/management/base.py", line 492, in check + all_issues = checks.run_checks( + app_configs=app_configs, + ...<2 lines>... + databases=databases, + ) + File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/core/checks/registry.py", line 89, in run_checks + new_errors = check(app_configs=app_configs, databases=databases) + File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/core/checks/urls.py", line 16, in check_url_config + return check_resolver(resolver) + File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/core/checks/urls.py", line 26, in check_resolver + return check_method() + File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/urls/resolvers.py", line 531, in check + for pattern in self.url_patterns: + ^^^^^^^^^^^^^^^^^ + File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/utils/functional.py", line 47, in __get__ + res = instance.__dict__[self.name] = self.func(instance) + ~~~~~~~~~^^^^^^^^^^ + File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/urls/resolvers.py", line 718, in url_patterns + patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module) + ^^^^^^^^^^^^^^^^^^^ + File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/utils/functional.py", line 47, in __get__ + res = instance.__dict__[self.name] = self.func(instance) + ~~~~~~~~~^^^^^^^^^^ + File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/urls/resolvers.py", line 711, in urlconf_module + return import_module(self.urlconf_name) + File "/usr/lib64/python3.13/importlib/__init__.py", line 88, in import_module + return _bootstrap._gcd_import(name[level:], package, level) + ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "", line 1387, in _gcd_import + File "", line 1360, in _find_and_load + File "", line 1331, in _find_and_load_unlocked + File "", line 935, in _load_unlocked + File "", line 1026, in exec_module + File "", line 488, in _call_with_frames_removed + File "/home/mnagel/Projekte/baseball_organisator/baseball_organisator/urls.py", line 22, in + path('accounts/', include('accounts.urls')), + ~~~~~~~^^^^^^^^^^^^^^^^^ + File "/home/mnagel/Projekte/baseball_organisator/venv/lib64/python3.13/site-packages/django/urls/conf.py", line 39, in include + urlconf_module = import_module(urlconf_module) + File "/usr/lib64/python3.13/importlib/__init__.py", line 88, in import_module + return _bootstrap._gcd_import(name[level:], package, level) + ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "", line 1387, in _gcd_import + File "", line 1360, in _find_and_load + File "", line 1331, in _find_and_load_unlocked + File "", line 935, in _load_unlocked + File "", line 1026, in exec_module + File "", line 488, in _call_with_frames_removed + File "/home/mnagel/Projekte/baseball_organisator/accounts/urls.py", line 2, in + from . import views + File "/home/mnagel/Projekte/baseball_organisator/accounts/views.py", line 2, in + @login_required + ^^^^^^^^^^^^^^ +NameError: name 'login_required' is not defined +