From b3d1c676f50d8a7df2ae9879c39bf7324bec399e Mon Sep 17 00:00:00 2001 From: y2-youssef <youssef2.youssef@live.uwe.ac.uk> Date: Fri, 28 Mar 2025 19:06:41 +0000 Subject: [PATCH] Update 82 files - /accounts/admin.py - /accounts/apps.py - /accounts/decorators.py - /accounts/forms.py - /accounts/models.py - /accounts/tests.py - /accounts/urls.py - /accounts/views.py - /accounts/__init__.py - /accounts/migrations/0001_initial.py - /accounts/migrations/__init__.py - /accounts/migrations/__pycache__/0001_initial.cpython-39.pyc - /accounts/migrations/__pycache__/__init__.cpython-39.pyc - /accounts/templates/accounts/login.html - /accounts/templates/accounts/signup.html - /accounts/__pycache__/admin.cpython-313.pyc - /accounts/__pycache__/admin.cpython-39.pyc - /accounts/__pycache__/apps.cpython-313.pyc - /accounts/__pycache__/apps.cpython-39.pyc - /accounts/__pycache__/auth_forms.cpython-39.pyc - /accounts/__pycache__/forms.cpython-313.pyc - /accounts/__pycache__/forms.cpython-39.pyc - /accounts/__pycache__/models.cpython-313.pyc - /accounts/__pycache__/models.cpython-39.pyc - /accounts/__pycache__/urls.cpython-313.pyc - /accounts/__pycache__/urls.cpython-39.pyc - /accounts/__pycache__/views.cpython-313.pyc - /accounts/__pycache__/views.cpython-39.pyc - /accounts/__pycache__/__init__.cpython-313.pyc - /accounts/__pycache__/__init__.cpython-39.pyc - /events/admin.py - /events/apps.py - /events/forms.py - /events/models.py - /events/tests.py - /events/urls.py - /events/views.py - /events/__init__.py - /events/migrations/0001_initial.py - /events/migrations/__init__.py - /events/migrations/__pycache__/0001_initial.cpython-39.pyc - /events/migrations/__pycache__/__init__.cpython-39.pyc - /events/templates/home.html - /events/templates/events/event_detail.html - /events/templates/events/event_form.html - /events/templates/events/event_list.html - /events/__pycache__/admin.cpython-313.pyc - /events/__pycache__/admin.cpython-39.pyc - /events/__pycache__/apps.cpython-313.pyc - /events/__pycache__/apps.cpython-39.pyc - /events/__pycache__/forms.cpython-313.pyc - /events/__pycache__/forms.cpython-39.pyc - /events/__pycache__/models.cpython-313.pyc - /events/__pycache__/models.cpython-39.pyc - /events/__pycache__/urls.cpython-313.pyc - /events/__pycache__/urls.cpython-39.pyc - /events/__pycache__/views.cpython-313.pyc - /events/__pycache__/views.cpython-39.pyc - /events/__pycache__/__init__.cpython-313.pyc - /events/__pycache__/__init__.cpython-39.pyc - /unihub_project/asgi.py - /unihub_project/settings.py - /unihub_project/urls.py - /unihub_project/views.py - /unihub_project/wsgi.py - /unihub_project/__init__.py - /unihub_project/__pycache__/settings.cpython-313.pyc - /unihub_project/__pycache__/settings.cpython-39.pyc - /unihub_project/__pycache__/urls.cpython-313.pyc - /unihub_project/__pycache__/urls.cpython-39.pyc - /unihub_project/__pycache__/views.cpython-313.pyc - /unihub_project/__pycache__/views.cpython-39.pyc - /unihub_project/__pycache__/wsgi.cpython-39.pyc - /unihub_project/__pycache__/__init__.cpython-313.pyc - /unihub_project/__pycache__/__init__.cpython-39.pyc - /Dockerfile - /manage.py - /Pipfile - /Pipfile.lock - /requirements.txt - /docker-compose.yml - /README.md --- Dockerfile | 22 ++ Pipfile | 16 ++ Pipfile.lock | 210 ++++++++++++++++++ README.md | 10 +- accounts/__init__.py | 0 accounts/__pycache__/__init__.cpython-313.pyc | Bin 0 -> 170 bytes accounts/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 117 bytes accounts/__pycache__/admin.cpython-313.pyc | Bin 0 -> 214 bytes accounts/__pycache__/admin.cpython-39.pyc | Bin 0 -> 158 bytes accounts/__pycache__/apps.cpython-313.pyc | Bin 0 -> 538 bytes accounts/__pycache__/apps.cpython-39.pyc | Bin 0 -> 398 bytes .../__pycache__/auth_forms.cpython-39.pyc | Bin 0 -> 756 bytes accounts/__pycache__/forms.cpython-313.pyc | Bin 0 -> 917 bytes accounts/__pycache__/forms.cpython-39.pyc | Bin 0 -> 711 bytes accounts/__pycache__/models.cpython-313.pyc | Bin 0 -> 1088 bytes accounts/__pycache__/models.cpython-39.pyc | Bin 0 -> 803 bytes accounts/__pycache__/urls.cpython-313.pyc | Bin 0 -> 560 bytes accounts/__pycache__/urls.cpython-39.pyc | Bin 0 -> 428 bytes accounts/__pycache__/views.cpython-313.pyc | Bin 0 -> 1531 bytes accounts/__pycache__/views.cpython-39.pyc | Bin 0 -> 966 bytes accounts/admin.py | 3 + accounts/apps.py | 6 + accounts/decorators.py | 11 + accounts/forms.py | 18 ++ accounts/migrations/0001_initial.py | 45 ++++ accounts/migrations/__init__.py | 0 .../__pycache__/0001_initial.cpython-39.pyc | Bin 0 -> 2280 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 128 bytes accounts/models.py | 31 +++ accounts/templates/accounts/login.html | 16 ++ accounts/templates/accounts/signup.html | 16 ++ accounts/tests.py | 3 + accounts/urls.py | 10 + accounts/views.py | 32 +++ docker-compose.yml | 27 +++ events/__init__.py | 0 events/__pycache__/__init__.cpython-313.pyc | Bin 0 -> 168 bytes events/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 115 bytes events/__pycache__/admin.cpython-313.pyc | Bin 0 -> 212 bytes events/__pycache__/admin.cpython-39.pyc | Bin 0 -> 156 bytes events/__pycache__/apps.cpython-313.pyc | Bin 0 -> 532 bytes events/__pycache__/apps.cpython-39.pyc | Bin 0 -> 392 bytes events/__pycache__/forms.cpython-313.pyc | Bin 0 -> 788 bytes events/__pycache__/forms.cpython-39.pyc | Bin 0 -> 577 bytes events/__pycache__/models.cpython-313.pyc | Bin 0 -> 1314 bytes events/__pycache__/models.cpython-39.pyc | Bin 0 -> 828 bytes events/__pycache__/urls.cpython-313.pyc | Bin 0 -> 458 bytes events/__pycache__/urls.cpython-39.pyc | Bin 0 -> 354 bytes events/__pycache__/views.cpython-313.pyc | Bin 0 -> 1821 bytes events/__pycache__/views.cpython-39.pyc | Bin 0 -> 1154 bytes events/admin.py | 3 + events/apps.py | 6 + events/forms.py | 7 + events/migrations/0001_initial.py | 30 +++ events/migrations/__init__.py | 0 .../__pycache__/0001_initial.cpython-39.pyc | Bin 0 -> 1075 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 126 bytes events/models.py | 18 ++ events/templates/events/event_detail.html | 7 + events/templates/events/event_form.html | 9 + events/templates/events/event_list.html | 16 ++ events/templates/home.html | 2 + events/tests.py | 3 + events/urls.py | 11 + events/views.py | 32 +++ manage.py | 22 ++ requirements.txt | 5 + unihub_project/__init__.py | 0 .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 176 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 123 bytes .../__pycache__/settings.cpython-313.pyc | Bin 0 -> 2792 bytes .../__pycache__/settings.cpython-39.pyc | Bin 0 -> 2449 bytes .../__pycache__/urls.cpython-313.pyc | Bin 0 -> 1289 bytes .../__pycache__/urls.cpython-39.pyc | Bin 0 -> 1089 bytes .../__pycache__/views.cpython-313.pyc | Bin 0 -> 377 bytes .../__pycache__/views.cpython-39.pyc | Bin 0 -> 294 bytes .../__pycache__/wsgi.cpython-39.pyc | Bin 0 -> 540 bytes unihub_project/asgi.py | 16 ++ unihub_project/settings.py | 137 ++++++++++++ unihub_project/urls.py | 26 +++ unihub_project/views.py | 4 + unihub_project/wsgi.py | 16 ++ 82 files changed, 841 insertions(+), 5 deletions(-) create mode 100644 Dockerfile create mode 100644 Pipfile create mode 100644 Pipfile.lock create mode 100644 accounts/__init__.py create mode 100644 accounts/__pycache__/__init__.cpython-313.pyc create mode 100644 accounts/__pycache__/__init__.cpython-39.pyc create mode 100644 accounts/__pycache__/admin.cpython-313.pyc create mode 100644 accounts/__pycache__/admin.cpython-39.pyc create mode 100644 accounts/__pycache__/apps.cpython-313.pyc create mode 100644 accounts/__pycache__/apps.cpython-39.pyc create mode 100644 accounts/__pycache__/auth_forms.cpython-39.pyc create mode 100644 accounts/__pycache__/forms.cpython-313.pyc create mode 100644 accounts/__pycache__/forms.cpython-39.pyc create mode 100644 accounts/__pycache__/models.cpython-313.pyc create mode 100644 accounts/__pycache__/models.cpython-39.pyc create mode 100644 accounts/__pycache__/urls.cpython-313.pyc create mode 100644 accounts/__pycache__/urls.cpython-39.pyc create mode 100644 accounts/__pycache__/views.cpython-313.pyc create mode 100644 accounts/__pycache__/views.cpython-39.pyc create mode 100644 accounts/admin.py create mode 100644 accounts/apps.py create mode 100644 accounts/decorators.py create mode 100644 accounts/forms.py create mode 100644 accounts/migrations/0001_initial.py create mode 100644 accounts/migrations/__init__.py create mode 100644 accounts/migrations/__pycache__/0001_initial.cpython-39.pyc create mode 100644 accounts/migrations/__pycache__/__init__.cpython-39.pyc create mode 100644 accounts/models.py create mode 100644 accounts/templates/accounts/login.html create mode 100644 accounts/templates/accounts/signup.html create mode 100644 accounts/tests.py create mode 100644 accounts/urls.py create mode 100644 accounts/views.py create mode 100644 docker-compose.yml create mode 100644 events/__init__.py create mode 100644 events/__pycache__/__init__.cpython-313.pyc create mode 100644 events/__pycache__/__init__.cpython-39.pyc create mode 100644 events/__pycache__/admin.cpython-313.pyc create mode 100644 events/__pycache__/admin.cpython-39.pyc create mode 100644 events/__pycache__/apps.cpython-313.pyc create mode 100644 events/__pycache__/apps.cpython-39.pyc create mode 100644 events/__pycache__/forms.cpython-313.pyc create mode 100644 events/__pycache__/forms.cpython-39.pyc create mode 100644 events/__pycache__/models.cpython-313.pyc create mode 100644 events/__pycache__/models.cpython-39.pyc create mode 100644 events/__pycache__/urls.cpython-313.pyc create mode 100644 events/__pycache__/urls.cpython-39.pyc create mode 100644 events/__pycache__/views.cpython-313.pyc create mode 100644 events/__pycache__/views.cpython-39.pyc create mode 100644 events/admin.py create mode 100644 events/apps.py create mode 100644 events/forms.py create mode 100644 events/migrations/0001_initial.py create mode 100644 events/migrations/__init__.py create mode 100644 events/migrations/__pycache__/0001_initial.cpython-39.pyc create mode 100644 events/migrations/__pycache__/__init__.cpython-39.pyc create mode 100644 events/models.py create mode 100644 events/templates/events/event_detail.html create mode 100644 events/templates/events/event_form.html create mode 100644 events/templates/events/event_list.html create mode 100644 events/templates/home.html create mode 100644 events/tests.py create mode 100644 events/urls.py create mode 100644 events/views.py create mode 100644 manage.py create mode 100644 requirements.txt create mode 100644 unihub_project/__init__.py create mode 100644 unihub_project/__pycache__/__init__.cpython-313.pyc create mode 100644 unihub_project/__pycache__/__init__.cpython-39.pyc create mode 100644 unihub_project/__pycache__/settings.cpython-313.pyc create mode 100644 unihub_project/__pycache__/settings.cpython-39.pyc create mode 100644 unihub_project/__pycache__/urls.cpython-313.pyc create mode 100644 unihub_project/__pycache__/urls.cpython-39.pyc create mode 100644 unihub_project/__pycache__/views.cpython-313.pyc create mode 100644 unihub_project/__pycache__/views.cpython-39.pyc create mode 100644 unihub_project/__pycache__/wsgi.cpython-39.pyc create mode 100644 unihub_project/asgi.py create mode 100644 unihub_project/settings.py create mode 100644 unihub_project/urls.py create mode 100644 unihub_project/views.py create mode 100644 unihub_project/wsgi.py diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..cedc68d --- /dev/null +++ b/Dockerfile @@ -0,0 +1,22 @@ +# Use the official Python image +FROM python:3.9-slimcd + +# Set the working directory +WORKDIR /code + +# Install system dependencies required for mysqlclient +RUN apt-get update && apt-get install -y \ + gcc \ + libmariadb-dev \ + pkg-config \ + && rm -rf /var/lib/apt/lists/* + +# Copy and install dependencies +COPY requirements.txt /code/ +RUN pip install --upgrade pip && pip install -r requirements.txt + +# Copy the project files +COPY . /code/ + +# Command to run the application +CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"] diff --git a/Pipfile b/Pipfile new file mode 100644 index 0000000..aee7311 --- /dev/null +++ b/Pipfile @@ -0,0 +1,16 @@ +[[source]] +url = "https://pypi.org/simple" +verify_ssl = true +name = "pypi" + +[packages] +django = ">=4.0" +mysqlclient = "*" +djangorestframework = "*" +pymysql = "*" +cryptography = "*" + +[dev-packages] + +[requires] +python_version = "3.13" diff --git a/Pipfile.lock b/Pipfile.lock new file mode 100644 index 0000000..5ac1f0f --- /dev/null +++ b/Pipfile.lock @@ -0,0 +1,210 @@ +{ + "_meta": { + "hash": { + "sha256": "2945d5ab87cd0426818793fb4ba82a8e6f0ecac5546e04c1fbb52e092c8cea36" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.13" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "asgiref": { + "hashes": [ + "sha256:3e1e3ecc849832fe52ccf2cb6686b7a55f82bb1d6aee72a58826471390335e47", + "sha256:c343bd80a0bec947a9860adb4c432ffa7db769836c64238fc34bdc3fec84d590" + ], + "markers": "python_version >= '3.8'", + "version": "==3.8.1" + }, + "cffi": { + "hashes": [ + "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8", + "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", + "sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1", + "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15", + "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36", + "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", + "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8", + "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36", + "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17", + "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf", + "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc", + "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3", + "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", + "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702", + "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1", + "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8", + "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", + "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6", + "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d", + "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b", + "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e", + "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be", + "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c", + "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", + "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", + "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c", + "sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8", + "sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1", + "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4", + "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655", + "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67", + "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595", + "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0", + "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", + "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41", + "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6", + "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401", + "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6", + "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3", + "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16", + "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93", + "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e", + "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", + "sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964", + "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c", + "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576", + "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0", + "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3", + "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662", + "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", + "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff", + "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5", + "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", + "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f", + "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", + "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14", + "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", + "sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9", + "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7", + "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382", + "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a", + "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e", + "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", + "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4", + "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99", + "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87", + "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b" + ], + "markers": "python_version >= '3.8'", + "version": "==1.17.1" + }, + "cryptography": { + "hashes": [ + "sha256:04abd71114848aa25edb28e225ab5f268096f44cf0127f3d36975bdf1bdf3390", + "sha256:0529b1d5a0105dd3731fa65680b45ce49da4d8115ea76e9da77a875396727b41", + "sha256:1bc312dfb7a6e5d66082c87c34c8a62176e684b6fe3d90fcfe1568de675e6688", + "sha256:268e4e9b177c76d569e8a145a6939eca9a5fec658c932348598818acf31ae9a5", + "sha256:29ecec49f3ba3f3849362854b7253a9f59799e3763b0c9d0826259a88efa02f1", + "sha256:2bf7bf75f7df9715f810d1b038870309342bff3069c5bd8c6b96128cb158668d", + "sha256:3b721b8b4d948b218c88cb8c45a01793483821e709afe5f622861fc6182b20a7", + "sha256:3c00b6b757b32ce0f62c574b78b939afab9eecaf597c4d624caca4f9e71e7843", + "sha256:3dc62975e31617badc19a906481deacdeb80b4bb454394b4098e3f2525a488c5", + "sha256:4973da6ca3db4405c54cd0b26d328be54c7747e89e284fcff166132eb7bccc9c", + "sha256:4e389622b6927d8133f314949a9812972711a111d577a5d1f4bee5e58736b80a", + "sha256:51e4de3af4ec3899d6d178a8c005226491c27c4ba84101bfb59c901e10ca9f79", + "sha256:5f6f90b72d8ccadb9c6e311c775c8305381db88374c65fa1a68250aa8a9cb3a6", + "sha256:6210c05941994290f3f7f175a4a57dbbb2afd9273657614c506d5976db061181", + "sha256:6f101b1f780f7fc613d040ca4bdf835c6ef3b00e9bd7125a4255ec574c7916e4", + "sha256:7bdcd82189759aba3816d1f729ce42ffded1ac304c151d0a8e89b9996ab863d5", + "sha256:7ca25849404be2f8e4b3c59483d9d3c51298a22c1c61a0e84415104dacaf5562", + "sha256:81276f0ea79a208d961c433a947029e1a15948966658cf6710bbabb60fcc2639", + "sha256:8cadc6e3b5a1f144a039ea08a0bdb03a2a92e19c46be3285123d32029f40a922", + "sha256:8e0ddd63e6bf1161800592c71ac794d3fb8001f2caebe0966e77c5234fa9efc3", + "sha256:909c97ab43a9c0c0b0ada7a1281430e4e5ec0458e6d9244c0e821bbf152f061d", + "sha256:96e7a5e9d6e71f9f4fca8eebfd603f8e86c5225bb18eb621b2c1e50b290a9471", + "sha256:9a1e657c0f4ea2a23304ee3f964db058c9e9e635cc7019c4aa21c330755ef6fd", + "sha256:9eb9d22b0a5d8fd9925a7764a054dca914000607dff201a24c791ff5c799e1fa", + "sha256:af4ff3e388f2fa7bff9f7f2b31b87d5651c45731d3e8cfa0944be43dff5cfbdb", + "sha256:b042d2a275c8cee83a4b7ae30c45a15e6a4baa65a179a0ec2d78ebb90e4f6699", + "sha256:bc821e161ae88bfe8088d11bb39caf2916562e0a2dc7b6d56714a48b784ef0bb", + "sha256:c505d61b6176aaf982c5717ce04e87da5abc9a36a5b39ac03905c4aafe8de7aa", + "sha256:c63454aa261a0cf0c5b4718349629793e9e634993538db841165b3df74f37ec0", + "sha256:c7362add18b416b69d58c910caa217f980c5ef39b23a38a0880dfd87bdf8cd23", + "sha256:d03806036b4f89e3b13b6218fefea8d5312e450935b1a2d55f0524e2ed7c59d9", + "sha256:d1b3031093a366ac767b3feb8bcddb596671b3aaff82d4050f984da0c248b615", + "sha256:d1c3572526997b36f245a96a2b1713bf79ce99b271bbcf084beb6b9b075f29ea", + "sha256:efcfe97d1b3c79e486554efddeb8f6f53a4cdd4cf6086642784fa31fc384e1d7", + "sha256:f514ef4cd14bb6fb484b4a60203e912cfcb64f2ab139e88c2274511514bf7308" + ], + "index": "pypi", + "markers": "python_version >= '3.7' and python_full_version not in '3.9.0, 3.9.1'", + "version": "==44.0.2" + }, + "django": { + "hashes": [ + "sha256:1323617cb624add820cb9611cdcc788312d250824f92ca6048fda8625514af2b", + "sha256:30de4ee43a98e5d3da36a9002f287ff400b43ca51791920bfb35f6917bfe041c" + ], + "index": "pypi", + "markers": "python_version >= '3.10'", + "version": "==5.1.7" + }, + "djangorestframework": { + "hashes": [ + "sha256:bea7e9f6b96a8584c5224bfb2e4348dfb3f8b5e34edbecb98da258e892089361", + "sha256:f022ff46613584de994c0c6a4aebbace5fd700555fbe9d33b865ebf173eba6c9" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==3.16.0" + }, + "mysqlclient": { + "hashes": [ + "sha256:199dab53a224357dd0cb4d78ca0e54018f9cee9bf9ec68d72db50e0a23569076", + "sha256:201a6faa301011dd07bca6b651fe5aaa546d7c9a5426835a06c3172e1056a3c5", + "sha256:24ae22b59416d5fcce7e99c9d37548350b4565baac82f95e149cac6ce4163845", + "sha256:2e3c11f7625029d7276ca506f8960a7fd3c5a0a0122c9e7404e6a8fe961b3d22", + "sha256:4b4c0200890837fc64014cc938ef2273252ab544c1b12a6c1d674c23943f3f2e", + "sha256:92af368ed9c9144737af569c86d3b6c74a012a6f6b792eb868384787b52bb585", + "sha256:977e35244fe6ef44124e9a1c2d1554728a7b76695598e4b92b37dc2130503069", + "sha256:a22d99d26baf4af68ebef430e3131bb5a9b722b79a9fcfac6d9bbf8a88800687" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==2.2.7" + }, + "pycparser": { + "hashes": [ + "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", + "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc" + ], + "markers": "python_version >= '3.8'", + "version": "==2.22" + }, + "pymysql": { + "hashes": [ + "sha256:4de15da4c61dc132f4fb9ab763063e693d521a80fd0e87943b9a453dd4c19d6c", + "sha256:e127611aaf2b417403c60bf4dc570124aeb4a57f5f37b8e95ae399a42f904cd0" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==1.1.1" + }, + "sqlparse": { + "hashes": [ + "sha256:09f67787f56a0b16ecdbde1bfc7f5d9c3371ca683cfeaa8e6ff60b4807ec9272", + "sha256:cf2196ed3418f3ba5de6af7e82c694a9fbdbfecccdfc72e281548517081f16ca" + ], + "markers": "python_version >= '3.8'", + "version": "==0.5.3" + }, + "tzdata": { + "hashes": [ + "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", + "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9" + ], + "markers": "python_version >= '2'", + "version": "==2025.2" + } + }, + "develop": {} +} diff --git a/README.md b/README.md index a4a019c..fef23e3 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Uni Hub - DSD Project +# GROUP_PROJECT_UWE @@ -11,18 +11,18 @@ Already a pro? Just edit this README.md and make it your own. Want to make it ea ## Add your files - [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files -- [ ] [Add files using the command line](https://docs.gitlab.com/topics/git/add_files/#add-files-to-a-git-repository) or push an existing Git repository with the following command: +- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command: ``` cd existing_repo -git remote add origin https://gitlab.uwe.ac.uk/y2-youssef/uni-hub-dsd-project.git +git remote add origin https://gitlab.uwe.ac.uk/m2-sefari/group_project_uwe.git git branch -M main git push -uf origin main ``` ## Integrate with your tools -- [ ] [Set up project integrations](https://gitlab.uwe.ac.uk/y2-youssef/uni-hub-dsd-project/-/settings/integrations) +- [ ] [Set up project integrations](https://gitlab.uwe.ac.uk/m2-sefari/group_project_uwe/-/settings/integrations) ## Collaborate with your team @@ -30,7 +30,7 @@ git push -uf origin main - [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html) - [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically) - [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/) -- [ ] [Set auto-merge](https://docs.gitlab.com/user/project/merge_requests/auto_merge/) +- [ ] [Set auto-merge](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html) ## Test and Deploy diff --git a/accounts/__init__.py b/accounts/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/accounts/__pycache__/__init__.cpython-313.pyc b/accounts/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..63ab691557bfd2616aeb18a6be3cf1feab5f7234 GIT binary patch literal 170 zcmey&%ge>Uz`)=bb|oD|KL!yn%m`(CW?^7pn97jOpvmaBlA(x+fq~&ONa~iSvsFxJ zacWU<jBjdsqC#*<eo<<SOMZD?PJUuaaZGwqerZ8`K~a8IYH~?@X?dz{ZenI$Ok#3! zeraAwaZG%CW?p7Ve7s&k<t+}I-29Z%oK(9aRt5$Jkj=#)#z$sGM#ds$1_lNIfqg7r literal 0 HcmV?d00001 diff --git a/accounts/__pycache__/__init__.cpython-39.pyc b/accounts/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0bc38790f85d990d9ad61ddc79c2ee330f977ba1 GIT binary patch literal 117 zcmYe~<>g{vU|^{4Kba1qAA<;F%*epN;K0DZP|U)>z>vZa%%I8Wx00a<B#a<_N$Dr& rr=;p9CMV~Y=9Lud$H!;pWtPOp>lIYq;;_lhPbtkwwFBw-3^E%4Gwc^h literal 0 HcmV?d00001 diff --git a/accounts/__pycache__/admin.cpython-313.pyc b/accounts/__pycache__/admin.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..81ef455e5599562790f2d46bee1fa32b66089b14 GIT binary patch literal 214 zcmey&%ge>Uz`)=bb|u}Ofq~&Mhy%k+P{wBg1_p+y48aV+jNS}hj75wJ4Czdo%r8OG znvAzt6H{_C^ZYcKZt<mLCFZ5)>m}#sl@w(r6)`g~Fsx+w3{rQ?&Dkm@v^ce>IL0?M zJy9XJB)=#%#wEWzFDE}Sr8p+ND8IBIzMv>SD>b<!zO+15H#adeFD5ZLIlnZoq&Nm_ rhh9PDEe@O9{FKt1RJ$S$1_lO31_p*=5aR<gBO~KI28ALv1_lNIfa*B> literal 0 HcmV?d00001 diff --git a/accounts/__pycache__/admin.cpython-39.pyc b/accounts/__pycache__/admin.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f588d68e1308cf3485b01f620556527c1fc08e69 GIT binary patch literal 158 zcmYe~<>g{vU|^{4KbdaNz`*br#6iYP3=9ko3=9m#0t^fcDGVu$ISjdsQH+cXDNMl( zn#?ajYBd>eu_mVEX6E^6GDY#FWF_XM=j$cs=am#?CKZ7USjkYt%)kI4eu?WR=clCV kCnhK7m*$le>w|Ub6;$5hu*uC&Da}c>V`N}p_zW@_0L@S$lK=n! literal 0 HcmV?d00001 diff --git a/accounts/__pycache__/apps.cpython-313.pyc b/accounts/__pycache__/apps.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c738dfa96d77fa16bb801c08988f041f288b900d GIT binary patch literal 538 zcmey&%ge>Uz`)=bb|rlZ0|Ucj5C?`?p^VRJ3=9lY8G;#t8NC_27>gJc7$g{!7=oFk z7=oE&7)_ZW>WY}sSu|N+f;gItw>TXO3Y_!v(lXPNK_W2B2xWYh0h<}aP{bI_P{b6> zSi~I6RKya@T*Mm8QpA?ds>ybX&oMbUzcjC;7-GLt}}D%q5*#Ju!;y_6)q-29Z( zoMJtv%yh@nl6<$!)SQ%C9EngpD;fMW*>7>g$LA&HrpCwL;);*Y%}*)K0kL`F;|og@ zbD%Q(@$qSyMa3mKnR%&s`SJ0$gi=z|5=(PR;uA|t^5fIM=CXhk-x7_FFD^+e$xMz< zEGa3<Oe!r&Esl>b;$UE4_zd#cEmvo&n9$<XqT(3e)bvD!;FA2J)EJli^1Ph<#FXNg z^rHOIg7|`>{H)aElK9f{RNdUf%)A(wn`06S3X1g#DvLlN4<<lfF6L!mU}$5wA!%`e zMeGK*XtPU^00RR9Sl&;Q`4%@cL_nI0Kyd+<0Xqt!P>_Lv;TDGt#QSzd!VC-yplB!- eVPIhRz|6?Vc$Y!(3mX%o*o4Th3`~q-U|j%@C6L1a literal 0 HcmV?d00001 diff --git a/accounts/__pycache__/apps.cpython-39.pyc b/accounts/__pycache__/apps.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d1fed5bf79691aeedf50c4e89bdb54f0097d347e GIT binary patch literal 398 zcmYe~<>g{vU|^{4Kbby-fq~&Mh=Yt-7#J8F7#J9e6&M&8QW#Pga~N_NqZk<(+!<1s zQkYv9QkYX2o0+4SQdoi+G+AGQ^lCER;&d!1aL&(5%S=xOi6CP}n290`3=F9ZQH&`J zQA{a}QOqe!Q7kFU!3>%#xA+{Blk-dSN{S(7RLQ1fCFZ5)>!l>=<>sfP<`nBWWu`lp zmgKu-rskyF;z)!l_tRv(#StH$mzbLxAAgH0K0Y@;r8Eb`=82ClEKSUT$_S;TrX`l< zl*A{NmgL8$fem2+$*p840)+>d_$8*FoS%}a4>Mdpv7n$>ub{GsnSp@;6fVUef`gHT t5iH`T$$X0&>Q0c#A|?g~2Cxj+G$ewXfq~%`hYiGScA)Sm2C3y?1^|?AUqJu> literal 0 HcmV?d00001 diff --git a/accounts/__pycache__/auth_forms.cpython-39.pyc b/accounts/__pycache__/auth_forms.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bab1fa326ecd5cb46eb917ffeaf73d9c11a7edb7 GIT binary patch literal 756 zcmYe~<>g{vU|`^yb~3$-k%8ech=Yt-7#J8F7#J9eEf^RWQW#Pga~N_NqZk=MY^EHh zT;?cdFq=7tC6_gdm65@nA%!J{wS^&tHI=!UIf^ZXEto-*{UyjuO~zZSY57ID#hQ$_ z1VW2bi=2y66H7Al^W5@_ay1!mv4F&qK`N0k+yxp83=F9ZQH&`JQB0}KSu81xDNHHM zy-ZQ82s@jZU^d?33eHT=3oQVd{qi3J14ETYP-<amW>IR2o<cxTepzNpszRbdSz=CR zib85`VrGs)VoFL;YH_iiCetmh+{B9boYcJZl8jrN8L2r1@g=DhB^YjFgoTa>irb=C zQW&FHQ<#DoG?}aT5$@3QO)W{(WVyvrTAW&xmzbM+ixq71EzW|(;^OlBq7*{})5uSg z?G{ITJV;%9{4K8d_}u)I(wx-z_**>j@r9*{IS`p5PypRx&CO3q&AG*vmYJH9QoNF( zNQi*}Lj01^PtH$C)lW=L&M(a?Db`OcEy;)n$Aex$<t-MFn>ax+3^Ip<k%h4c<QYFr z_99-85quzmA4D)QFfiQWas>sI8_1R-P|5)-Mpy=634@fgGB7Z(A<X4tDguf4X|ms9 zOUX*iOV2L?8z>3k=q2apl@w(r>499Q2X<W%Gsr?IZ1P~w7K42bHWgwm+{;BE2i)SY TfdrTx$ev=5Q+OD87<rfgo@ch* literal 0 HcmV?d00001 diff --git a/accounts/__pycache__/forms.cpython-313.pyc b/accounts/__pycache__/forms.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..24d3ee5ecbd76875656389e502afb456b82b9170 GIT binary patch literal 917 zcmey&%ge>Uz`)=bb|t-%k%8echy%l{P{!v71_p+y48aV+jNS}hj75wJAU2aXlNWOl zGnmcn&Emyc#0qA!c(Zx27qKfa#IP$dm_m&xVwGS}VhCoHVhCo7VK!xk2p4grvukp^ z1aUMOZ?UH37v&afGTsshElw?RE=o--$;{7l%P-2+WW2=!64PY7#h0F15?@-JS`?p~ zpOTuB4AKk3EKtU04X}G-7>XE!8H$*K8H<>~wlhgF1T&j5K~xp71hW*ern73Y-Qo() zOwS7~0NM1ClYxN&#ZahnhR+HZhQ_cIvFbAfGX*jhu>~_1v8S_WvfkoH7^df&T9Wt@ z6uz1)w>UtK&P&Wqy~UcEo0yq%i?blHxVSvOD8&%LG+N2vr^#`PBR(FaGCuwmS3Jm{ zr8%kb@wa&5;|og@bD%Q(@$qSyMa3mKnR%&s`SI~ZpxC;_3J#T9Y-yRPIVr`rMC0R& zOA<>mlj9RhN{TX*N=s6U<Kv4285kHogM#6fo3m96C}fLcd{fgC6@p9hi&A4;^2_sb z@)J{vW73QAOAF!)it@8klS|@D%Tsl86EpK-5|fkjOY=&KW56+{S5SG21?1HtZUzPh zkavrD7#JAZ7;XrNbg<qMbm(R)l4M|DD3S&dAiMoE*@}cf9AOY40wP2~1XzIthy_vw z(If@pa=-{s^c3@fP5;is#OlcSg#koDl!8?GX>#6TOUX*iOV2L?rLtR+5RP7QejX?U z^b$);GW5XiE&`>OTT<BM!J$|T2~uG!3X0fZ4g!ZI#CniRZ*kb<=BJeAq}mmM(hDO4 z14A(=HGW`bWMq8GAaR$$>@I`$T?V~}?4p<1#T!_@urM<^GF}i={K^1gfK37b4PWD0 literal 0 HcmV?d00001 diff --git a/accounts/__pycache__/forms.cpython-39.pyc b/accounts/__pycache__/forms.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8842586f3b933eb434500ad686c325b13c977a36 GIT binary patch literal 711 zcmYe~<>g{vU|{&JaW1`^k%8ech=Yt-7#J8F7#J9ey%-o6QW#Pga~N_NqZk=MY^EHh zT;?cdFq=7tC6_gd70hPIVasKYVrOJXWp8GPVs&RoVNGFcVMt+1Wo~AU;z(f+X3*q# z39?0#@fK@Zeo=0*CgUxE(Bjl0=c3falFa-(xBQ}9O~zX+ATdqGTYTxMCGn-jsYUU* z`6;P6$soPRm>K3uDFz0HRE8+V6ox1!cZL+k6s8u26sBgTDCQLAU<OT=TU^1J>3N|A zAoDRyVS<?=fn-W5a}-NDLki;}#wgYlreFq5<|=-K8G62{C5f6Ww>UtK%S+5ny~UcE zo0yq%i?blHxVSvOD8&%LH1gAAyTuV74^kH&e~T*~<eSo*)cE*YJn`{`rHMHZnIcf2 z-(m%O^%h%NW@=7K@k)jw0R{#L@k?AkIX@*;KQTEuzcjC;SRWjOdIgoYSU}DJMQAa| z2o6RT#v&mG1_nP(mLhJDZXOW93nD<m2ooVJL68I+0|NsmD8fOZ!NFJr;`?cG-eOD1 zO3X{oF9HeQl7w*dlJoOQiZYY*5=%=m^uVqt0!76wDQxm!{}e+!CyYfw5i87oh;!in eEdn|07Kcr4eoARhsvXD$#UM}eFoGcy8xsH*T&3Uu literal 0 HcmV?d00001 diff --git a/accounts/__pycache__/models.cpython-313.pyc b/accounts/__pycache__/models.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ba8f239623aa2c93a88e0d9e92951fd5d256a5e9 GIT binary patch literal 1088 zcmey&%ge>Uz`)=bb|qb&nStRkhy%l{P{wB?1_p+y48aV+jNS}hj75wJAU2aXlNWOl zvjT$zgAzk9vlK%xOAMnaGel1jOFFA2+e;8flkpahV^VQRQDSmQXmM(hCgUx(-29Z( zoZ@7VGz_yr8J`z{EsJ3&Vhm;|VhUy~Vh(01VhLt0Vhv^~VvAu3W;J1oVGU+8VTxf3 zW;bEdXD(uo;Rq6f>PMoK7=k%s*kf3NIW3usxMDbh#E>MROeKb3u3+w9o?u=}<{}=P zYWRZrp=x-81&a961vQ0kv4DK@l7)eR;TC&wNoh)IUdb(i<ow*+(!9))%J`hr#FW&c zTdavGxtV#l*n=S|ssx;2DinO6DjY#7UWza<FlaL0;>t~|h|fvQOE1Z|#h#pzpP8Im ze2YCLH7&6;r=*H2v9u&Z&%G$WwBVLda%pi%er|keacWU~I!LHEM3d<jPf==4Vo7RB zd|qO1>Mho!oW#8BDt@rOfYhSg%;MtA{JdM@$eIh_;>9Z&{51J*am0gl$H(8|ijU9D zPbtkwjgP;@6CYn#nwSGJH$MIre|&seW>IlTPG(+eUVeQ1E%xA$P#0IfkXr)I{=UAU zex4zb@jkAOF0MhhSRGw_J^gO+1o`{8#yflXdpf%Y7lA{L(>Wut$SpH9C*>APQGQP9 zEq>p`yvmS#5D5`xgLv(h0N9^MPQ4`>A75OOSdy6>pIA~-l$lgol3E-eUnI)F!0;Iq zy|>(*tztltR2<`*nx3c-T#{du8sm~*o|luKm{J@AHaNbZC_gJTxg@@{JXJS0F*7eF zF*!NEG_RyM29iqk3Mz|0i4#nK++5tqz`)SPaDz|0!TpA~<^>j!8$7}dt{>PKxCAF? zUf__q!6|t`TK58n-VIK^3G5d*BtEdSh_E&IeBfc=5xUMTeTiFoLD2@A6XF-S0~=gE zurct7T<2B3#H)ORL*$02<_$ifkL)abYz=N7xELhlu8Zql64$-KA$dbo4<aSOc9}(_ zNQHrc0qiC}P1ajdDOrhm>G^ue`FWs_&;v&|#QjB}EP0C)svso^9PVI^;E;ltqY6sJ x95#@swky(LU|?WmU|=W~XJBCXz|6?Vc$dNWE`!V$7I8+l4x6tG;*4xyjQ}AaGJF64 literal 0 HcmV?d00001 diff --git a/accounts/__pycache__/models.cpython-39.pyc b/accounts/__pycache__/models.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..06b64117f518bc5c816e0a6d6b766ae4ae82c94d GIT binary patch literal 803 zcmYe~<>g{vU|=|^dMaI>nStRkh=Yt-7#J8F7#J9ebr={JQW#Pga~N_NqZk=MY^EHh zT;?cdMh16=6y_9`7KRj-RK{lJD3%n~U<OULmmqUA8E^48CKZ<yB_@}I7N-_zGTvg# z%}+_qDNY7SBV$&WRdEaq45<uJj42FJOeu^}%qdJ!EGf)Utf|Z?ENM)sEGevMOsT9X zY-vpC%u#Hq>{%Qs?5S+2%qbkb%u$@F>{(nXoGDx>+$lW0%u(E6K5q&il+TmGAIzXB zaEk@xnke?-lG2paypkw^<ow*+(!9))%J`hr#FW&cTdavGxtV!U?7<KfRRYd16$(CJ z6;Z5?AQdk~7#J8dnQw9BCRW7fq~@iUWZYs;&dAS9PA$I0o|2lDSejE(#g$lElA-5b zlwVp9C6ruRT#}y~Us{}66rT<fDh|<Py2VqJnv+<Pni8Lvn45ZwH7O@CFT08#tS=z7 zC^xgXI5R&lN*q~p0bIP;Pm}i+M?6?>eEco0`1suXl+v8k`1o5q@$rSFi8&xs<Kv^) zgF`}HT>V0#1f2bSeM9{`Ln7mSTpe9pgKn`py7+qfMezjr`?$tCd-!`gy9O6AGcYjR z;&jePEON_C%}Ke%Qk0*QdW+vTF|RTtA4Ecg*&zP7B>?smlDk$i6p1o0K!{%w`pNkz zsrre@$@!&uCB^!Xl%Q8oSp-UFAY81%z`(%4$O3}QY>aG-Y=2qU1ejSEnLzL_8!L<j z*5RkgdP^!LD={xUUoSa7ucRn5Ne>)g5QB@Dz>bG1NJ#>F2CNa`CJ0Lmq>#e~5@vRc Npac(c4G$v^697LK+!Fu* literal 0 HcmV?d00001 diff --git a/accounts/__pycache__/urls.cpython-313.pyc b/accounts/__pycache__/urls.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f4dc712c771852614779519229b64f286d80a267 GIT binary patch literal 560 zcmey&%ge>Uz`)=bb|u}Dk%8echy%l%P{!vn1_p+y48aV+jNS}hj75wJ48csn%-&31 z%tg#zEJZ8|AUPIqRxh?9HU)+lMkR(|))?kswqSNkW-yN<h9#I2&f|(<3*v*CjYKIi z1ak&+TQUaofK=);7jdNXYVy4VsnBG+#Zr)1lJSy}fq_Aj=@xf!W_n&}L3~+eYWXd$ zoc#36JTP06@fMd)etLdsNmyoTc@;ZEnf@&{2m@qHUSe))6&qNK{w-E8UB#XQ)}yb< zc#AVHwW1`xATd4l7D!QkX^EdE=PmA(ti-(Ze7(}5oZ=#81_p*(tRSn4i&z;L7>d|H z0+LWA$@zIDMVU!@iKQhOdJskIAbIx0Vz3i$ahDe56eO0Eq!#5BuVnZP^4=|1XRDad z;?$zz7~j<NM1|mz{G!wtm;Ca)oczR;;+XWJ{L+H>f};Ga)Z~)*((+W@+{Dbhn8f7d z{L;LV;uw&#^a?6(aoFVMr<CTT+7*d1Fff3^s@RQzf#Cx)BO~Ke2ATT|T6Y-?KC&^e za&|~g@LrH{kwyO|3rB~<1giz^7g=;bY{>~;*G1GWiKuN5zbImPfa4;I=LdEcex^q5 JB4Gvw1^{l^o<INq literal 0 HcmV?d00001 diff --git a/accounts/__pycache__/urls.cpython-39.pyc b/accounts/__pycache__/urls.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a26d0697866c0255bed01d4e1c00de3c3e9f0057 GIT binary patch literal 428 zcmYe~<>g{vU|?82?PPi|BLl-@5C<8vGcYhXFfcF_$1pH3q%fo~<}l<kMlmunq%fs0 z=P>0mM=|HJM6ob}<XCc8bJ?QU7#UI-Q&>}(Q`l12dzn)iQ#evtQaGV(u2i-x_7u(( z?q0?e9*|f%a}-AkZ!m)<-%F6anvAzt3KB~)UNSN;FlaK};x5ii&nqp6FUw3Vzr~f4 zpPrcqW@|Fu;_}H)&o3<r%S<h=VuvWxk79!`K*r=H=B8G$fwk!0Vg=Jx>^WdP`kIVU zoO!7gCGiD`>8ZCsit<ZK{4_alai?S@=B4NBl@{d`7cns~Fx+AVSzTPj!oa{##0nCS zgepnS&nqd)Owvm%Ey>V>C}IQ2vnLjVop_78v?!+_v7{umD6e=WLlHm71Q78{Og}k4 yB~?E$IXS;HucTNXWSL$;<t+}I-29Z%oK!oI#l<`f3=BMs0*pM&Jd8YyB7Xs3eRZq= literal 0 HcmV?d00001 diff --git a/accounts/__pycache__/views.cpython-313.pyc b/accounts/__pycache__/views.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..490bec89c11f8102d00fdb854915497507a1cd68 GIT binary patch literal 1531 zcmey&%ge>Uz`)=bb|u}Og@NHQhy%k+P{!vF1_p+y48aV+jNS}hj75wJAT|?(?Zs5Y z1m-h)GkdWVv3Ri-v4Z(5-fUj%MeGU;!K}e--W*<>MVtx@!R%5DMO?ugQVd1h>71He zFF{slGTve<O3h12Ez)EvVrF1qxW!SFnvz+Rnp~pEbc;17KRq+=7EfYnNk(d3NoI0l zNvbB}Eg?q)KQlkiEx#!DB_jg^gC^rGuHek{ywC!WP%=meWCsYdF)%QIjQ{)%?4MAE zAdn~;4ra89U|>iLWMGH}sRhf1G6b=J87PD))a*RQP{ts36e%#r6ihNOXh7*iH3o)I z#vo287m0$Y%wvk?h6zV7nL@)~fgzd~CK}8HvsHz`p9|qaxCxBW{4lkl48hF7ETN1B zjHXbZs4!@<`rTp)@DC2T#gdVqn_4B3n4FwnnpaY+U!0kqS6ZN#QIeZ;izO|;C|8r? z7F%v=Nk)E35y;6!AeY_Z$SjU8OU%hkxy4ePSe9DE%D})-1PU8)ysc!u#a@(JSejZ~ zQUr4HEtb;a)S_aL?FtGCx7?hqVnRUzF}|tki3-6b`9-NQF8SqoIr)hx#WCqc`K1N% z1x5K;smUerrRAx*xrv#1F)$a#lx3!t7wZ*N-r|P1H6A2TB+9_R0CHb(Is*ek1H%n= zzV^Dtx*1}Z+2!x>OU_WAuQOBUGQWBU%MEV+e%nsle)~@Q8^Yq#Ehkz|w(fAb!y`CB z{R)r59bxGiZkL6XFYqXTU}xZw{=&r|Ak|&d!E%RNaDw^;X~PX}J6tx{UFLSWz~b~7 z6vWt*)+fSA%O5#uMPN-@!AzD+bWK*wBqb}BU{<tb#pVZ2ADWD}SW*&85{q~k7#OOA zVNs_K&cfid1x^>597TMfgagVnV0}fPM0<-PJ+&krlw#15RgoYA0|P7-6^Vcf2rjUR zkQ5-rz`y_!EY84^0u&dhZ|B*_bCKT`BL&z_w4H2^KLsdV=2wO%0fP-@J4`m{UFLSY zz~WdW#=yYfr^$0mASEj?FFjwcI3vHPB)PPt7@QNpdE%BZR4zF`ucRn5Ne@(nLHq_P zif&0_k=6rcz2YKJ$lPLuutBLCoXm?rK3&NGwi*%)95%W6DWy57c0~#d3=E+1s2Iff nz|6?Vc$Y!>IfL$f2IIR77Ec*uKe2E!Ix~J2<79MV1e*W=bHX-| literal 0 HcmV?d00001 diff --git a/accounts/__pycache__/views.cpython-39.pyc b/accounts/__pycache__/views.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..da3d75a994d4308aaad2c1e9133b117843171491 GIT binary patch literal 966 zcmYe~<>g{vU|?w1IG1kE!octt#6iYP3=9ko3=9m#5ey6rDGVu$ISjdsQH+crHWP%M z%M`@~<}>Fo=dwhx<g!Mwg83{tY`N@F?2HU4tSM|c9J!oPoQw=9>?s^A3{hMuoGDx_ z3{l)E+`$Z*JTF0ZYBJtpD@x5vNiEW3Dgs%2i=!wtC9^0sxkQuc7Hdv^dS>1&p2X6U zjMTi6%;dz9R87WPLXHT2W`3Sqeo^jAMg|53O~zYX!I|lKp#>nJWRMWZ4iIK$U|?Wn zU|?_t`OA-ifuV*Wiy?(Eo2kg6gt3Mpi>aBhma&F$0rNtJBD)&K1uP30YMDw{YZz*n znwc0GO4w4Eni+!`^4Llkn;B{uOW11|QkYX%Y8W#ao0)?dG+F&_u>|-BhumVx$j?o! z5=l%>&M(a?Db_E}OwTJV(90;v&AG*rmS2>s$#IJ<H?<@qKc$F+fq|ijlYxQZ7Dr}r zd|6^nX38y=;>5DlA{LMg$j#s|S;>5hy(qP?G_|;-h#RDwrL;J;XeC3D5Ca3lFLC|k z{FGFExQ%6*spZ9b1(mnBA$G@u1VFYF3xGm`k&BUwk%N%~L^H857Kt!0FyIcVAmpI3 z0R<H(uu_<Mnc%_Ygf+OBF@lRFg%uuLY<^&WYck$qNl7e8ECMCSDq*-6z|js4Gq8U( zIf{5d0m23%Kt3tr1%(1fdTL2LC?wE=tB4<@4iq-v04fp&Ddqy32@VU8kKtj#ha48- z3=9l@nmkbgDOrhm>G^ua8Tmye$)zR5;AkiUMaV5-s9bV>UP)1Ak{&2+LL2}}U$-Q& zNb7;(y|@VE{9CLLHaO}*4k-fJ32`Tyi#cp^^HWN5Qtd$LxEK@wJWK+N0*pLNJWL$i E0KL-MWdHyG literal 0 HcmV?d00001 diff --git a/accounts/admin.py b/accounts/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/accounts/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/accounts/apps.py b/accounts/apps.py new file mode 100644 index 0000000..3e3c765 --- /dev/null +++ b/accounts/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class AccountsConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'accounts' diff --git a/accounts/decorators.py b/accounts/decorators.py new file mode 100644 index 0000000..1b30439 --- /dev/null +++ b/accounts/decorators.py @@ -0,0 +1,11 @@ +from django.core.exceptions import PermissionDenied + +def role_required(allowed_roles): + """ Restrict access to views based on user roles. """ + def decorator(view_func): + def wrapper(request, *args, **kwargs): + if not request.user.is_authenticated or request.user.role not in allowed_roles: + raise PermissionDenied # 403 Forbidden + return view_func(request, *args, **kwargs) + return wrapper + return decorator diff --git a/accounts/forms.py b/accounts/forms.py new file mode 100644 index 0000000..637109d --- /dev/null +++ b/accounts/forms.py @@ -0,0 +1,18 @@ +# accounts/forms.py +from django import forms +from django.contrib.auth.forms import UserCreationForm +from django.contrib.auth.models import User +from django.contrib.auth import get_user_model + +User = get_user_model() + +class SignUpForm(UserCreationForm): + class Meta: + model = User + fields = ["username", "email", "password1", "password2"] + + + +# forms.py + + diff --git a/accounts/migrations/0001_initial.py b/accounts/migrations/0001_initial.py new file mode 100644 index 0000000..34b418a --- /dev/null +++ b/accounts/migrations/0001_initial.py @@ -0,0 +1,45 @@ +# Generated by Django 4.2.19 on 2025-03-06 22:56 + +import django.contrib.auth.models +import django.contrib.auth.validators +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('auth', '0012_alter_user_first_name_max_length'), + ] + + operations = [ + migrations.CreateModel( + name='User', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('password', models.CharField(max_length=128, verbose_name='password')), + ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), + ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), + ('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')), + ('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')), + ('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')), + ('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')), + ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')), + ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')), + ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')), + ('role', models.CharField(choices=[('student', 'Student'), ('community_leader', 'Community Leader'), ('admin', 'Admin')], default='student', max_length=20)), + ('groups', models.ManyToManyField(blank=True, related_name='custom_user_groups', to='auth.group')), + ('user_permissions', models.ManyToManyField(blank=True, related_name='custom_user_permissions', to='auth.permission')), + ], + options={ + 'verbose_name': 'user', + 'verbose_name_plural': 'users', + 'abstract': False, + }, + managers=[ + ('objects', django.contrib.auth.models.UserManager()), + ], + ), + ] diff --git a/accounts/migrations/__init__.py b/accounts/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/accounts/migrations/__pycache__/0001_initial.cpython-39.pyc b/accounts/migrations/__pycache__/0001_initial.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..41c6efb56fee2663616aff7ded2853aac90f243d GIT binary patch literal 2280 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 Spy({-0QrlNgHeEygBbv!#MX-d literal 0 HcmV?d00001 diff --git a/accounts/migrations/__pycache__/__init__.cpython-39.pyc b/accounts/migrations/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ef155c26c26564f4d41fbb44fd05016f668ac3cf GIT binary patch literal 128 zcmYe~<>g{vU|^{4Kba1qAA<;F%*epN;K0DZP|U)>z>vZa%%I8Wx00a<B#a<_sp==^ zr=;p9CMV~Y=9Lud=VqoCC6;97=N0S6$7kkcmc+;F6;$5hu*uC&Da}c>18M&ZvIYQh Cc^kk0 literal 0 HcmV?d00001 diff --git a/accounts/models.py b/accounts/models.py new file mode 100644 index 0000000..78c42db --- /dev/null +++ b/accounts/models.py @@ -0,0 +1,31 @@ +from django.contrib.auth.models import AbstractUser +from django.db import models + +class User(AbstractUser): + STUDENT = 'student' + COMMUNITY_LEADER = 'community_leader' + ADMIN = 'admin' + + ROLE_CHOICES = [ + (STUDENT, 'Student'), + (COMMUNITY_LEADER, 'Community Leader'), + (ADMIN, 'Admin'), + ] + + role = models.CharField(max_length=20, choices=ROLE_CHOICES, default=STUDENT) + + # Fix for SystemCheckError: Add `related_name` to prevent clashes with auth.User + groups = models.ManyToManyField( + "auth.Group", + related_name="custom_user_groups", + blank=True + ) + user_permissions = models.ManyToManyField( + "auth.Permission", + related_name="custom_user_permissions", + blank=True + ) + + + +# Create your models here. diff --git a/accounts/templates/accounts/login.html b/accounts/templates/accounts/login.html new file mode 100644 index 0000000..96f3d18 --- /dev/null +++ b/accounts/templates/accounts/login.html @@ -0,0 +1,16 @@ +<!-- templates/accounts/signup.html --> +<!DOCTYPE html> +<html> +<head> + <title>Login</title> +</head> +<body> + <h2>Login</h2> + <form method="post"> + {% csrf_token %} + {{ form.as_p }} + <button type="submit">Login</button> + </form> + <p>Don't have an account? <a href="{% url 'signup' %}">Register here</a>.</p> +</body> +</html> diff --git a/accounts/templates/accounts/signup.html b/accounts/templates/accounts/signup.html new file mode 100644 index 0000000..d0f7a9c --- /dev/null +++ b/accounts/templates/accounts/signup.html @@ -0,0 +1,16 @@ +<!-- templates/accounts/login.html --> +<!DOCTYPE html> +<html> +<head> + <title>Sign Up</title> +</head> +<body> + <h2>Sign Up</h2> + <form method="post"> + {% csrf_token %} + {{ form.as_p }} + <button type="submit">Sign Up</button> + </form> + <p>Already have an account?<a href="{% url 'login' %}">Login here</a>.</p> +</body> +</html> diff --git a/accounts/tests.py b/accounts/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/accounts/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/accounts/urls.py b/accounts/urls.py new file mode 100644 index 0000000..301858a --- /dev/null +++ b/accounts/urls.py @@ -0,0 +1,10 @@ +# accounts/urls.py +from django.urls import path +from .views import signup_view, login_view +from django.contrib.auth.views import LogoutView + +urlpatterns = [ + path("signup/", signup_view, name="signup"), + path("login/", login_view, name="login"), + path("logout/", LogoutView.as_view(next_page="login"), name="logout"), +] diff --git a/accounts/views.py b/accounts/views.py new file mode 100644 index 0000000..3680ccd --- /dev/null +++ b/accounts/views.py @@ -0,0 +1,32 @@ +from django.shortcuts import render +# accounts/views.py +from django.shortcuts import render, redirect +from django.contrib.auth import login, authenticate +from django.contrib.auth.forms import AuthenticationForm + +from .forms import SignUpForm + +def signup_view(request): + if request.method == "POST": + form = SignUpForm(request.POST) + if form.is_valid(): + user = form.save() + login(request, user) # Automatically log in the user after signup + return redirect("home") # Redirect to homepage after signup + else: + form = SignUpForm() + return render(request, "accounts/signup.html", {"form": form}) + +def login_view(request): + if request.method == "POST": + form = AuthenticationForm(request, data=request.POST) + if form.is_valid(): + user = form.get_user() + login(request, user) + return redirect("home") # Redirect to homepage after login + else: + form = AuthenticationForm() + return render(request, "accounts/login.html", {"form": form}) + + +# Create your views here. diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..294c75f --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,27 @@ + +services: + web: + build: . + command: python manage.py runserver 0.0.0.0:8000 + volumes: + - .:/code + ports: + - "8000:8000" + depends_on: + - db + + db: + image: mysql:8.0 + restart: always + environment: + MYSQL_DATABASE: unihub_db + MYSQL_USER: unihub_user + MYSQL_PASSWORD: Thescotts111 + MYSQL_ROOT_PASSWORD: Constantine.25 + ports: + - "3307:3306" + volumes: + - db_data:/var/lib/mysql + +volumes: + db_data: diff --git a/events/__init__.py b/events/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/events/__pycache__/__init__.cpython-313.pyc b/events/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..81fd327f1a1854dd82d2e08cec1ea1d8efa9c99b GIT binary patch literal 168 zcmey&%ge>Uz`)=bb|oD|KL!yn%m`(CW?^7pn97jOpvmaBlA(x+fq~&ONa~imvsFxJ zacWU<jBjdsqC#*<eo<<SOMZD?PJUuaaZGwqerZ8`K~a8IYH~?@X?dz{ZenI$Olnzb xUP*CGe0*kJW=VX!UP0w84x8Nkl+v73yCPNw1_qG5#URE<W=2NFB4!2#1^^l*E0O>J literal 0 HcmV?d00001 diff --git a/events/__pycache__/__init__.cpython-39.pyc b/events/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..07c93c299966525bb0dc622df306925289af718a GIT binary patch literal 115 zcmYe~<>g{vU|?XeJCzQiAA<;F%*epN;K0DZP|U)>z>vZa%%I8Wx00a<B#a<_N$4l% pr=;qqmZj#E6zj*wXXa&=#K-FuRNmsS$<0qG%}KQb>G%vX833zZ6|n#S literal 0 HcmV?d00001 diff --git a/events/__pycache__/admin.cpython-313.pyc b/events/__pycache__/admin.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..85bc0c386dbe0456b22170ca5b7fa2e5481a1ed3 GIT binary patch literal 212 zcmey&%ge>Uz`)=bb|u}Ofq~&Mhy%k+P{wBg1_p+y48aV+jNS}hj75wJ4Czdo%r8OG znvAzt6H{_C^ZYcKZt<mLCFZ5)>m}#sl@w(r6)`g~Fsx+w3{rQ?#n~z*v^ce>IL0?M zJy9XJB)=#%#wEWzFDE}Sr8p+ND8IBIzMv>SD>b<!zO+15H#adeFDA7tHLs*N25f^~ pLFFwDo80`A(wtPgA`S)y21W)3hGG!o12ZEd<2?q2A~psF1^@sSI4=MI literal 0 HcmV?d00001 diff --git a/events/__pycache__/admin.cpython-39.pyc b/events/__pycache__/admin.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7c49eeed3100ad2cdafa4c41ca39dbccdb6af90a GIT binary patch literal 156 zcmYe~<>g{vU|?XeJC$zFz`*br#6iYP3=9ko3=9m#0t^fcDGVu$ISjdsQH+cXDNMl( zn#?ajYBd>eu_mVEX6E^6GDY#FWF_XM=j$cs=am#?CKZ7USjkYt%)kI4eu?TQ=clCV ir<SGWl@#lP_30H<-r}&y%}*)KNws5SU|{$RG8O<0(;)i* literal 0 HcmV?d00001 diff --git a/events/__pycache__/apps.cpython-313.pyc b/events/__pycache__/apps.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2f869b4099b269e211c70696a8cff4d216864919 GIT binary patch literal 532 zcmey&%ge>Uz`)=bb|rlR0|Ucj5C?`?p^VRJ3=9lY8G;#t8NC_27>gJc7$g{!7=oFk z7=oE&7)_ZW>WY}sSu|N+f;gItw>TXO3Y_!v(lXPNK_W2B2xWYh0h<}aP{bI_P{b6> zSi~I6RKya@T*Mm8QpA?ds>ybX$F(dqucR1a%1ago28Jrxl&r+O^nAUPB)#1Hl+>JJ zJ*Uic$I_B~x6IU>lv`}6U>z$N{508bam2^xCFZ8a$KT?LkI&6dDa`?~dE(;>OA~XT zGW_xJX_-aEB{`XSsd@SF@wbFhQqvMkb4ub9OH1<O)4-;(fE3>njgK!bNi4}sj!!Hp zDauSLElDkok1yh2U|{$R^3*M7XRDad;?$zz7~j<NM1|mz{G!wtm;Ca)oczR;;+XWJ z{L+H>f};Ga)Z~)*((+W@+{Dbh7>J8w5(^57^$IGBKw%ChK;A9pWnf@vW4Iw{ae+nb z2DfmtOOXHr0|QvzPm}o;H#9Urnu|cO0G0te38GMtfq~%`hYiH@c16Mr3=E(MC>CL0 cVEDky$jEq?LGcS46Qjrk%dZSfj3QuN0Cc~OG5`Po literal 0 HcmV?d00001 diff --git a/events/__pycache__/apps.cpython-39.pyc b/events/__pycache__/apps.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..37181a8abb832d49b5a6c91ac678d152b2f0b3f3 GIT binary patch literal 392 zcmYe~<>g{vU|?XeJC#0xfq~&Mh=Yt-7#J8F7#J9e6&M&8QW#Pga~N_NqZk<(+!<1s zQkYv9QkYX2o0+4SQdoi+G+AGQ^lCER;&d!1aL&(5%S=xOi6CP}n290`3=F9ZQH&`J zQA{a}QOqe!Q7kFU!3>%#w|HF3Qu9iRAtqGGrer1NrRVFVB<bbmr=;c->p5knJC>H@ zyJe>4q}*al1uOQ`WWB`^AD@?)n;IW~iz_}pH$SB`2gK%yk1s4u%z?@XrKF}Mmgbbi zCzh7v$ESgfU;)XkWGDiK1(^6HqMw|flBy3eT0gO%pjfY<vWOWJRG`oR1q%lw3nN&> qPm}o;H`I+Fl|@Vp3=Ciyuvth1Hv<F1Ee;!q%j`fQQ4CVc!wdkI{agzG literal 0 HcmV?d00001 diff --git a/events/__pycache__/forms.cpython-313.pyc b/events/__pycache__/forms.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..edcd646bdc553765cd6c930a26c2cc72dc1d859b GIT binary patch literal 788 zcmey&%ge>Uz`)=bb|w7~0|Ucj5C?`?p^VRN3=9lY8G;#t8NC_27>gJc7=oFCnZ233 zn2VSd7$g{!7=l@(7=l@27=t*VdXOknW(cQ<HJwe9{UwN_$#{!3Ex#zY_$4C)0|SWX zT9%quk_?iAVHPOkvj*7q7=|LoV1^>5V8$Y5u#HSo48hE%Ob}H?EWs>Atm&+pY_~YU zM!Dq|<-P<Nfnp|9HN$5G3^QX`idgj-f|&vti`ashi`dgyG+A%)!Ohb1O)W`$2?`NS z)?2J4nI$=?x42VMi<65o3raHc^KP-EB$lM!VkybYO})jDlb@Uj5?#sQr^#`PBR)Pa zF*h|n{uWn!d~SY9X%2|Z6CYn#nwSHX;g63`%PcA`$;r%1&C8FEF9KP0i#0btB{k<3 zTUusnPD=4D(fIh{lEjkC<oLvrlA_F{(vsBT`1m401_p-Dpm4b5;%pTYTAW%`9OIjs zo~RI9l3$b><C0&Vmy@5EQXG?BlwVp9Ur>~vm6}`<Us|53o12)K7n2GK`{EdIgy<Di z-eLjywFs0hK#nNpVPIfrW4Iw8+QE8D(6yVbNRokpp-37;fNb{DWGfN^afCsH2#62` z5nu%pAQng!M3WSV%MK$z(NoL^HvKyj6RR8J7X}asQ3_J!r^$AUEhQ^4FFn5ql!$Jz zfy1L15;&Z`puhn|bP-4~I2a&$LDt;juz>`%U6DKk0|O|X70WU(FnnNUWMsU{AaR#L X@(T+yqZ{J{*6I8c`M)xN*kJ7d>_N8B literal 0 HcmV?d00001 diff --git a/events/__pycache__/forms.cpython-39.pyc b/events/__pycache__/forms.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9aabdf07b080c83280a5d08b175275127a7f4139 GIT binary patch literal 577 zcmYe~<>g{vU|<N?b0PgC0|Ucj5C<8vFfcGUFfcF_>oG7eq%fo~<}l<kMlmunq%fs0 z=P>0mM=>)pxHF`%q_DOyq_CzkX0bFgN3o``1v6-}zXX}2$#{!3Ex#zY_$4C)0|SWX zT9%quk_?hV#>_CAq!<_&QW>HcQy8L{+!<0BQ<z#9Qka^VqL@>dgBdhgZgGMQaLX^s z#V~{kW{3omA*sw!Ea?m>jEfkfSW}pS88n%z_~1t9`KFd6YO>y9Ey*m&Nxj9Ll3JWx zlvz-cnV)xyB_**W^%hG>W^U>&j-34DM3AVTCfhBJ`1riU+|>B^TU_z+x%nxjIUqJq ze0*VPVh%*62o!R+Sab7JQgd#xrDdk(q!h1YC=y^`fDpe#^^@~cQuR|ofl;gv4k5jQ z%3CZT_ppLO9Ap3oBMW1Z5Ca2)pC(HYH%KoJh~NbgAYp`g5SAcF0;C(Hxfm209E?RE zKFHN<DOrhm>G?$<;ahBAmlZ>t$>|GnCMZO~iXmpfomvDk^%jQ>#G`hgXe<Vq&%?;W F1OO-#d~g5& literal 0 HcmV?d00001 diff --git a/events/__pycache__/models.cpython-313.pyc b/events/__pycache__/models.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1bf1f0ac9993b8700854969bde01d7e201101eed GIT binary patch literal 1314 zcmey&%ge>Uz`)=bb|qbfiGkrUhy%l{P{wCB1_p+y48aV+jNS}hj75wJAU2aXlNWOl zvjT$zgAzk9vlK%xOAKQW2UHIdWy%cU6tSkWYO=iqaWolkvE}Bcq~;WBGT!1SPAw_P z%u6p$21&s%8<g=`hY@6X3_}rPFhdbjFk=yO3`-E$(NGmoN{JzuDVW)kv4|~(C5R6y zh(swdm_m6)95F0GLQoD8g`|Qjh9yW0NeaqDQo%#O6}&MlK{8NnNR$#o41bUUk^qz$ z!xE$fWg=0*EWxan%tb;mEJ12W!ce9XLoiz~yCq|hNHB*KLy>4OXOUPsmnQcuR@buB zypoqJ3=9k}|1&T!Xfod7%1x|@&q>WoFUhzikYALZn3q|Vni8K1Qdq3Xbc-`TFFqwT zC$%K?7Ee)XPGU)FN_<{oZfb}o<1L=V(vtl6y!`U`#FUg|MyTx|3d9D*?q?}*3JGNh z0*Rtw6$VX4KTXD4tR<NxIjNeAw^)i(bJB`IdKGTDI$Onr7N-^!$M~kECn^M&<QJvJ zxa61T<>V)(6vw0&<(C%37Zl}Zr6!lemzJmM<|bz5#Xy`L14%-91(mnh<Kv4<isIvM z@q)ds2j%iJFfbJJFfcGQFx=o5?yu^sy1*g%8RWi|41Sv8w>aX#o{W#b#T6f)o1ape zlNuj?izhz5urx6T<o)>gTm13yX_-aEB{`XSsd@SF@kJmH-{N%6NGx*8OwCCt0$Fm4 zGbFX51kAt1oswFdT$EW*l9``(i_;~sBo!jgl9E`GdW$n8GZ!XMl9`)&iz6pLIT5Uu z%PqesH8VZWJGHV16nD4y9YaGr;zNU7gW`StU0i)`u{%2kJ3G3#-r|HsVbLvKkPQe! zxsr=g!LgTEQUprlw?si<kyw(M9G_THQk0ogT9R5EA73QOz`#%>0wM%K1Sq=|fe4Vr z#jOks3~dZIc!aL=$Xw!)S;2gfN2kH{hLFT{A*D+~N|%LH8oY0C3ts1zzQiqknOnBO z1&zlqdYxbX62JTk<BR<I4IVcH#I6e{UJ_8e!69&+L*XKa!V0(bek=Vhct(F@W)fs; z@ch8WAS7{JQ1z0a>IRdGf))*4Us)Jgr64W@xyw(J?G|TBR$^XyzFtZaBoerx{N((+ zG)RcC`hrRout(5*c#FdZ62W#wIt&a9pww3^&A`C$ftit!@h*eRT?U0OEIf=-9d7+T NojzX~co-p;0|1U$GVA~V literal 0 HcmV?d00001 diff --git a/events/__pycache__/models.cpython-39.pyc b/events/__pycache__/models.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dd7106e098e800bd3a6e197810a8db1f7ca78aba GIT binary patch literal 828 zcmYe~<>g{vU|>+&eIZ?iiGkrUh=Yt-7#J8F7#J9e^%xi!QW#Pga~N_NqZk=MY^EHh zT;?cdMh16=6y_9`7KRj-RK_fpX67i?6xLt{O}3XHlQbD`vE}Bcq~;WBGT!1SPAw_P z%u6p$21y}fR+vR83=9mZ3{i|J3{gy}%vmfcj44dLj8Uwq%nR5SGDNYbGB4m*$PmSu z%DjMUAwv{5k{X^=<}BV+zAXM!<}3k_lX{t>1XG!_gi=^j*m@bGgj3j4I9eE@L{d0| z88o?WvAUL}=9Rqs&%nT-$#{z^H?bl<Cp9m<BqK^7zbHL1FS9B&B|a6TrdX5d7H585 zd`fCgYDwxXo}$#8#FEsM_`Jm2)DTU^TRe%SCHe7r`Q`D6DJjW}NFD>RLD(4-h-?fD z3^fc{48aVVjDDJow^&OuOL9^*8E>%^r{<)sWGLccU|{$qrk|XjlBy4}SRWF0dIgoY z*yH1iON!#-`9Vf8f$U(c;stv_4=UrQDSC?|9_*_4_*-1@@wxdar8%kb@wa&5;|og@ zb3pEmk1qmgzQyUBkyzxGnVOSQ1WE(9I73n^O2GVE+$pKW$wiq3C7Jnow>VuAOHv`? zEGda4skb;oGIL=9C7HRYw>Wb0lM}&ex!m%LQZv)@yi+TSm>C!tZt**YhIqt>2D=8u z`}(`M`rKl7b_{lQba9R1gavWYEnbifa6_ZGl8aKop_^Dz#K*t@2^DbAKnPxt7${+a zaIpvj0|N&m4<iQ{@-VV6a{Xsx=3y!V$@*!s-QrBiO3X{o*Gox)_?sKbPtMOvgE*4a i7nDB18Xz`+q5;AJ*>#J<1`>{TpolC6najh-!vp|*pwpND literal 0 HcmV?d00001 diff --git a/events/__pycache__/urls.cpython-313.pyc b/events/__pycache__/urls.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6e92f1c16f9a755e6408ae0499c87a268fe41634 GIT binary patch literal 458 zcmey&%ge>Uz`)=bb|u}9k%8echy%kMP{!vV1_p+y48aV+jNS}hj75wJ48csn%-&31 z%tg#zEJZ9{tVOH}3^9yK48bfh%)zX|Y?jPm9(xQ+FbAB+8N(XP1>)&57qO*tYx2AV zS)j>yi=`m3B;zF`0|SF5^DVB_vedki_?*n*l3P3wc1mhVVrI@Qp5&s`#FEr_u;49* zB36(F##=0TiMgp&{5F|+C01am_{<bL{USC728Jqjh!*`Kb_NCpKTY;q+$mX!dFlCj zrA0Z#Ma&Eg47XUzGE>Wo!G?kLfR*0jE-lI_NGvHyEy^oi$?zHE&|A*VRxzQ)sYS&x zzNzVn3c)4$MX50^`Q>>z`H3mTG3iD5r3LW?Mfq8&$tCfn<*B;4iJ5sZU?&yFfGpH2 zsJz8tlbfGXnv-f*B*4JH0P=IO4Fdzi2WCb_#=8tM_ZciNGFX1(U|{9!5bB7Uk#mtn r`z8y=1x~3MJ}c@jve?~Z;pmW@;Ip9aB8%Avb{2l7M(!d$1_lNIIAVQt literal 0 HcmV?d00001 diff --git a/events/__pycache__/urls.cpython-39.pyc b/events/__pycache__/urls.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ee5c8912770e457abb17b6d4f2f1e379b14f02e8 GIT binary patch literal 354 zcmYe~<>g{vU|{e$bRj*Gk%8ech=YvT85kHG7#J9eeHa)RQW#Pga~N_NqZk<(QkYVh zbC`0OqnLA9qF8cSqgWXkQW;ZNQkhd&Q`mZ$QyEj(Q(00tplr@m))X!fJDoX-ErmOn zL6het$R16`TPy{MB^fUn85kHenQw8WmZj#E#OGudm)zokuv1b?5;Jpd@gx_eCYGee zg9UFf6tRFbFy3OxOUzBJ;<w4nE3pDg#b>72=@+pwFfdfHL$v4@u`w_(_-V4=;!ep* z%uCPLD=o??E@EO}V7SFvmYG^!3^oj`2dwlKcWF^hL1IZsYEfSCN`@jH1_lW6OGH08 rKP6QkY*Dd3$QZqX%3B;Zx%nxjIjMFaPZWa!l!sA-g@=)ck>@V}XBJpK literal 0 HcmV?d00001 diff --git a/events/__pycache__/views.cpython-313.pyc b/events/__pycache__/views.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0637b9595f1cf1bfd3006bdac8d8f2c183d68728 GIT binary patch literal 1821 zcmey&%ge>Uz`)=bb|rl(3j@Pr5C?{tpp4HE3=9lY8G;#t8NC_27>gLan2MOZn2VSd zKw?bZEMBZdtO^Xl%)u<)Y+md|>|i#lH-{Hz5vKw}Fq;%Z5mzv~6hjer3~Mll6oV<$ z;3A%MPED?tAf6`kEw-Z6yp+_UTY~ASCGq)5S*gh-@%csZCI%+AIEqqJGK*4^OEej8 z@#W;FXXeEhr52WE7Nw@VWMp7q&}6*D>ROhX2a@LmGu-lva+5()Aj3hJje&uInSp`f za~0S#(I7D}4uW|T%!3d?tPmQRggH8h9a$8@4rVlk+Lgx`%?S}>U<hRhW(sBwWi((k z1=-BNz@WmQ$>Mj5B_**WwMr}%<ltg`FcqJZSzMx*QIeZ;iw!JLtjSu$!N9<9iyaaY z#kZIfb8>ER<QJu+7R4u37J*FEWV*!;3WwC<k|G`k28LpgR}>U(xj0+Jgche37039d zrY9-{m*f|v#<=8{=jG%lrWD7d7v+~0#1|ChgM+xVJXJS0F*7d)VsA`YW@>q{UP0w8 zF0cUDWko^^3=AND7n?9JFf=gS;T7tS?To$7D|eAs?lP~!bzaSjyqYW2F7p~TxZU9v zoS=R|+IU080k#XK?w7eeF0gof1_eqo$bBFN2*V@91`;9A0Ayf@hN}u?3}&=s%43R# zM+Y=Wnb3k%lkpZ)W=fR=*u}6QO-U_D%*=rVDl1q<levh6fq?-Wu#f;`E)oC*G6z^X zJ~O3A3>1u@uvJh{C=vw8@j&DtrWHvrFff3FS{V`$JhF3AS8!b9F>G*!`rC8|`vK7l z=1_kZ2{SM-U{8oyjG$Z<$`Aw!4K$1`Q3f+wl`}9Tax*X>!Xuaomhe;<LK%WUVTxu_ zFtb$z14CjO0|Rox3<BqRRHZPJ@)$!IgLqNpKs;Cm&;W557#I?*85lwtgZQCbBr2FC znAMUoj|scqLYZ<vDI2UllnI-Dm`w^eeCp4I@C!_B9%D2ps3E2@1hWORqh&k}zgq&y z`MJ5Jd6^}Z@j0o9DXB%^bbX5@z&|*|O_T8!8%RF01TAZ(<rn2bQV|P?smXPVrL;J; z=oU*+eokr;C~4ke%S|oG$WJK(W&I*)P^#g`ERHWr%*jl-#ZsJDmU@dbzbHL1FS9DO z2sz;u$%2w2mNb`Kl$uzQ8V^o-MJfyo44|Y~JPn-Y9<cMZ*EH5#XP3ChE^$Fd?=rjI z9e(i{JeT=ZFL0=WWa}F1W{6#8m%qa=F++U5%uJcf{AwL6H@NxxZ98rI?K|ynh)7KL zoanhAbb{vv5$z7w8*-}ib7tmrxc2zp;1TTi>h$XIxg#t+!{@TF<^>+j51b4<(qDKO z1SGqwJ6N8;@^{*flnrs0xm_->xPX(npC<1uft0Moy!3p%;*9*FlH}5oVz751*$y03 za!>`y`FSNpnMrzyr6n19DXGc%MTsT(Ma4y+Bz%i4H$Npcrx=`3Z?S?xy%-X<pmGSD z2f=}|k^yWlB%gBF<mRW8=A_ycX)!P`fJ&2MGX@5R56p~=jQ1HFE;2aWWw5-<AbFQT g<`WweqbK7hE)e;Fi-AetBNHE^E8}NoI1_9x0M=Q6iU0rr literal 0 HcmV?d00001 diff --git a/events/__pycache__/views.cpython-39.pyc b/events/__pycache__/views.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a3d48a69ccce03e41d2399db0a1989976706d79e GIT binary patch literal 1154 zcmYe~<>g{vU|{Ine<6J;3j@Pr5C<7EGcYhXFfcF_M=&rjq%fo~<}l<kMlt3xMKR?v zM=>*k#F%nea#^ET85vTTQ&@7?a@nKU!EDwXj$F<tPDX|lwiNajhA6HSjug%ohA8e- z))cN3?iPk-#weZ?o?r$|-j^UdHJNX*6{Y5-q!!&0OiwL|&rixqO)iPgFN!xYFuBE1 zl$w%Rl$u<k$#{z|CqF$iFTN<Xur#wMHRUBE0|SF5<1JR#veZ0~JSUjpmS2>c43YvF z4#G?f3=FIc3=Ga74=FG(FqAN4F)m<Q$gqGpg>fNcEn^8w4MPf33Udu(CSx;mFoPzG z-z}Du#FEr1u~d-J#rj|>J}0xdL@%QxH|G``SfE&wwTPX8f#DWA#LdOGm=kkyZgJ!n zrKA?cCsh`KY}RDD#SU_DYH>*sD9~3j6!9}KF#HnLPtH$Cg_vBdUzV9#UaVJ8d5a5d zGT17R(ZwtvA213q76~#iFeHNv1POpJD30LXk^y_Ggt3M(g|U~ZmZ^jZ>Ln()moyn~ zF=eJyNq{YYc_}5eBr!7w;we_Jj3#pt$Yij`ARb^Y;$vW7h~fZC$7iM#2{SN2JOTDe zkpL(Ncp$P6^LRiZ4RJXSW045R<;W2NG9T{p90mr48ip)}EXEYZY~~`75~dWUX2xKU z7;_49Hd9d;D0;G3n;B~vYZw=>Eo3N)sbS1wPhm-6?PaWG0_m+`isz_dTEM=Lfsp~G zKaZ`1rJ13Yv4pb*oD$)Y%i(uRAUQubw=^%aq%uAyH8CZ%2pqb%SOWZmL)<hOZ?S>o zGfU8-KP|r~7ZOq|Af_hQEtb;a)S_D~Mfo|YMIi6qV#`e}$;eMB;sAw^7${sgGK=HO z5_2+BZm|?6mZjd}%r8n$%*(7wEkX|5A_<TNtl^qml$uzQ8V?R$P#P!(8Oy-L!^pwJ z#mL3T!N|kN!N|eL#l*%`B+tOW;HSxZOCTjHF)uw|uQ(&Ws3f_xq!?@$BwoSpl!Gcr z&d)0;%1qKrEG@~<OG!=6FG?)QFDfnq#m+6Z-29Z(oMLcFxWx+caxuhXAZLJM6>K3S n5rEP(gau9x95%W6DWy57cA$7K2BjYnMjjAk=3wPuWnu&XE>scH literal 0 HcmV?d00001 diff --git a/events/admin.py b/events/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/events/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/events/apps.py b/events/apps.py new file mode 100644 index 0000000..20f48f2 --- /dev/null +++ b/events/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class EventsConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'events' diff --git a/events/forms.py b/events/forms.py new file mode 100644 index 0000000..d8efb62 --- /dev/null +++ b/events/forms.py @@ -0,0 +1,7 @@ +from django import forms +from .models import Event + +class EventForm(forms.ModelForm): + class Meta: + model = Event + fields = ["title", "description", "date", "time", "location"] diff --git a/events/migrations/0001_initial.py b/events/migrations/0001_initial.py new file mode 100644 index 0000000..d3ece7d --- /dev/null +++ b/events/migrations/0001_initial.py @@ -0,0 +1,30 @@ +# Generated by Django 4.2.20 on 2025-03-11 22:38 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Event', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=255)), + ('description', models.TextField()), + ('date', models.DateField()), + ('time', models.TimeField()), + ('location', models.CharField(max_length=255)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('organizer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='organized_events', to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/events/migrations/__init__.py b/events/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/events/migrations/__pycache__/0001_initial.cpython-39.pyc b/events/migrations/__pycache__/0001_initial.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9ff70ed178a0d1e18a7bf8a70edba9b2845be094 GIT binary patch literal 1075 zcmYe~<>g{vU|{gveIZ?qg@NHQh=Yt-7#J8F7#J9etr!>>QW#Pga~N_NqZk=MY^EHh zT;?d|T$U&nFrPVxHHyuhA%!J{wS^&tHI+Gwy_q?RJ%u@#L6hwz$W%?nTO7ryB_)}8 z>BX8%x43dM(~A;IGV}9_Z?Wa(r=;c-`z3?aA!B}+3zji3Fr+d>F{Us?F{Lm@F{iRD zU`=JqVqeIZ&KSj!%96#I!j!_C%9X{P!kEGcazzSTFH0Iz3VSM77EcOC3TH248dC~a zD%S$ug$!v-Dcq@C3;4h+o>Z;{{9qO@idw!@t}KBR#uR?APJvXeEWuQvEa5D!ERihH z6hV;fDMG!>X-w%HDZ;%>>5NfgDI&oPnxeNjePLb;xy9;QmYP>`izze3?G}@#izdr0 zp2X6U{P^Ue)Wnk1lv~^dMVYyYMV0Z{sg<`li&Kj-6LT`FQg88;r4}XS7pKPOCFZ8y zVlBxm$w__rpMilvlkpZ;Zem4zPHJ9yNyaVil+@znqRawNK;B|WNi0dd#Zr=)n|g~Q zCqEe+ytlZZcEu-_Xfi^r&&w~5PfSU<#hG7}o|u<em0EO50LDy-PX)QTSd;k{XMSFM zN@`AON$M@0qSPFaiy;nTD#_Pmy2S!^99vpuYEDYApQiXNj(D(ieEco0`1suXl+v8k z`1o5q@$rSFi8&y}@$t9VGxIV_G81!(m>C!tZiy6^Cl(YWCgr5Yr=%97=B1?OC07<P zfu#5yLqj~`LxWv|;(h&HTzziwz*S_X7T@A_1_z-pDCrb|lIkrUr_6N6(vo~Pkb7=% zI%gynL75?`6(vxnOJYeXlo^tl3uW?xL=jvrxBQ~i%=A3()XH0IDOrhm>G`*qQj%_Q zfWsm)KkpX1vtzKcql@b;uKa>jXfj^OP-Mu!03m*<>nG=@r0PRLQXi4l^$iRR4CA3e zpjS{?#LB?HzyZo+3Lpj(3p3Y$7FHHUCMFR^K1MDu<YVMxl=;E*kL5pDwI;_cZiu7w zlJoP@Ac4gR6-h|~hbtsNB;kU3kQ}B5^FWaf$fY2=5pIUCj6gxpVFQUgJ5U@IvoSC* L@GuH6axen`(oR3T literal 0 HcmV?d00001 diff --git a/events/migrations/__pycache__/__init__.cpython-39.pyc b/events/migrations/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..37c89e2a65040891a4a594bcbedc537cf624664d GIT binary patch literal 126 zcmYe~<>g{vU|?XeJCzQiAA<;F%*epN;K0DZP|U)>z>vZa%%I8Wx00a<B#a<_DeEWa zr=;qqmZj#E6zk_^rWYlaWaj4;>&M4u=4F<|$LkeT-r}&y%}*)KNwouM{tU7N0N70$ AC;$Ke literal 0 HcmV?d00001 diff --git a/events/models.py b/events/models.py new file mode 100644 index 0000000..5913ad1 --- /dev/null +++ b/events/models.py @@ -0,0 +1,18 @@ +from django.db import models +from django.conf import settings + +class Event(models.Model): + title = models.CharField(max_length=255) + description = models.TextField() + date = models.DateField() + time = models.TimeField() + location = models.CharField(max_length=255) + organizer = models.ForeignKey( + settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="organized_events" + ) + created_at = models.DateTimeField(auto_now_add=True) + + def __str__(self): + return self.title + +# Create your models here. diff --git a/events/templates/events/event_detail.html b/events/templates/events/event_detail.html new file mode 100644 index 0000000..d11f455 --- /dev/null +++ b/events/templates/events/event_detail.html @@ -0,0 +1,7 @@ +{% extends "base.html" %} +{% block content %} +<h2>{{ event.title }}</h2> +<p><strong>Date:</strong> {{ event.date }} at {{ event.time }}</p> +<p><strong>Location:</strong> {{ event.location }}</p> +<p>{{ event.description }}</p> +{% endblock %} diff --git a/events/templates/events/event_form.html b/events/templates/events/event_form.html new file mode 100644 index 0000000..cc7b8c9 --- /dev/null +++ b/events/templates/events/event_form.html @@ -0,0 +1,9 @@ +{% extends "base.html" %} +{% block content %} +<h2>Create an Event</h2> +<form method="POST"> + {% csrf_token %} + {{ form.as_p }} + <button type="submit">Save Event</button> +</form> +{% endblock %} diff --git a/events/templates/events/event_list.html b/events/templates/events/event_list.html new file mode 100644 index 0000000..509e014 --- /dev/null +++ b/events/templates/events/event_list.html @@ -0,0 +1,16 @@ +{% extends "base.html" %} + +{% block content %} + <h2>Upcoming Events</h2> + <ul> + {% for event in events %} + <li><a href="{% url 'event_detail' event.id %}">{{ event.title }}</a> - {{ event.date }}</li> + {% empty %} + <li>No events available.</li> + {% endfor %} + </ul> + + {% if user.is_authenticated and user.role == "community_leader" %} + <a href="{% url 'create_event' %}">Create Event</a> + {% endif %} +{% endblock %} diff --git a/events/templates/home.html b/events/templates/home.html new file mode 100644 index 0000000..8e6f219 --- /dev/null +++ b/events/templates/home.html @@ -0,0 +1,2 @@ +<h1>Welcome to Uni Hub</h1> +<p>Go to <a href="/events/">Events</a></p> diff --git a/events/tests.py b/events/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/events/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/events/urls.py b/events/urls.py new file mode 100644 index 0000000..7377619 --- /dev/null +++ b/events/urls.py @@ -0,0 +1,11 @@ +from django.urls import path +from .views import event_list, event_detail, create_event + + +urlpatterns = [ + path("", event_list, name="event_list"), # Show all events + path("<int:event_id>/", event_detail, name="event_detail"), # View event details + path("create/", create_event, name="create_event"), # Create an event +] + + diff --git a/events/views.py b/events/views.py new file mode 100644 index 0000000..eacb72c --- /dev/null +++ b/events/views.py @@ -0,0 +1,32 @@ +from django.shortcuts import render, get_object_or_404, redirect +from django.contrib.auth.decorators import login_required +from .models import Event +from .forms import EventForm + +# ✅ View All Events (Homepage) +def event_list(request): + events = Event.objects.all().order_by('date') + return render(request, "events/event_list.html", {"events": events}) + +# ✅ View a Single Event +def event_detail(request, event_id): + event = get_object_or_404(Event, id=event_id) + return render(request, "events/event_detail.html", {"event": event}) + +# ✅ Create an Event (Only for Community Leaders) +@login_required +def create_event(request): + if request.user.role != "community_leader": # Restrict access + return redirect("event_list") # Redirect unauthorized users + + if request.method == "POST": + form = EventForm(request.POST) + if form.is_valid(): + event = form.save(commit=False) + event.organizer = request.user # Set the event creator + event.save() + return redirect("event_list") + else: + form = EventForm() + + return render(request, "events/event_form.html", {"form": form}) diff --git a/manage.py b/manage.py new file mode 100644 index 0000000..497afbc --- /dev/null +++ b/manage.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +import os +import sys + +def main(): + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'unihub_project.settings') + + try: + from django.core.management import execute_from_command_line + except ImportError: + try: + import django + except ImportError: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and available on your PYTHONPATH environment variable?" + ) + raise + + execute_from_command_line(sys.argv) + +if __name__ == '__main__': + main() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..fabc354 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +Django>=4.0 +mysqlclient +djangorestframework +pymysql +cryptography diff --git a/unihub_project/__init__.py b/unihub_project/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/unihub_project/__pycache__/__init__.cpython-313.pyc b/unihub_project/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..77b1621ecfe7f0844cf92f21e92efc123645fae2 GIT binary patch literal 176 zcmey&%ge>Uz`)=bb|oD|KL!yn%m`(CW?^7pn97jOpvmaBlA(x+fq~&ONa~iqvsFxJ zacWU<jBjdsqC#*<eo<<SOMZD?PJUuaaZGwqerZ8`K~a8IYH~?@X?dz{ZenI$Ole+b zMrjgEJSILqGcU6wK3=b&@)n0pZhlH>PO4oID+2=q$o^sw<0CU8BV!RW0|Ns9$-6G* literal 0 HcmV?d00001 diff --git a/unihub_project/__pycache__/__init__.cpython-39.pyc b/unihub_project/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0c893463e52528bb5219b3f6587d4cf85c5371ff GIT binary patch literal 123 zcmYe~<>g{vU|=}yb|M`_KL!!Vn2~{j!GVE+p_qk%fgyz<m_d`#ZzV$!NEku<QqWJ% xPf67;&CARvO^Pol%FjwoF42#V&&<m#iI3MSsJz8tlbfGXnv-e=()k%=0|4Pe8PWg% literal 0 HcmV?d00001 diff --git a/unihub_project/__pycache__/settings.cpython-313.pyc b/unihub_project/__pycache__/settings.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cb8c527d375feb8531c6c77abea1dd56c24c28fa GIT binary patch literal 2792 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 literal 0 HcmV?d00001 diff --git a/unihub_project/__pycache__/settings.cpython-39.pyc b/unihub_project/__pycache__/settings.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..92d747bfaf1605954944f125db7e4cd20b58e124 GIT binary patch literal 2449 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 a@GqACEJ7^*nOKnUHx^+QCNN}UVFduE21o}0 literal 0 HcmV?d00001 diff --git a/unihub_project/__pycache__/urls.cpython-313.pyc b/unihub_project/__pycache__/urls.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c725bca990714f571f369a13026b258e0f8067c8 GIT binary patch literal 1289 zcmey&%ge>Uz`)=bb|syig@NHQhy%l%P{!v?3=9lY8G;##7=jstnY<ajn2MMbKx}4j zW-pc^7BAK!Rt1J&mS9$IHZS%fb_IqQ7A1yYwiu=$0jL>BRFDu72g)>Mf-u1P*kf3g z7=k%W86jdQa-3i}F069gG3>!S!Mv8t`Yc6U>3o{}iLFcw3|yf>J_^bCd1;yHrA3J) znfZANY57G8rFoedrAhGxMfq8&$t4O<T91n>BqLQJp|mKcAhDz*wJ5JRK_MrzxJ02S zzqBN^SRpjXr&ysRU!g2BwY*qQ!7aZ?AveD$RUtDkEx#xiVthePYGQG!LUC%U6_<j7 zf<i_~NkOrdzJ5x6a<N`YR$^XyKFqr0{9OIiJbhC=L;aHcg3RP%eUM`P(xRMVeJ<CE z#N2|M)M6_xx6-_1u*<>Lf(<p)Q*ca4QAo^F$jmLsFDkK8P)IAv&sE5+j87~mfC@sK z307|eRS)t3$OA||v{FzgNG!?FP*>N1Xwb{Z&rQ`)$V<#kwN(eP)it@Ca}tY-b(0c{ zQ&S*{z^3AIMSe*}Y7xjGdSDmBoa2$7n+n!Pq-#Lx^%9HYL565(qPfU3FFB_)B{MHw zAu$hZAINK<hz8qWsHflw4j6@!3{dod)TU}^Dx^V!(h3q>km%3@1vt!+nP78Mb-;lF zHj5b7CgtR(>#OT1Ky_=Vg9O0ls%vU;y#ys?O~zZSi7C06d74bOSU@3uiyf-^B`B$D zGT!0@1vc2XRcv6D`c<5X$;tVpc_qdARlG1J*w`xe)Us5tI5&g=7QMxAiv?teCgUv@ zQ2hC6a^GT)k59=@j*q{^2lZ`oeqKpYW>OI|0|Ub?Zm1wA2#Q!37#NCJLBgz{FfT4* z2eDa-GfPr$v4B+E;zmk1D;Yk6{B_IQ*(xTqIJKxa#y2%RQ6ab_zbG}vCBHl`CqFTz zI3~R)zqA0B)8b3ZQ+0C_GxK6lb6^a}biIPgTO2mI`6;D2sdh!83=9mQfGLh*U|{&b z%*e?2k%^y?<*Nb%qvCxA)w>KbAK4gKIXfgKm`=BvXf@q_qWxtS<(n)V9nuriXXIZN s)4R-~58_Hrbf4jSSw!nHi#CWW)Dbx&>>`WG2ToRgrbg}}VFm^U0GH5x=>Px# literal 0 HcmV?d00001 diff --git a/unihub_project/__pycache__/urls.cpython-39.pyc b/unihub_project/__pycache__/urls.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..476840f2406d3b785ac9d1d402638f6149707e40 GIT binary patch literal 1089 zcmYe~<>g{vU|`VWxs<NR!octt#6iX!3=9ko3=9m#DGUq@DGX5zDU2yhIgGhXQA~^= zHggVhE=v?kE^8DkBSQ*H3TqBqE_)O^BSR`n3R@~u7DpCmGgB%{3VSMR3P&>|n9Z5W zn!*KTbEmSW@TBneGN-ddai#DDGidTBwlXm=aD@i>C?x0SrDdj<7A2Ns=I1G-<rgWG z=4ED-CdC&N<!7ZPmncAKJua@0j8uh$(xRM##FCQKqP*e+g`CXd5{07t(vs9-h0q|M zVug}?g|f`l@?t#&xBMc7-29?ch0MIP{Gwcl@dY`liN&c3#i^-QTnY*b3K=CO1;tkS z`YHLz#d;}OiFxVyFzb@@bM;g6^iA~)^-J;#GLwt-L5lTDi*kzfxm+s}a|?1(i><ia zO7oJzE(co+Hq=m0!7(L8Au&%OGq)hWsKiP^A+0DsS0T4DKCz$xDhP2VSiKQcJ;(<j z4<Px_N<pC@u_Qx7U0nyFK`$deH&sU=FEKaORvpAv*W_}}Nh~hbO-d|IO@Sx^n~KX7 z`6U^tMIeXhfn5x9jz@lODp((pt^ujnODv8D8KR+y<|5C$<ebu!%)E4k#5}NlAg_TU z8f=51o`NShU=&I+K+ywIo2sFykOmD(D@brbqC*c9;4nvKg3V3U0S5}$EMi=nl#`#X zudbs2)vcip5&)a4uBplO5|k4(8E>&BrsQVkX)@hn0fqQ2cBtx?j0_A6nvAzNL4ghS zZ510>rG6D>VsdhRX<kXOeibi_2{yKhJ+&+qEY1yKfJJXH++qP4qRDuR1r&dNn%uY8 z<Kt8EljGx~_@KT`&d)0;%1kO^Vqjpn#SIk%1wj!r0|P@53rLt16z0W6Y#=sEab`*C zEf$c9Tii$qXC*_C07wIf_$8yCoS%}akD9N*DOs<e@)n0pZhlH>PO2Tqr^O%*ECM`? N0*pM&Jd9xY2LSOTPU`>w literal 0 HcmV?d00001 diff --git a/unihub_project/__pycache__/views.cpython-313.pyc b/unihub_project/__pycache__/views.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1e59009d6588ca854fc5532d6fc070549160e1d1 GIT binary patch literal 377 zcmey&%ge>Uz`)=bb|t-^fq~&Mhy%k+P{wC51_p+y48aV+jNS}hj75wJ48crN3`I=o z%$h7OL5fx~-eN0C%}YrwN@fJ{p_qk%fq|KUf#I_h*nnubTqr{@qbbyQ6$VWvzbej* z{M=N%jFQ}(B9IPE##`(~sfDGf#U;fcT?)5+oULL)i&Kk=V|-K76BU9>@{3YqT=L8F za`F>Xieu7?@=FWi3ySiyQj<&KOUqMra}zW3VoLKeGfI<S;xT2JspZ9b1(mnJ*2ROk zMI2B^7V|SOFf=gS;TD{rKEwJlxB3MZ_0J%W_-QiV5=hBP%uCPLE6&I-DoHLaDJ}x} z4Xk%1LlGwf149uz0|Ub?4x8Nkl+v73yCNP21_qGJi+LFs7(OsFGBVy}Q2xxq$fyBU F4gdjESu+3t literal 0 HcmV?d00001 diff --git a/unihub_project/__pycache__/views.cpython-39.pyc b/unihub_project/__pycache__/views.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..91529644c8eda20741bd3dd07afca03ab6032b4c GIT binary patch literal 294 zcmYe~<>g{vU|`t7eJOo10|Ucj5C<7EF)%PVFfcF_OE54nq%fo~<}l<kMlmunq%fs0 zw=hI8rLY7uXtKTp=~>Bmi>)X%FD11onGwW?Vi22|fq}spWDLl*5{4Rv6vk$zU<OSl zzbej*{M=N%jFQ}(B9LX8jJMc}QVUB{i%V8A6tOZeF#M9$PtH$C)i2G<%qUHYFDS~- zN=+`&FUw3VFV-ulyahHO9>fLNQVcSLfw734fq}tKllhiFN>*ZCdcIz9Mt)IAa%o9% h5l9tS8f-ce!N$PAaErqxH$SB`C)Ez*Y_MTGOaKL;Jn#Sj literal 0 HcmV?d00001 diff --git a/unihub_project/__pycache__/wsgi.cpython-39.pyc b/unihub_project/__pycache__/wsgi.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..56c909a3d223001ddc5f74ef328b5ad153c132e7 GIT binary patch literal 540 zcmYe~<>g{vU|=}yb|QT#BLl-@5C<8vFfcGUFfcF_8!#|1q%cG=q%fv1<uFDurZA>3 z=P>0mM=>)pq%vl)EMQGxNnu^c#K@4!+{_TgmckUwpvhKsk1IUb-BTesKQApaT_G*M zNTD<@Gov&qzMv>SD>b=90ZQv}ae0;~q*fH<7pE30lw_nTK=dW%<Rm8Lq$(s9D<mr9 z=BJeAr0V9RmZjz>lqD8rf~E2jb5m0k5)u*%3UV@&6H7Al^AZyDxVYT%ixhJ6i&7Ob z^V0H*a={V``FRQ@8JWcjX_+~xIts<9sazQ)B?ZM+`uZvP$;EmpS&4b+`7k#n=jZCD z=INX28R}=`mzU)0r=%9-<X7gV=9TD|7pG_HbG-zGm7gZ#Es^xpl6a6<Jd!hRiMe<= z`nmhZ2fK!Zc>1{q$NT!bg!;HviK7OBUU6zkNoHPpu_pU1_W1ae{N(ufTTJ=Iw*(;W z(M!%RO4S3IUc|(}z;KH_HLonQC_nEOS8-}dN@`kSX->&4ZX}CWG8BQL6-@k+(NE4# kN!3TS66}7xg34PQHjq%YV+6%A2Ll5G3nvE?4-+2~0A7ly^Z)<= literal 0 HcmV?d00001 diff --git a/unihub_project/asgi.py b/unihub_project/asgi.py new file mode 100644 index 0000000..02da321 --- /dev/null +++ b/unihub_project/asgi.py @@ -0,0 +1,16 @@ +""" +ASGI config for unihub_project project. + +It exposes the ASGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/5.1/howto/deployment/asgi/ +""" + +import os + +from django.core.asgi import get_asgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'unihub_project.settings') + +application = get_asgi_application() diff --git a/unihub_project/settings.py b/unihub_project/settings.py new file mode 100644 index 0000000..745d403 --- /dev/null +++ b/unihub_project/settings.py @@ -0,0 +1,137 @@ +""" +Django settings for unihub_project project. + +Generated by 'django-admin startproject' using Django 5.1.6. + +For more information on this file, see +https://docs.djangoproject.com/en/5.1/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/5.1/ref/settings/ +""" + +from pathlib import Path +import pymysql +pymysql.install_as_MySQLdb() + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/5.1/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = 'django-insecure-9os%w6o3zjgxf-7^=51h4vtl)j)7e4yp--puf!v8_zmh7!#@nc' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] + + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'accounts', + 'events', +] + +AUTH_USER_MODEL = 'accounts.User' + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'unihub_project.urls' + + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'unihub_project.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/5.1/ref/settings/#databases + +# unihub_project/settings.py + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.mysql', + 'NAME': 'unihub_db', + 'USER': 'unihub_user', + 'PASSWORD': 'Thescotts111', + 'HOST': 'db', # Refer to the service name in docker-compose.yml + 'PORT': '3306', + } +} + + + +# Password validation +# https://docs.djangoproject.com/en/5.1/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/5.1/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/5.1/howto/static-files/ + +STATIC_URL = 'static/' + +# Default primary key field type +# https://docs.djangoproject.com/en/5.1/ref/settings/#default-auto-field + +DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' diff --git a/unihub_project/urls.py b/unihub_project/urls.py new file mode 100644 index 0000000..0feeb72 --- /dev/null +++ b/unihub_project/urls.py @@ -0,0 +1,26 @@ +""" +URL configuration for unihub_project project. + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/5.1/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: path('', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.urls import include, path + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) +""" +from django.contrib import admin +from django.urls import path, include +from .views import home_view # Import the homepage view + +urlpatterns = [ + path("admin/", admin.site.urls), + path("accounts/", include("accounts.urls")), # Include accounts URLs + path("events/", include("events.urls")), # Include events URLs + path("", home_view, name="home"), # Homepage +] diff --git a/unihub_project/views.py b/unihub_project/views.py new file mode 100644 index 0000000..ab86773 --- /dev/null +++ b/unihub_project/views.py @@ -0,0 +1,4 @@ +from django.shortcuts import render + +def home_view(request): + return render(request, "home.html") # This will look for templates/home.html diff --git a/unihub_project/wsgi.py b/unihub_project/wsgi.py new file mode 100644 index 0000000..d8a08ab --- /dev/null +++ b/unihub_project/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for unihub_project project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/5.1/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'unihub_project.settings') + +application = get_wsgi_application() -- GitLab