From 5394b63ebb3a9594ec5f92bc4ec789eeadbd9185 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Mon, 8 Dec 2025 02:33:51 +0000 Subject: [PATCH] numbero 1 --- core/__pycache__/models.cpython-311.pyc | Bin 1872 -> 2917 bytes core/__pycache__/urls.cpython-311.pyc | Bin 657 -> 742 bytes core/__pycache__/views.cpython-311.pyc | Bin 3939 -> 5303 bytes core/migrations/0002_clubmembership.py | 28 +++++++++++++++++ .../0002_clubmembership.cpython-311.pyc | Bin 0 -> 1568 bytes core/models.py | 14 ++++++++- core/templates/base.html | 3 ++ core/templates/core/club_list.html | 29 ++++++++++++++++++ core/templates/core/index.html | 2 +- core/urls.py | 3 +- core/views.py | 25 +++++++++++++-- 11 files changed, 98 insertions(+), 6 deletions(-) create mode 100644 core/migrations/0002_clubmembership.py create mode 100644 core/migrations/__pycache__/0002_clubmembership.cpython-311.pyc create mode 100644 core/templates/core/club_list.html diff --git a/core/__pycache__/models.cpython-311.pyc b/core/__pycache__/models.cpython-311.pyc index 39bb88db6f4a2fff7f6483bd550f53bbf6fbae3f..fdd89df3545218f26da97e86a854d14b0ffc430a 100644 GIT binary patch literal 2917 zcmaJ@O>7fK6yEi&?e)((*lAM;K^O{=Od4B}P?|^)Z5l)Q5pG2cs1{o^o@PoH+HpT|169f${G1ym@cmzIpR~ zGy9J$2RUf>=4OiPwDtIi7GikB6heAXUOQJR3Zu3%AoSUGVVr^$qB}?JHc)kJHUbM1(ZF zmbg@|t!xu8zu~Q5MSY@_skUks^84YygndkA_ZWzm+;3b7{+$Lv_zY&RsTB$#M1z(e z82CW^V=`6HD>PMGscB{{MW4`o&D2@yvCbYERW(mjd7aUeQ-EakspVG`!(@u`ER0Dd zdzu8X3|!|r*BKdo{?jH@8(`@c@;+jhb}(17yMwRt(Fxjo4!2AQA$@dRhK_ zK`-X1VfhJtpw`M}7M>5Q0A5AYA1f*$L+n6++3ZL{XP6zYVb=k+>~pEKzdoCXZ_hy5`UnxctWs(D^LZ+EShC%iFsgy4O@mw;gHKgCzkcu_~DB6xpN%-CqMvq zVq-5-&5<-*Tj}@L-e;VCQ%c)F%p_tg3XUv>VibfGST%^^SaM?M_=hwK>|9r(5!LTb{08=?}K#({1_m zK;MjQ-T&}QQ@-1h@3!T;V2GZ_kmt89HluT`=v+HGSHF%-zsw`mkCM)Ga1ujw7hwR~ zZUe-C?m(IYdpz|X+|L`li|T%txAa->fbET-w;S;^1Q#KJ_HZbQaFBUjZweD1P*o;= zfUaakaGSnKD=U;4g<_S(Az+qGf*hJ+AN{)st-%y=M2ia>+*9EqZ z(t`8xafy8oE(mzzUl3h^=lKpd(Hy=y+*EV;>WW?-J`xU#wb|zjJ2<{KFh(LgZZJp7 hS7U!p?AW%wgC6k!4|O>#*6+Nyw}az*M;PtO{SR5%fK>nh delta 521 zcmY+BJ4?hs5XX0u+sj>!i;vUuQHUTaX%qwx3lYv|;{zX+f+1#Cjpnkl$$?m^U*Oon z&Qh@yOTU0v33e%LMC58aD|ezIZt)xDKePLv-F+)RS=M#2Xd<;<$1A?2H>~ddZIxXh ziYN|H4R2zMG_-)Ic8;jd@PXF2>}t_dDWfFvBb75WyN+z535VG@$<{b!L3I0E!q|}S zcx3`?lKcicj^}+A(4;_FMFmj=kYDIB)K<;30Giim>%4o>7I9UX zz^25QYKI#}XY$hQm5-(?^MwLQeZK(Pv~(T- diff --git a/core/__pycache__/urls.cpython-311.pyc b/core/__pycache__/urls.cpython-311.pyc index 65aa3aabde49159bc6621fae0f866c19cd1e53a3..995d448a4647b46c63f2e5ece65c1da9efa5197d 100644 GIT binary patch delta 305 zcmbQp`ixb5IWI340}yyvm}M3)GB7*_abSQG%J_V2qPo6RE_)O^BLfpdDq{+3DsvVG zOjQco#08=g8$Bm(V71{(Wl!N>!@i7}fnhZeLqIxf6laP+FoUMxOOSvj<1Lng#FC7c zK1ZHyb}w12+g32?I?802NJ1od5s; delta 229 zcmaFHI+0aWoHJK;#GpbK^WOOv})8xFxosyN9 zm!7XzT9i{<#0*qe#0er;K?EC!U7fa5Z*ukuXi0g7!neDaZ>0u!J(8AqN1WCKvY3{0HiAB5INb!*=W~>w`*u3 zQ=>Lgec(W}9O$2#LzNc6fr>~)JyFy{Z(T>060H=eQpG)0FA=BC>?V{@7(IWUH*enT z_ukB#zcN3|!VmFylmhwe*imgcwjk`Gzh5}eQ#XQzAWbQh!s#I+TnKx5K#vq6N^qVk zL}4YQ#|*x}8}UNi5DJ3l5!OW`QAl`tL~k>ag(T>V64g^id!Zfl80_Aq@PKJ04!B!Q zD8f9o1QhNe4^IlAJxbs_C5sDRWodTdm(H9kjOx|N4^?AQCFZntS*Bg#gR-TTh-S^6 zBBVloYRO#3UD{(|Rm%;RRBNJYsssspOA|!B zQq_p6Jp4F(fu>{j{m8zF4h-3k5Cd?-nmKW`sB4PLnZ>IrIe;r10t;}LB{|dw09+1( zn`o9KiS(i=W@@E!_4343O}$2rfaQ?gAN_*f|8P0_E?vhD02xjxT1AqF$(%Sy@Eg?|w zYW`su`;TY`{hNJ-?y>vnHo*#R`%u&jXAjevvo-oYy9B%MJ&$mmv5?=E)TozM*$8D} zL2Stkvi4*#WDhg#^%`4a?sH2FgoK|j@B#ugW+uEn|C&;Q-?G=a^4=cG!V=q(UMO7f z4ZX^DoGNqIs885&>KeWC9NW7W@k!fUL>dlQSmj$%qm*zhP~()yH_Q^;%RRgsPtH@X z3uM!gp8EfyDA8I#qhF38$3F5)r3ZqN6oAZ-cTmS`n(H2~RHbRCXUVKiO{u1NsjBO< z(o97wtBUlD&d+tBN0F#fQ739qnU#u?0Z+cJ5~*@YnoD_wIt7hjLf1^oD^~adzDGA? zK)_;2^=2~f7n4_Aok#%FO}Y@g3dZ{<-2g6EE*dI{;5>tXS0V@f2j(3EsMjg~6vxp4 zzh+`McyA#7lZ!kjMc#*{Gw1{PgL?lnB+P$$C%qENI-%@Zvg3CDYBINy%qO-L&VshP;N61mAnU|rmGtK?*lJPtVL#+{=D7)|kFOT6fWFFxfH zH_xu}T`PQ7lh3sH%#Bm)v9?O4#d4{VS0??eWWh+V#k#4jm8nYEBHCoWShc48UgR|mOst!E zg->2lp>T>;g_z_mdq~Kh?nBqWr3x`jzw2U`B-p74wiPdjcPWDX#LMrq@NuJ}RCV=z zG6ptm5N3+DzZCZ6k2}>Rcubmxyb)ZpvJ8a3qX95ySS%SS0DvB3!RNysDO P-z*sBGcTI_1&{N;FmBFw delta 769 zcmZutzi-n(6!s;yYdf}+CM8hRlBA)n4%%cuv>;WWN^C3$n7mjiXHp|OM&~3576yiuOB!oI=;16IyV#!v?D=ShvfyBgnXCZ!Cr_bN}{k`{|e!k$oa~w;7@9WM^_{NyJ z=g45X*}g**rZ6?qJ)LPU6>kA7Ju+g`Gh@rMWON}a#kOYyFEAr=V%Kwln~+^*7GQ;y z02i5hPoeg7-XMkP>G|0fq3SXvSs`Rpz;bFqK zDZXh3o!@FO=T}JuP1*Jgvb=+s=(n{su(jE-{*hD)nHDAeaFFTnOGd-lC*wXLrf6C% zzm8>_2qr*ggsDI7MIp=7v^Ng;MU1EjMS!CsZy>(}kg20I;3>MB%_eW5tCWWQ!RWC+ z4udDW3!aX6ZB5iRFmYnkXZxiU@*L;DMO4-s_BaLOS@}W2gRYd=IUL53>`x6YwQWF# z)W$CZ%Zz?7^l|cE()cz+|5Rhij=7jC5WS8WFT}AuA#LG1Pj8|Usel&qS?lP)Z7Gq9 zrUdxU-SXSz?XH6VmN@I~>bM)NinrCSz5fzYsNa5H*-tW7y7bk2K1vmH}_;7goK@qQNt@_qn`OgzyYOD3mT-pBjiQT2Uu2Lkc IrwDS!4-q=3Q~&?~ diff --git a/core/migrations/0002_clubmembership.py b/core/migrations/0002_clubmembership.py new file mode 100644 index 0000000..cc1dd06 --- /dev/null +++ b/core/migrations/0002_clubmembership.py @@ -0,0 +1,28 @@ +# Generated by Django 5.2.7 on 2025-12-08 02:30 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0001_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='ClubMembership', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('date_joined', models.DateTimeField(auto_now_add=True)), + ('club', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='core.club')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'unique_together': {('user', 'club')}, + }, + ), + ] diff --git a/core/migrations/__pycache__/0002_clubmembership.cpython-311.pyc b/core/migrations/__pycache__/0002_clubmembership.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..da9122ba408a3c6fbcf4647e313e99a9e09f2e55 GIT binary patch literal 1568 zcmbVMJ#gGa6kbVpI_ds=7o6N&6V6~JIm6r;#%3rOhQogWV#8o3GhAla(cP|PT~5+v zCB-b?^mg~{w{O4qo_?%U ziU=Bh?_KLp1);yhAZz&x<@|F{zC#2NX^i?3eC4rhD}6;0bILep=lgkE?W+=!(FP*9 zZxG4T{HTxt9Rcz&^tAO0MA}Ae^=~oUYD--6sP9{j>9u8Ev@MevzU4X|S8bQju{XTf zmwZYWgY&N>;S){#>B~ft5miRH%oI*nGyMoGkD;f{l>3FmR?B9HOca>WM+p;RmgL~c z6ZNEU1c=8|)LofqiDl*mSf1$5}OHE`Pk*&hfGl_%0qYYWS4!(u7&I!4B|Udcbv$GT3fC0KEH@ z4P1|6$FM0c5irIh*K#O<%t#>|cOM&sfCF&Y16{b$5i0nkyAFmNp+4oZ@A6y#z% zy}%fYT^KWw41CtxHzpHf0PBQKs6(hTJYXWj`AqND&JBEPd+iIn`Pu5)OL~rjn82m@b#efNRO6p-OmR zrMJD(TV3NtcS0{J=Vx>d$mr>Mch9wHHy8wtA9U&0bO`6L?!L?JdJ|(vyMoH@zZKVo z*uH}Wwe~cmoyh?cg`5acGhPhhaQeh5(&x^!Yu^?l?b=UTbp69qtruy%IIqmAhd1Lg z(q9#8SI_EmkLs7h#=^t!gOQPT`-d;e`VjP7`0 z(?4zcQPU4=L9FLzt8o?8Ukm4#!q=B$MZR2(>m|MT7=d^qM66UUsfVA4hrO9m(AIb} z4Mc|wI_V#(lSPBQ0cMcINuWAI*V#>zLZ9wP@+S#=%Ibo^O~Bs*?Wy*Dnsy(sMHq^o xmgj?r6-knSX=yG*t@J(1lxJqHhv+45tjNWlGVhke*ldxp*R2l literal 0 HcmV?d00001 diff --git a/core/models.py b/core/models.py index ac43acf..b2a11e3 100644 --- a/core/models.py +++ b/core/models.py @@ -1,4 +1,5 @@ from django.db import models +from django.contrib.auth.models import User class Club(models.Model): name = models.CharField(max_length=100) @@ -21,4 +22,15 @@ class BookRecommendation(models.Model): created_at = models.DateTimeField(auto_now_add=True) def __str__(self): - return f"{self.book_title} recommended for {self.club.name}" \ No newline at end of file + return f"{self.book_title} recommended for {self.club.name}" + +class ClubMembership(models.Model): + user = models.ForeignKey(User, on_delete=models.CASCADE) + club = models.ForeignKey(Club, on_delete=models.CASCADE) + date_joined = models.DateTimeField(auto_now_add=True) + + class Meta: + unique_together = ('user', 'club') + + def __str__(self): + return f"{self.user.username} joined {self.club.name}" \ No newline at end of file diff --git a/core/templates/base.html b/core/templates/base.html index c701a32..4ed9b2c 100644 --- a/core/templates/base.html +++ b/core/templates/base.html @@ -26,6 +26,9 @@ diff --git a/core/urls.py b/core/urls.py index fcada4d..8e6ace1 100644 --- a/core/urls.py +++ b/core/urls.py @@ -1,10 +1,11 @@ from django.urls import path from . import views -from .views import signup_view, login_view, logout_view +from .views import signup_view, login_view, logout_view, club_list urlpatterns = [ path('', views.index, name='index'), path('signup/', signup_view, name='signup'), path('login/', login_view, name='login'), path('logout/', logout_view, name='logout'), + path('clubs/', club_list, name='club_list'), ] \ No newline at end of file diff --git a/core/views.py b/core/views.py index a9eef7b..c4f7524 100644 --- a/core/views.py +++ b/core/views.py @@ -1,5 +1,6 @@ from django.shortcuts import render, redirect -from .models import Club, BookRecommendation +from .models import Club, BookRecommendation, ClubMembership +from django.db import IntegrityError import random def index(request): @@ -39,7 +40,8 @@ def index(request): 'captcha_error': captcha_error, }) -from django.contrib.auth import login, logout +from django.contrib.auth import login, logout, get_user +from django.contrib.auth.decorators import login_required from django.contrib.auth.forms import AuthenticationForm from .forms import SignUpForm @@ -68,4 +70,21 @@ def login_view(request): def logout_view(request): if request.method == 'POST': logout(request) - return redirect('/') \ No newline at end of file + return redirect('/') + +@login_required +def club_list(request): + if request.method == 'POST': + club_id = request.POST.get('club_id') + club = Club.objects.get(id=club_id) + user = get_user(request) + try: + ClubMembership.objects.create(user=user, club=club) + message = f"You have successfully joined {club.name}." + except IntegrityError: + message = f"You are already a member of {club.name}." + clubs = Club.objects.all() + return render(request, 'core/club_list.html', {'clubs': clubs, 'message': message}) + + clubs = Club.objects.all() + return render(request, 'core/club_list.html', {'clubs': clubs}) \ No newline at end of file