From a8391bc4f5f26edb91b95f91f7aa02f167d39cd2 Mon Sep 17 00:00:00 2001 From: Johanan Oppong Amoateng Date: Tue, 11 Jul 2023 23:55:57 +0000 Subject: [PATCH 01/17] added LibraryApia pp,djoser and rest_framwork to settings.py --- LibraryManagementSystem/settings.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/LibraryManagementSystem/settings.py b/LibraryManagementSystem/settings.py index 6c30852..bff56b5 100644 --- a/LibraryManagementSystem/settings.py +++ b/LibraryManagementSystem/settings.py @@ -37,6 +37,11 @@ "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", + "LibraryApi", + + # third party libraries + "rest_framework", + "djoser", ] MIDDLEWARE = [ From d38997e334dfad1c8bf74bb26a459d0624280b7d Mon Sep 17 00:00:00 2001 From: Johanan Oppong Amoateng Date: Wed, 12 Jul 2023 17:05:59 +0000 Subject: [PATCH 02/17] registered models in admin dashboard --- LibraryApi/admin.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/LibraryApi/admin.py b/LibraryApi/admin.py index 8c38f3f..638d4fb 100644 --- a/LibraryApi/admin.py +++ b/LibraryApi/admin.py @@ -1,3 +1,13 @@ from django.contrib import admin # Register your models here. +from .models import Book,Borrowing,Genre,Author,Publisher,Fine,Reservation + +admin.site.register(Book) +admin.site.register(Borrowing) +admin.site.register(Publisher) +admin.site.register(Author) +admin.site.register(Fine) +admin.site.register(Reservation) +admin.site.register(Genre) + From d602cb40631d8dcfcc5ac2bbf36dd8fcdc1615b6 Mon Sep 17 00:00:00 2001 From: Johanan Oppong Amoateng Date: Wed, 12 Jul 2023 17:06:31 +0000 Subject: [PATCH 03/17] djoser and drf added as depencies --- Pipfile | 13 ++ Pipfile.lock | 364 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 377 insertions(+) create mode 100644 Pipfile create mode 100644 Pipfile.lock diff --git a/Pipfile b/Pipfile new file mode 100644 index 0000000..b005a76 --- /dev/null +++ b/Pipfile @@ -0,0 +1,13 @@ +[[source]] +url = "https://pypi.org/simple" +verify_ssl = true +name = "pypi" + +[packages] +djoser = "*" +djangorestframework = "*" + +[dev-packages] + +[requires] +python_version = "3.11" diff --git a/Pipfile.lock b/Pipfile.lock new file mode 100644 index 0000000..6532247 --- /dev/null +++ b/Pipfile.lock @@ -0,0 +1,364 @@ +{ + "_meta": { + "hash": { + "sha256": "28d4fec85df1853d34f7b1f5fb02f78626485399c3e38629974e2799ff42fc0c" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.11" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "asgiref": { + "hashes": [ + "sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e", + "sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed" + ], + "markers": "python_version >= '3.7'", + "version": "==3.7.2" + }, + "certifi": { + "hashes": [ + "sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7", + "sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716" + ], + "markers": "python_version >= '3.6'", + "version": "==2023.5.7" + }, + "cffi": { + "hashes": [ + "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5", + "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef", + "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104", + "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426", + "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405", + "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375", + "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a", + "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e", + "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc", + "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf", + "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185", + "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497", + "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3", + "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35", + "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c", + "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83", + "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21", + "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca", + "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984", + "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac", + "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd", + "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee", + "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a", + "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2", + "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192", + "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7", + "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585", + "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f", + "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e", + "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27", + "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b", + "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e", + "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e", + "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d", + "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c", + "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415", + "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82", + "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02", + "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314", + "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325", + "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c", + "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3", + "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914", + "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045", + "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d", + "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9", + "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5", + "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2", + "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c", + "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3", + "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2", + "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8", + "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d", + "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d", + "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9", + "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162", + "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76", + "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4", + "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e", + "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9", + "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6", + "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b", + "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01", + "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0" + ], + "version": "==1.15.1" + }, + "charset-normalizer": { + "hashes": [ + "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96", + "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c", + "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710", + "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706", + "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020", + "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252", + "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad", + "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329", + "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a", + "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f", + "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6", + "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4", + "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a", + "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46", + "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2", + "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23", + "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace", + "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd", + "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982", + "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10", + "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2", + "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea", + "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09", + "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5", + "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149", + "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489", + "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9", + "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80", + "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592", + "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3", + "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6", + "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed", + "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c", + "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200", + "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a", + "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e", + "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d", + "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6", + "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623", + "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669", + "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3", + "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa", + "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9", + "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2", + "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f", + "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1", + "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4", + "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a", + "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8", + "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3", + "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029", + "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f", + "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959", + "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22", + "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7", + "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952", + "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346", + "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e", + "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d", + "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299", + "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd", + "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a", + "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3", + "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037", + "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94", + "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c", + "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858", + "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a", + "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449", + "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c", + "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918", + "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1", + "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c", + "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac", + "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa" + ], + "markers": "python_full_version >= '3.7.0'", + "version": "==3.2.0" + }, + "cryptography": { + "hashes": [ + "sha256:01f1d9e537f9a15b037d5d9ee442b8c22e3ae11ce65ea1f3316a41c78756b711", + "sha256:079347de771f9282fbfe0e0236c716686950c19dee1b76240ab09ce1624d76d7", + "sha256:182be4171f9332b6741ee818ec27daff9fb00349f706629f5cbf417bd50e66fd", + "sha256:192255f539d7a89f2102d07d7375b1e0a81f7478925b3bc2e0549ebf739dae0e", + "sha256:2a034bf7d9ca894720f2ec1d8b7b5832d7e363571828037f9e0c4f18c1b58a58", + "sha256:342f3767e25876751e14f8459ad85e77e660537ca0a066e10e75df9c9e9099f0", + "sha256:439c3cc4c0d42fa999b83ded80a9a1fb54d53c58d6e59234cfe97f241e6c781d", + "sha256:49c3222bb8f8e800aead2e376cbef687bc9e3cb9b58b29a261210456a7783d83", + "sha256:674b669d5daa64206c38e507808aae49904c988fa0a71c935e7006a3e1e83831", + "sha256:7a9a3bced53b7f09da251685224d6a260c3cb291768f54954e28f03ef14e3766", + "sha256:7af244b012711a26196450d34f483357e42aeddb04128885d95a69bd8b14b69b", + "sha256:7d230bf856164de164ecb615ccc14c7fc6de6906ddd5b491f3af90d3514c925c", + "sha256:84609ade00a6ec59a89729e87a503c6e36af98ddcd566d5f3be52e29ba993182", + "sha256:9a6673c1828db6270b76b22cc696f40cde9043eb90373da5c2f8f2158957f42f", + "sha256:9b6d717393dbae53d4e52684ef4f022444fc1cce3c48c38cb74fca29e1f08eaa", + "sha256:9c3fe6534d59d071ee82081ca3d71eed3210f76ebd0361798c74abc2bcf347d4", + "sha256:a719399b99377b218dac6cf547b6ec54e6ef20207b6165126a280b0ce97e0d2a", + "sha256:b332cba64d99a70c1e0836902720887fb4529ea49ea7f5462cf6640e095e11d2", + "sha256:d124682c7a23c9764e54ca9ab5b308b14b18eba02722b8659fb238546de83a76", + "sha256:d73f419a56d74fef257955f51b18d046f3506270a5fd2ac5febbfa259d6c0fa5", + "sha256:f0dc40e6f7aa37af01aba07277d3d64d5a03dc66d682097541ec4da03cc140ee", + "sha256:f14ad275364c8b4e525d018f6716537ae7b6d369c094805cae45300847e0894f", + "sha256:f772610fe364372de33d76edcd313636a25684edb94cee53fd790195f5989d14" + ], + "markers": "python_version >= '3.7'", + "version": "==41.0.2" + }, + "defusedxml": { + "hashes": [ + "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69", + "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==0.7.1" + }, + "django": { + "hashes": [ + "sha256:45a747e1c5b3d6df1b141b1481e193b033fd1fdbda3ff52677dc81afdaacbaed", + "sha256:f7c7852a5ac5a3da5a8d5b35cc6168f31b605971441798dac845f17ca8028039" + ], + "markers": "python_version >= '3.8'", + "version": "==4.2.3" + }, + "django-templated-mail": { + "hashes": [ + "sha256:8db807effebb42a532622e2d142dfd453dafcd0d7794c4c3332acb90656315f9", + "sha256:f7127e1e31d7cad4e6c4b4801d25814d4b8782627ead76f4a75b3b7650687556" + ], + "version": "==1.1.1" + }, + "djangorestframework": { + "hashes": [ + "sha256:579a333e6256b09489cbe0a067e66abe55c6595d8926be6b99423786334350c8", + "sha256:eb63f58c9f218e1a7d064d17a70751f528ed4e1d35547fdade9aaf4cd103fd08" + ], + "index": "pypi", + "version": "==3.14.0" + }, + "djangorestframework-simplejwt": { + "hashes": [ + "sha256:4c0d2e2513e12587d93501ac091781684a216c3ee614eb3b5a10586aef5ca845", + "sha256:d27d4bcac2c6394f678dea8b4d0d511c6e18a7f2eb8aaeeb8a7de601aeb77c42" + ], + "markers": "python_version >= '3.7'", + "version": "==5.2.2" + }, + "djoser": { + "hashes": [ + "sha256:4aa48502df870c8b5f07109ad4a749cc881c37bb5efa85cf5462ea695a0dca8c", + "sha256:7b24718cdc51b4294b0abcf6bf0ead11aa3ca83652e351dfb04b7b8b15afa3b0" + ], + "index": "pypi", + "version": "==2.2.0" + }, + "idna": { + "hashes": [ + "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4", + "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2" + ], + "markers": "python_version >= '3.5'", + "version": "==3.4" + }, + "oauthlib": { + "hashes": [ + "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca", + "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918" + ], + "markers": "python_version >= '3.6'", + "version": "==3.2.2" + }, + "pycparser": { + "hashes": [ + "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9", + "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206" + ], + "version": "==2.21" + }, + "pyjwt": { + "hashes": [ + "sha256:ba2b425b15ad5ef12f200dc67dd56af4e26de2331f965c5439994dad075876e1", + "sha256:bd6ca4a3c4285c1a2d4349e5a035fdf8fb94e04ccd0fcbe6ba289dae9cc3e074" + ], + "markers": "python_version >= '3.7'", + "version": "==2.7.0" + }, + "python3-openid": { + "hashes": [ + "sha256:33fbf6928f401e0b790151ed2b5290b02545e8775f982485205a066f874aaeaf", + "sha256:6626f771e0417486701e0b4daff762e7212e820ca5b29fcc0d05f6f8736dfa6b" + ], + "version": "==3.2.0" + }, + "pytz": { + "hashes": [ + "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588", + "sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb" + ], + "version": "==2023.3" + }, + "requests": { + "hashes": [ + "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f", + "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" + ], + "markers": "python_version >= '3.7'", + "version": "==2.31.0" + }, + "requests-oauthlib": { + "hashes": [ + "sha256:2577c501a2fb8d05a304c09d090d6e47c306fef15809d102b327cf8364bddab5", + "sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.3.1" + }, + "social-auth-app-django": { + "hashes": [ + "sha256:0347ca4cd23ea9d15a665da9d22950552fb66b95600e6c2ebae38ca883b3a4ed", + "sha256:4a5dae406f3874b4003708ff120c02cb1a4c8eeead56cd163646347309fcd0f8" + ], + "markers": "python_version >= '3.7'", + "version": "==5.2.0" + }, + "social-auth-core": { + "hashes": [ + "sha256:9791d7c7aee2ac8517fe7a2ea2f942a8a5492b3a4ccb44a9b0dacc87d182f2aa", + "sha256:ea7a19c46b791b767e95f467881b53c5fd0d1efb40048d9ed3dbc46daa05c954" + ], + "markers": "python_version >= '3.6'", + "version": "==4.4.2" + }, + "sqlparse": { + "hashes": [ + "sha256:5430a4fe2ac7d0f93e66f1efc6e1338a41884b7ddf2a350cedd20ccc4d9d28f3", + "sha256:d446183e84b8349fa3061f0fe7f06ca94ba65b426946ffebe6e3e8295332420c" + ], + "markers": "python_version >= '3.5'", + "version": "==0.4.4" + }, + "tzdata": { + "hashes": [ + "sha256:11ef1e08e54acb0d4f95bdb1be05da659673de4acbd21bf9c69e94cc5e907a3a", + "sha256:7e65763eef3120314099b6939b5546db7adce1e7d6f2e179e3df563c70511eda" + ], + "markers": "sys_platform == 'win32'", + "version": "==2023.3" + }, + "urllib3": { + "hashes": [ + "sha256:48e7fafa40319d358848e1bc6809b208340fafe2096f1725d05d67443d0483d1", + "sha256:bee28b5e56addb8226c96f7f13ac28cb4c301dd5ea8a6ca179c0b9835e032825" + ], + "markers": "python_version >= '3.7'", + "version": "==2.0.3" + } + }, + "develop": {} +} From c5ac1cc4407f0b7c9e29e68f560cb99a3eee88b4 Mon Sep 17 00:00:00 2001 From: Johanan Oppong Amoateng Date: Wed, 12 Jul 2023 17:06:54 +0000 Subject: [PATCH 04/17] migrations --- LibraryApi/migrations/0001_initial.py | 147 ++++++++++++++++++ ...02_rename_borrowings_borrowing_and_more.py | 54 +++++++ .../0003_alter_fine_borrowing_id.py | 20 +++ 3 files changed, 221 insertions(+) create mode 100644 LibraryApi/migrations/0001_initial.py create mode 100644 LibraryApi/migrations/0002_rename_borrowings_borrowing_and_more.py create mode 100644 LibraryApi/migrations/0003_alter_fine_borrowing_id.py diff --git a/LibraryApi/migrations/0001_initial.py b/LibraryApi/migrations/0001_initial.py new file mode 100644 index 0000000..023689c --- /dev/null +++ b/LibraryApi/migrations/0001_initial.py @@ -0,0 +1,147 @@ +# Generated by Django 4.2.3 on 2023-07-12 00:33 + +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="Author", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=255)), + ], + ), + migrations.CreateModel( + name="Book", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("title", models.CharField(max_length=255)), + ("publication_date", models.DateField()), + ("isbn", models.CharField(max_length=20)), + ("copies", models.PositiveIntegerField()), + ("available_copies", models.PositiveIntegerField()), + ("availabity_stautus", models.BooleanField(default=True)), + ("author", models.ManyToManyField(to="LibraryApi.author")), + ], + ), + migrations.CreateModel( + name="Genre", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=255)), + ], + ), + migrations.CreateModel( + name="Publisher", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=255)), + ], + ), + migrations.CreateModel( + name="Reservations", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("reservation_date", models.DateTimeField()), + ( + "book_id", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="LibraryApi.book", + ), + ), + ( + "user_id", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), + ], + ), + migrations.CreateModel( + name="Borrowings", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("borrowing_date", models.DateTimeField()), + ("due_date", models.DateTimeField()), + ("return_date", models.DateTimeField()), + ( + "book", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="LibraryApi.book", + ), + ), + ( + "borrower", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to=settings.AUTH_USER_MODEL, + ), + ), + ], + ), + migrations.AddField( + model_name="book", + name="genre", + field=models.ManyToManyField(to="LibraryApi.genre"), + ), + ] diff --git a/LibraryApi/migrations/0002_rename_borrowings_borrowing_and_more.py b/LibraryApi/migrations/0002_rename_borrowings_borrowing_and_more.py new file mode 100644 index 0000000..0f4d1c4 --- /dev/null +++ b/LibraryApi/migrations/0002_rename_borrowings_borrowing_and_more.py @@ -0,0 +1,54 @@ +# Generated by Django 4.2.3 on 2023-07-12 00:59 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("LibraryApi", "0001_initial"), + ] + + operations = [ + migrations.RenameModel( + old_name="Borrowings", + new_name="Borrowing", + ), + migrations.RenameModel( + old_name="Reservations", + new_name="Reservation", + ), + migrations.CreateModel( + name="Fine", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("fine_amount", models.DecimalField(decimal_places=2, max_digits=6)), + ("fine_date", models.DateTimeField()), + ("fine_paid_status", models.BooleanField(default=False)), + ( + "borrowing_id", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="LibraryApi.book", + ), + ), + ( + "user_id", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), + ], + ), + ] diff --git a/LibraryApi/migrations/0003_alter_fine_borrowing_id.py b/LibraryApi/migrations/0003_alter_fine_borrowing_id.py new file mode 100644 index 0000000..52a47d6 --- /dev/null +++ b/LibraryApi/migrations/0003_alter_fine_borrowing_id.py @@ -0,0 +1,20 @@ +# Generated by Django 4.2.2 on 2023-07-12 07:39 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + ("LibraryApi", "0002_rename_borrowings_borrowing_and_more"), + ] + + operations = [ + migrations.AlterField( + model_name="fine", + name="borrowing_id", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="LibraryApi.borrowing" + ), + ), + ] From 11c6e85d4c601b52972bbc91596411a84fb4606d Mon Sep 17 00:00:00 2001 From: Johanan Oppong Amoateng Date: Wed, 12 Jul 2023 17:07:27 +0000 Subject: [PATCH 05/17] added models --- LibraryApi/models.py | 66 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/LibraryApi/models.py b/LibraryApi/models.py index 71a8362..32bc9dc 100644 --- a/LibraryApi/models.py +++ b/LibraryApi/models.py @@ -1,3 +1,69 @@ from django.db import models +from django.contrib.auth import get_user_model + + # Create your models here. +class Author(models.Model): + name = models.CharField(max_length=255) + + def __str__(self): + return self.name + + +class Publisher(models.Model): + name = models.CharField(max_length=255) + + def __str__(self): + return self.name + + +class Genre(models.Model): + name = models.CharField(max_length=255) + + def __str__(self): + return self.name + + +class Book(models.Model): + author = models.ManyToManyField(Author) + title = models.CharField(max_length=255) + publication_date = models.DateField() + isbn = models.CharField(max_length=20) + edition = models.SmallIntegerField() + genre = models.ManyToManyField(Genre) + copies = models.PositiveIntegerField() + available_copies = models.PositiveIntegerField() + availabity_stautus = models.BooleanField(default=True) + + def __str__(self): + return self.title + + +class Borrowing(models.Model): + borrower = models.ForeignKey(get_user_model(),on_delete=models.PROTECT) + book = models.ForeignKey(Book,on_delete=models.PROTECT) + borrowing_date = models.DateTimeField() + due_date = models.DateTimeField() + return_date = models.DateTimeField() + + def __str__(self): + return f"{self.borrower} borrowed {self.book}" + +class Reservation(models.Model): + user_id = models.ForeignKey(get_user_model(),on_delete=models.CASCADE) + book_id = models.ForeignKey(Book,on_delete=models.PROTECT) + reservation_date = models.DateTimeField() + + def __str__(self): + return f"{self.user_id} reserved {self.book}" + +class Fine(models.Model): + user_id = models.ForeignKey(get_user_model(),on_delete=models.CASCADE) + borrowing_id = models.ForeignKey(Borrowing,on_delete=models.PROTECT) + fine_amount = models.DecimalField(max_digits=6,decimal_places=2) + fine_date = models.DateTimeField() + fine_paid_status = models.BooleanField(default=False) + + def __str__(self): + return f"{self.user_id} fined {self.fine_amount} for {self.borrowing_id}" \ No newline at end of file From 9dc9d503d95c8111368bc938d815122e3c27abe6 Mon Sep 17 00:00:00 2001 From: Johanan Oppong Amoateng Date: Mon, 17 Jul 2023 23:14:21 +0000 Subject: [PATCH 06/17] migrations --- LibraryApi/migrations/0004_book_edition.py | 18 ++++++++++ ...owing_libarian_alter_borrowing_borrower.py | 35 +++++++++++++++++++ ...ilabity_stautus_book_available_and_more.py | 25 +++++++++++++ .../0007_alter_borrowing_borrower.py | 24 +++++++++++++ 4 files changed, 102 insertions(+) create mode 100644 LibraryApi/migrations/0004_book_edition.py create mode 100644 LibraryApi/migrations/0005_borrowing_libarian_alter_borrowing_borrower.py create mode 100644 LibraryApi/migrations/0006_rename_availabity_stautus_book_available_and_more.py create mode 100644 LibraryApi/migrations/0007_alter_borrowing_borrower.py diff --git a/LibraryApi/migrations/0004_book_edition.py b/LibraryApi/migrations/0004_book_edition.py new file mode 100644 index 0000000..71b79f4 --- /dev/null +++ b/LibraryApi/migrations/0004_book_edition.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.2 on 2023-07-12 20:31 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("LibraryApi", "0003_alter_fine_borrowing_id"), + ] + + operations = [ + migrations.AddField( + model_name="book", + name="edition", + field=models.SmallIntegerField(default=1), + preserve_default=False, + ), + ] diff --git a/LibraryApi/migrations/0005_borrowing_libarian_alter_borrowing_borrower.py b/LibraryApi/migrations/0005_borrowing_libarian_alter_borrowing_borrower.py new file mode 100644 index 0000000..060e5e5 --- /dev/null +++ b/LibraryApi/migrations/0005_borrowing_libarian_alter_borrowing_borrower.py @@ -0,0 +1,35 @@ +# Generated by Django 4.2.2 on 2023-07-13 19:52 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("LibraryApi", "0004_book_edition"), + ] + + operations = [ + migrations.AddField( + model_name="borrowing", + name="libarian", + field=models.ForeignKey( + default=1, + on_delete=django.db.models.deletion.PROTECT, + related_name="libarian", + to=settings.AUTH_USER_MODEL, + ), + preserve_default=False, + ), + migrations.AlterField( + model_name="borrowing", + name="borrower", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="member", + to=settings.AUTH_USER_MODEL, + ), + ), + ] diff --git a/LibraryApi/migrations/0006_rename_availabity_stautus_book_available_and_more.py b/LibraryApi/migrations/0006_rename_availabity_stautus_book_available_and_more.py new file mode 100644 index 0000000..7892445 --- /dev/null +++ b/LibraryApi/migrations/0006_rename_availabity_stautus_book_available_and_more.py @@ -0,0 +1,25 @@ +# Generated by Django 4.2.2 on 2023-07-13 23:51 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("LibraryApi", "0005_borrowing_libarian_alter_borrowing_borrower"), + ] + + operations = [ + migrations.RenameField( + model_name="book", + old_name="availabity_stautus", + new_name="available", + ), + migrations.RemoveField( + model_name="book", + name="available_copies", + ), + migrations.RemoveField( + model_name="book", + name="copies", + ), + ] diff --git a/LibraryApi/migrations/0007_alter_borrowing_borrower.py b/LibraryApi/migrations/0007_alter_borrowing_borrower.py new file mode 100644 index 0000000..95fbf62 --- /dev/null +++ b/LibraryApi/migrations/0007_alter_borrowing_borrower.py @@ -0,0 +1,24 @@ +# Generated by Django 4.2.2 on 2023-07-14 23:26 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("LibraryApi", "0006_rename_availabity_stautus_book_available_and_more"), + ] + + operations = [ + migrations.AlterField( + model_name="borrowing", + name="borrower", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="borrower", + to=settings.AUTH_USER_MODEL, + ), + ), + ] From 371e947ea03633af1c821e84cfa755a193663d51 Mon Sep 17 00:00:00 2001 From: Johanan Oppong Amoateng Date: Mon, 17 Jul 2023 23:23:56 +0000 Subject: [PATCH 07/17] added the libraryapi urlconf --- LibraryManagementSystem/urls.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/LibraryManagementSystem/urls.py b/LibraryManagementSystem/urls.py index fb5e473..a55e4f1 100644 --- a/LibraryManagementSystem/urls.py +++ b/LibraryManagementSystem/urls.py @@ -15,8 +15,11 @@ 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ from django.contrib import admin -from django.urls import path +from django.urls import path,include urlpatterns = [ path("admin/", admin.site.urls), + path("library/",include("LibraryApi.urls")), + path('auth/', include('djoser.urls')), + path('auth/', include('djoser.urls.authtoken')), ] From af03efd47f81015aad66e3e86958aa8185db4b2d Mon Sep 17 00:00:00 2001 From: Johanan Oppong Amoateng Date: Mon, 17 Jul 2023 23:25:03 +0000 Subject: [PATCH 08/17] added IsLibarianorReadOnly and IsLibarian --- LibraryApi/permissions.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 LibraryApi/permissions.py diff --git a/LibraryApi/permissions.py b/LibraryApi/permissions.py new file mode 100644 index 0000000..a607097 --- /dev/null +++ b/LibraryApi/permissions.py @@ -0,0 +1,29 @@ +from rest_framework import permissions + +class IsLibarianOrReadOnly(permissions.BasePermission): + def has_object_permission(self, request, view, obj): + # Read permissions are allowed to any request, + # so we'll always allow GET, HEAD or OPTIONS requests. + if request.method in permissions.SAFE_METHODS: + return True + + if request.user.groups.filter(name="Libarian").exists(): + return True + return False + +class IsLibarian(permissions.BasePermission): + def has_permission(self,request,view): + if request.user.groups.filter(name="Libarian").exists(): + return True + return False + + def has_object_permission(self, request, view, obj): + # Read permissions are allowed to any request, + # so we'll always allow GET, HEAD or OPTIONS requests. + if request.method in permissions.SAFE_METHODS: + return True + + if request.user.groups.filter(name="Libarian").exists(): + return True + return False + From 218e68545e8938fb9711a86dfc88e4a02ddeec69 Mon Sep 17 00:00:00 2001 From: Johanan Oppong Amoateng Date: Mon, 17 Jul 2023 23:25:34 +0000 Subject: [PATCH 09/17] librraryapi endpoints --- LibraryApi/urls.py | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 LibraryApi/urls.py diff --git a/LibraryApi/urls.py b/LibraryApi/urls.py new file mode 100644 index 0000000..75660e6 --- /dev/null +++ b/LibraryApi/urls.py @@ -0,0 +1,43 @@ +from django.urls import path +from .views import ( + BookDetailView, + BookListView, + AuthorDetailView, + AuthorListView, + PublisherListView, + PublisherDetailView, + FineListView, + FineDetailView, + BorrowingDetailView, + BorrowingListView, + GenreDetailView, + GenreListView, + ReservationDetailView, + ReservationListView, + SearchBookView, + LendBook, + books_lended_by_libarian, + return_book +) + +urlpatterns = [ + path("authors/", AuthorListView.as_view(), name="authors"), + path("authors/", AuthorDetailView.as_view(), name="author-detail"), + path("publishers/", PublisherListView.as_view(), name="publishers"), + path("publishers/", PublisherDetailView.as_view(), name="publisher-detail"), + path("books/", BookListView.as_view(), name="books"), + path("books/", BookDetailView.as_view(), name="book-detail"), + path("fines/", FineListView.as_view(), name="fines"), + path("fines/", FineDetailView.as_view(), name="fine-detail"), + path("genres/", GenreListView.as_view(), name="genres"), + path("genres/", GenreDetailView.as_view(), name="genre-detail"), + path("reservations/", ReservationListView.as_view(), name="reservations"), + path("reservations/", ReservationDetailView.as_view(), name="reservation-detail"), + path("borrowings/", BorrowingListView.as_view(), name="borrowings"), + path("borrowings/", BorrowingDetailView.as_view(), name="borrowing-detail"), + path("lend-book/", LendBook.as_view(), name="lend-book"), + path("books-search",SearchBookView.as_view(),name="search-books"), + path("libarian/lended-books",books_lended_by_libarian,name="books_lended_by_libarian"), + path("borrowed-books/return-book/ Date: Mon, 17 Jul 2023 23:26:11 +0000 Subject: [PATCH 10/17] made model changes --- LibraryApi/models.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/LibraryApi/models.py b/LibraryApi/models.py index 32bc9dc..3ceb752 100644 --- a/LibraryApi/models.py +++ b/LibraryApi/models.py @@ -1,5 +1,6 @@ from django.db import models from django.contrib.auth import get_user_model +import datetime @@ -32,19 +33,18 @@ class Book(models.Model): isbn = models.CharField(max_length=20) edition = models.SmallIntegerField() genre = models.ManyToManyField(Genre) - copies = models.PositiveIntegerField() - available_copies = models.PositiveIntegerField() - availabity_stautus = models.BooleanField(default=True) + available = models.BooleanField(default=True) def __str__(self): return self.title - class Borrowing(models.Model): - borrower = models.ForeignKey(get_user_model(),on_delete=models.PROTECT) + borrower = models.ForeignKey(get_user_model(),on_delete=models.PROTECT,related_name="borrower") + libarian = models.ForeignKey(get_user_model(),on_delete=models.PROTECT,related_name="libarian") book = models.ForeignKey(Book,on_delete=models.PROTECT) - borrowing_date = models.DateTimeField() - due_date = models.DateTimeField() + borrowing_date = models.DateTimeField(auto_now=True) + due_date = models.DateTimeField(default=datetime.datetime.now()+ datetime.timedelta(days=3)) + returned = models.BooleanField(default=False) return_date = models.DateTimeField() def __str__(self): @@ -53,7 +53,7 @@ def __str__(self): class Reservation(models.Model): user_id = models.ForeignKey(get_user_model(),on_delete=models.CASCADE) book_id = models.ForeignKey(Book,on_delete=models.PROTECT) - reservation_date = models.DateTimeField() + reservation_date = models.DateTimeField(auto_now=True) def __str__(self): return f"{self.user_id} reserved {self.book}" @@ -62,8 +62,8 @@ class Fine(models.Model): user_id = models.ForeignKey(get_user_model(),on_delete=models.CASCADE) borrowing_id = models.ForeignKey(Borrowing,on_delete=models.PROTECT) fine_amount = models.DecimalField(max_digits=6,decimal_places=2) - fine_date = models.DateTimeField() + fine_date = models.DateTimeField(auto_now=True) fine_paid_status = models.BooleanField(default=False) def __str__(self): - return f"{self.user_id} fined {self.fine_amount} for {self.borrowing_id}" \ No newline at end of file + return f"{self.user_id} fined {self.fine_amount} for {self.borrowing_id}" From e13cf250a943f1d2edd127b5c32a967216a2c09a Mon Sep 17 00:00:00 2001 From: Johanan Oppong Amoateng Date: Mon, 17 Jul 2023 23:27:07 +0000 Subject: [PATCH 11/17] serializers --- LibraryApi/serializers.py | 105 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 LibraryApi/serializers.py diff --git a/LibraryApi/serializers.py b/LibraryApi/serializers.py new file mode 100644 index 0000000..be9a5b9 --- /dev/null +++ b/LibraryApi/serializers.py @@ -0,0 +1,105 @@ +from rest_framework import serializers +from django.contrib.auth.models import User +from .models import Book,Borrowing,Genre,Author,Publisher,Fine,Reservation + + +class UserSerializer(serializers.ModelSerializer): + username = serializers.CharField(max_length=255) + class Meta: + model = User + fields = ["username","email"] + + +class GenreSerializer(serializers.ModelSerializer): + class Meta: + model = Genre + fields = "__all__" + +class AuthorSerializer(serializers.ModelSerializer): + class Meta: + model = Author + fields = "__all__" + +class PublisherSerializer(serializers.ModelSerializer): + class Meta: + model = Publisher + fields = "__all__" + +class BookSerializer(serializers.ModelSerializer): + genre = GenreSerializer(many=True) + author = AuthorSerializer(many=True) + class Meta: + model = Book + fields = "__all__" + + def create(self, validated_data): + author_data = validated_data.pop('author') + genre_data = validated_data.pop('genre') + book = Book.objects.create(**validated_data) + + # for author in author_data: + author_obj = Author.objects.create(**author_data) + book.author.add(author_obj) + + # for genre in genre_data: + genre_obj = Genre.objects.create(**genre_data) + print(genre_obj) + book.genre.add(genre_obj) + + return book + + + +class BorrowedBookSerializer(serializers.ModelSerializer): + class Meta: + model = Book + fields = ["title","isbn","edition"] + + + +class BorrowingSerializer(serializers.ModelSerializer): + due_date = serializers.DateTimeField(read_only=True) + borrower= UserSerializer() + libarian = UserSerializer(read_only=True) + book = BorrowedBookSerializer() + + class Meta: + model = Borrowing + fields = "__all__" + + + + def create(self, validated_data): + borrower_data = validated_data.pop('borrower') + print(borrower_data) + book = validated_data.pop('book') + + # borrower = User.objects.get(**borrower_data) + book = Book.objects.get(**book) + if book.available: + user = User.objects.get(username=borrower_data['username']) + + lent_book = Borrowing.objects.create(**validated_data,book=book,borrower=user) + book.available = False + book.save() + + return lent_book + + + # def update() + + + +class ReservationSerializer(serializers.ModelSerializer): + user_id = UserSerializer() + book_id = BookSerializer() + class Meta: + model = Reservation + fields = "__all__" + +class FineSerializer(serializers.ModelSerializer): + user_id = UserSerializer() + borrowing_id = BorrowingSerializer() + class Meta: + model = Fine + fields = "__all__" \ No newline at end of file From bc1ebb5bfff0ff34bac491200764eb2379e6980f Mon Sep 17 00:00:00 2001 From: Johanan Oppong Amoateng Date: Mon, 17 Jul 2023 23:27:21 +0000 Subject: [PATCH 12/17] libraryapi views --- LibraryApi/views.py | 167 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 166 insertions(+), 1 deletion(-) diff --git a/LibraryApi/views.py b/LibraryApi/views.py index 91ea44a..72ec273 100644 --- a/LibraryApi/views.py +++ b/LibraryApi/views.py @@ -1,3 +1,168 @@ -from django.shortcuts import render +import datetime +from rest_framework import generics +from rest_framework.views import APIView +from rest_framework.response import Response +from rest_framework.decorators import api_view,permission_classes +from .models import Fine, Book, Borrowing, Author, Genre, Publisher, Reservation +from .serializers import ( + AuthorSerializer, + BorrowingSerializer, + FineSerializer, + PublisherSerializer, + BookSerializer, + GenreSerializer, + ReservationSerializer, + # CreateBorrowingSerializer +) +from rest_framework.permissions import IsAuthenticated +from .permissions import IsLibarianOrReadOnly,IsLibarian + # Create your views here. +class AuthorListView(generics.ListCreateAPIView): + serializer_class = AuthorSerializer + queryset = Author.objects.all() + permission_classes = [IsLibarianOrReadOnly] + +class AuthorDetailView(generics.RetrieveUpdateDestroyAPIView): + serializer_class = AuthorSerializer + queryset = Author.objects.all() + permission_classes = [IsLibarianOrReadOnly] + +class GenreListView(generics.ListCreateAPIView): + serializer_class = GenreSerializer + queryset = Genre.objects.all() + permission_classes = [IsLibarianOrReadOnly] + +class GenreDetailView(generics.RetrieveUpdateDestroyAPIView): + serializer_class = GenreSerializer + queryset = Genre.objects.all() + permission_classes = [IsLibarianOrReadOnly] + +class PublisherListView(generics.ListCreateAPIView): + serializer_class = PublisherSerializer + queryset = Publisher.objects.all() + permission_classes = [IsLibarianOrReadOnly] + +class PublisherDetailView(generics.RetrieveUpdateDestroyAPIView): + serializer_class = AuthorSerializer + queryset = Publisher.objects.all() + permission_classes = [IsLibarianOrReadOnly] + +class BookListView(generics.ListCreateAPIView): + serializer_class = BookSerializer + queryset = Book.objects.all() + # permission_classes = [IsLibarianOrReadOnly,IsAuthenticated] + +class BookDetailView(generics.RetrieveUpdateDestroyAPIView): + serializer_class = BookSerializer + queryset = Book.objects.all() + permission_classes = [IsLibarianOrReadOnly,IsAuthenticated] + + +class BorrowingListView(generics.ListAPIView): + serializer_class = BorrowingSerializer + # permission_classes = [IsLibarianOrReadOnly,IsAuthenticated] + # queryset=Borrowing.objects.all() + + def get_queryset(self): + user = self.request.user + if user.groups.filter(name="Libarian").exists(): + return Borrowing.objects.all() + return Borrowing.objects.filter(borrower=user.id) + +class LendBook(generics.CreateAPIView): + serializer_class = BorrowingSerializer + permission_classes = [IsLibarian,IsAuthenticated] + queryset=Borrowing.objects.all() + + def perform_create(self, serializer): + serializer.save(libarian=self.request.user) + +class BorrowingDetailView(generics.RetrieveUpdateDestroyAPIView): + serializer_class = BorrowingSerializer + # queryset = Borrowing.objects.all() + permission_classes = [IsLibarianOrReadOnly,IsAuthenticated] + + def get_queryset(self): + + user = self.request.user + if user.groups.filter(name="Libarian").exists(): + return Borrowing.objects.all() + return Borrowing.objects.filter(borrower=user.id) + + + +class ReservationListView(generics.ListCreateAPIView): + serializer_class = ReservationSerializer + queryset = Reservation.objects.all() + permission_classes = [IsAuthenticated] + def get_queryset(self): + user = self.request.user + if user.groups.filter(name="Libarian").exists(): + return Reservation.objects.all() + return Reservation.objects.filter(borrower=user.id) + + def perform_create(self,serializer): + serializer.save(user_id=self.request.user) + +class ReservationDetailView(generics.RetrieveUpdateDestroyAPIView): + serializer_class = ReservationSerializer + queryset = Reservation.objects.all() + permission_classes = [IsAuthenticated] + + def get_queryset(self): + user = self.request.user + if user.groups.filter(name="Libarian").exists(): + return Reservation.objects.all() + return Reservation.objects.filter(borrower=user.id) + + +class FineListView(generics.ListCreateAPIView): + queryset = Fine.objects.all() + serializer_class = FineSerializer + + def get_queryset(self): + + user = self.request.user + if user.groups.filter(name="Libarian").exists(): + return Fine.objects.all() + return Fine.objects.filter(user_id==user.id) + +class FineDetailView(generics.RetrieveUpdateDestroyAPIView): + queryset = Fine.objects.all() + serializer_class = FineSerializer + + def get_queryset(self): + + user = self.request.user + if user.groups.filter(name="Libarian").exists(): + return Fine.objects.all() + return Fine.objects.filter(user_id=user.id) + +class SearchBookView(generics.ListAPIView): + queryset = Book.objects.all() + serializer_class = BookSerializer + filterset_fields = ["id","title","isbn","author","genre","edition"] + + + +@api_view(['GET']) +@permission_classes([IsLibarian]) +def books_lended_by_libarian(request): + libarian = request.user + lended_books = libarian.libarian.all() + serializer = BookSerializer(data=lended_books,many=True) + return Response(serializer.data) + + +@api_view(["PUT"]) +@permission_classes([IsAuthenticated,IsLibarian]) +def return_book(request,book_id): + user = request.user + borrowed_book = Borrowing.objects.filter(book=book_id,borrower=user,returned=False) + borrowed_book.returned=True + borrowed_book.return_date=datetime.datetime.now() + borrowed_book.save() + serializer = BorrowingSerializer(data=borrowed_book) + return Response(data=serializer.data) From 474d21b6a5bc187e38fb5613c1b4ff373bd4e64b Mon Sep 17 00:00:00 2001 From: Johanan Oppong Amoateng Date: Mon, 17 Jul 2023 23:27:35 +0000 Subject: [PATCH 13/17] settings --- LibraryManagementSystem/settings.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/LibraryManagementSystem/settings.py b/LibraryManagementSystem/settings.py index bff56b5..de2b7fd 100644 --- a/LibraryManagementSystem/settings.py +++ b/LibraryManagementSystem/settings.py @@ -40,10 +40,35 @@ "LibraryApi", # third party libraries + 'django_filters', "rest_framework", + 'rest_framework.authtoken', "djoser", ] +REST_FRAMEWORK = { + 'DEFAULT_AUTHENTICATION_CLASSES': ( + 'rest_framework.authentication.TokenAuthentication', + ), + 'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'] +} +DJOSER = { + # 'LOGIN_FIELD': 'email', + # 'USER_CREATE_PASSWORD_RETYPE': True, + # 'SERIALIZERS': { + # 'user_create': 'accounts.serializers.UserRegistrationSerializer', + # }, + # 'TOKEN_MODEL': 'accounts.models.TokenModel', + # 'PASSWORD_RESET_CONFIRM_URL': 'password/reset/confirm/{uid}/{token}', + # 'USERNAME_RESET_CONFIRM_URL': 'email/reset/confirm/{uid}/{token}', + # 'ACTIVATION_URL': 'activate/{uid}/{token}', + # 'SEND_ACTIVATION_EMAIL': True, + # 'SEND_CONFIRMATION_EMAIL': True, + # 'SET_PASSWORD_RETYPE': True, + # 'PASSWORD_RESET_SHOW_EMAIL_NOT_FOUND': True, + # 'PASSWORD_RESET_CONFIRM_RETYPE': True, +} + MIDDLEWARE = [ "django.middleware.security.SecurityMiddleware", "django.contrib.sessions.middleware.SessionMiddleware", From f596cea34a1e50cb8b2b4ba0a64e6c4ddbda3ca6 Mon Sep 17 00:00:00 2001 From: Johanan Oppong Amoateng Date: Mon, 17 Jul 2023 23:28:00 +0000 Subject: [PATCH 14/17] celery and tasks --- LibraryApi/tasks.py | 14 ++++++++++++++ LibraryManagementSystem/celery.py | 22 ++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 LibraryApi/tasks.py create mode 100644 LibraryManagementSystem/celery.py diff --git a/LibraryApi/tasks.py b/LibraryApi/tasks.py new file mode 100644 index 0000000..52d7254 --- /dev/null +++ b/LibraryApi/tasks.py @@ -0,0 +1,14 @@ +from celery import shared_task +from .models import Borrowing,Fine +from datetime import datetime + +fine = 0.2 + +@shared_task(name="fine-defaulters") +def fine_defaulters(): + defaulted = Borrowing.objects.filter(returned=False,due_date__lt=datetime.now()) + for i in defaulted: + fine = Fine.objects.get + # if defaulters. + + diff --git a/LibraryManagementSystem/celery.py b/LibraryManagementSystem/celery.py new file mode 100644 index 0000000..07b8bde --- /dev/null +++ b/LibraryManagementSystem/celery.py @@ -0,0 +1,22 @@ +import os + +from celery import Celery + +# Set the default Django settings module for the 'celery' program. +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'LibraryManagementSystem.settings') + +app = Celery('LibraryManagementSystem') + +# Using a string here means the worker doesn't have to serialize +# the configuration object to child processes. +# - namespace='CELERY' means all celery-related configuration keys +# should have a `CELERY_` prefix. +app.config_from_object('django.conf:settings', namespace='CELERY') + +# Load task modules from all registered Django apps. +app.autodiscover_tasks() + + +# @app.task(bind=True, ignore_result=True) +# def debug_task(self): +# print(f'Request: {self.request!r}') \ No newline at end of file From 3aab4df6cc9c063160a075d09c2c72342a552bb1 Mon Sep 17 00:00:00 2001 From: Johanan Oppong Amoateng Date: Mon, 17 Jul 2023 23:28:27 +0000 Subject: [PATCH 15/17] added celery as dependency --- Pipfile | 1 + Pipfile.lock | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 131 insertions(+), 2 deletions(-) diff --git a/Pipfile b/Pipfile index b005a76..2236ca0 100644 --- a/Pipfile +++ b/Pipfile @@ -6,6 +6,7 @@ name = "pypi" [packages] djoser = "*" djangorestframework = "*" +celery = {extras = ["redis"], version = "*"} [dev-packages] diff --git a/Pipfile.lock b/Pipfile.lock index 6532247..bb7a6d4 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "28d4fec85df1853d34f7b1f5fb02f78626485399c3e38629974e2799ff42fc0c" + "sha256": "ba780288d9eb686025fa9f5baf57a96108ba620c2d7152cd858743b7f18b7aae" }, "pipfile-spec": 6, "requires": { @@ -16,6 +16,14 @@ ] }, "default": { + "amqp": { + "hashes": [ + "sha256:2c1b13fecc0893e946c65cbd5f36427861cffa4ea2201d8f6fca22e2a373b5e2", + "sha256:6f0956d2c23d8fa6e7691934d8c3930eadb44972cbbd1a7ae3a520f735d43359" + ], + "markers": "python_version >= '3.6'", + "version": "==5.1.1" + }, "asgiref": { "hashes": [ "sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e", @@ -24,6 +32,33 @@ "markers": "python_version >= '3.7'", "version": "==3.7.2" }, + "async-timeout": { + "hashes": [ + "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15", + "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c" + ], + "markers": "python_full_version <= '3.11.2'", + "version": "==4.0.2" + }, + "billiard": { + "hashes": [ + "sha256:0f50d6be051c6b2b75bfbc8bfd85af195c5739c281d3f5b86a5640c65563614a", + "sha256:1ad2eeae8e28053d729ba3373d34d9d6e210f6e4d8bf0a9c64f92bd053f1edf5" + ], + "markers": "python_version >= '3.7'", + "version": "==4.1.0" + }, + "celery": { + "extras": [ + "redis" + ], + "hashes": [ + "sha256:27f8f3f3b58de6e0ab4f174791383bbd7445aff0471a43e99cfd77727940753f", + "sha256:f84d1c21a1520c116c2b7d26593926581191435a03aa74b77c941b93ca1c6210" + ], + "index": "pypi", + "version": "==5.3.1" + }, "certifi": { "hashes": [ "sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7", @@ -182,6 +217,45 @@ "markers": "python_full_version >= '3.7.0'", "version": "==3.2.0" }, + "click": { + "hashes": [ + "sha256:4be4b1af8d665c6d942909916d31a213a106800c47d0eeba73d34da3cbc11367", + "sha256:e576aa487d679441d7d30abb87e1b43d24fc53bffb8758443b1a9e1cee504548" + ], + "markers": "python_version >= '3.7'", + "version": "==8.1.5" + }, + "click-didyoumean": { + "hashes": [ + "sha256:a0713dc7a1de3f06bc0df5a9567ad19ead2d3d5689b434768a6145bff77c0667", + "sha256:f184f0d851d96b6d29297354ed981b7dd71df7ff500d82fa6d11f0856bee8035" + ], + "markers": "python_full_version >= '3.6.2' and python_full_version < '4.0.0'", + "version": "==0.3.0" + }, + "click-plugins": { + "hashes": [ + "sha256:46ab999744a9d831159c3411bb0c79346d94a444df9a3a3742e9ed63645f264b", + "sha256:5d262006d3222f5057fd81e1623d4443e41dcda5dc815c06b442aa3c02889fc8" + ], + "version": "==1.1.1" + }, + "click-repl": { + "hashes": [ + "sha256:17849c23dba3d667247dc4defe1757fff98694e90fe37474f3feebb69ced26a9", + "sha256:fb7e06deb8da8de86180a33a9da97ac316751c094c6899382da7feeeeb51b812" + ], + "markers": "python_version >= '3.6'", + "version": "==0.3.0" + }, + "colorama": { + "hashes": [ + "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", + "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" + ], + "markers": "platform_system == 'Windows'", + "version": "==0.4.6" + }, "cryptography": { "hashes": [ "sha256:01f1d9e537f9a15b037d5d9ee442b8c22e3ae11ce65ea1f3316a41c78756b711", @@ -266,6 +340,14 @@ "markers": "python_version >= '3.5'", "version": "==3.4" }, + "kombu": { + "hashes": [ + "sha256:48ee589e8833126fd01ceaa08f8a2041334e9f5894e5763c8486a550454551e9", + "sha256:fbd7572d92c0bf71c112a6b45163153dea5a7b6a701ec16b568c27d0fd2370f2" + ], + "markers": "python_version >= '3.8'", + "version": "==5.3.1" + }, "oauthlib": { "hashes": [ "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca", @@ -274,6 +356,14 @@ "markers": "python_version >= '3.6'", "version": "==3.2.2" }, + "prompt-toolkit": { + "hashes": [ + "sha256:04505ade687dc26dc4284b1ad19a83be2f2afe83e7a828ace0c72f3a1df72aac", + "sha256:9dffbe1d8acf91e3de75f3b544e4842382fc06c6babe903ac9acb74dc6e08d88" + ], + "markers": "python_full_version >= '3.7.0'", + "version": "==3.0.39" + }, "pycparser": { "hashes": [ "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9", @@ -289,6 +379,14 @@ "markers": "python_version >= '3.7'", "version": "==2.7.0" }, + "python-dateutil": { + "hashes": [ + "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86", + "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==2.8.2" + }, "python3-openid": { "hashes": [ "sha256:33fbf6928f401e0b790151ed2b5290b02545e8775f982485205a066f874aaeaf", @@ -303,6 +401,13 @@ ], "version": "==2023.3" }, + "redis": { + "hashes": [ + "sha256:585dc516b9eb042a619ef0a39c3d7d55fe81bdb4df09a52c9cdde0d07bf1aa7d", + "sha256:e2b03db868160ee4591de3cb90d40ebb50a90dd302138775937f6a42b7ed183c" + ], + "version": "==4.6.0" + }, "requests": { "hashes": [ "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f", @@ -319,6 +424,14 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.3.1" }, + "six": { + "hashes": [ + "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", + "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.16.0" + }, "social-auth-app-django": { "hashes": [ "sha256:0347ca4cd23ea9d15a665da9d22950552fb66b95600e6c2ebae38ca883b3a4ed", @@ -348,7 +461,7 @@ "sha256:11ef1e08e54acb0d4f95bdb1be05da659673de4acbd21bf9c69e94cc5e907a3a", "sha256:7e65763eef3120314099b6939b5546db7adce1e7d6f2e179e3df563c70511eda" ], - "markers": "sys_platform == 'win32'", + "markers": "python_version >= '2'", "version": "==2023.3" }, "urllib3": { @@ -358,6 +471,21 @@ ], "markers": "python_version >= '3.7'", "version": "==2.0.3" + }, + "vine": { + "hashes": [ + "sha256:4c9dceab6f76ed92105027c49c823800dd33cacce13bdedc5b914e3514b7fb30", + "sha256:7d3b1624a953da82ef63462013bbd271d3eb75751489f9807598e8f340bd637e" + ], + "markers": "python_version >= '3.6'", + "version": "==5.0.0" + }, + "wcwidth": { + "hashes": [ + "sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e", + "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0" + ], + "version": "==0.2.6" } }, "develop": {} From 5e477a40380d9bf28f2204695fcbdc298fdbc2c6 Mon Sep 17 00:00:00 2001 From: Johanan Oppong Amoateng Date: Mon, 17 Jul 2023 23:28:40 +0000 Subject: [PATCH 16/17] updated gitignore file --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a043ce0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +db.sqlite3 +__pycache__/ \ No newline at end of file From fce1d7bc50a2a1d630e69657f66e69b588005a9c Mon Sep 17 00:00:00 2001 From: Johanan Oppong Amoateng Date: Mon, 17 Jul 2023 23:30:33 +0000 Subject: [PATCH 17/17] updated readme --- README.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1eadcf7..47386d0 100644 --- a/README.md +++ b/README.md @@ -1 +1,14 @@ -# Library-Management-System \ No newline at end of file +# Library-Management-System +A library management system is designed to efficiently manage the operations and resources of a library. Here are some common features found in library management systems: + +1. Catalog Management: Maintain a centralized catalog of books, periodicals, media, and other library materials. This includes features for adding, editing, and deleting items from the catalog, as well as searching and browsing capabilities for users. + +2. User Management: Manage user accounts and profiles, including registration, authentication, and user roles (e.g., students, faculty, staff). Users may be able to view their borrowing history, manage their personal information, and place holds or requests for materials. + +3. Circulation and Borrowing: Facilitate the borrowing and lending process, including check-in and check-out of library materials. This feature may include due date management, loan renewals, holds, and notifications for overdue items. + +4. Reservation and Request Management: Enable users to reserve or request items that are currently unavailable or in high demand. Users can be notified when the requested items become available. + +5. Fine and Fee Management: Track and manage fines, fees, and penalties for overdue materials, lost items, or other library-related charges. Provide an interface for users to view and pay fines online. + +6. Catalog Search and Discovery: Provide a user-friendly search interface for users to find and discover library materials based on title, author, subject, ISBN, or other criteria. Implement advanced search options, filters, and sorting capabilities.