Merge pull request #10 from lemeow125/feature/auth

Feature/auth
This commit is contained in:
Keannu Bernasol 2023-11-12 21:47:24 +08:00 committed by GitHub
commit 31b9778d40
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
40 changed files with 1873 additions and 129 deletions

View file

@ -10,6 +10,11 @@ python-dotenv = "*"
whitenoise = "*" whitenoise = "*"
djoser = "*" djoser = "*"
django-cors-headers = "*" django-cors-headers = "*"
drf-spectacular = {version = "*", extras = ["sidecar"]}
django-extra-fields = "*"
pillow = "*"
psycopg2 = "*"
django-simple-history = "*"
[dev-packages] [dev-packages]

573
Pipfile.lock generated
View file

@ -1,7 +1,7 @@
{ {
"_meta": { "_meta": {
"hash": { "hash": {
"sha256": "78c49b7899d981508de476af5e9aa819ee18a8c6ecaa040961788004559f5cac" "sha256": "ebe508cba3dbd2fa271c39d69ab71cb95f5630e21875aea04ad9f6893ced1877"
}, },
"pipfile-spec": 6, "pipfile-spec": 6,
"requires": { "requires": {
@ -24,6 +24,14 @@
"markers": "python_version >= '3.7'", "markers": "python_version >= '3.7'",
"version": "==3.7.2" "version": "==3.7.2"
}, },
"attrs": {
"hashes": [
"sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04",
"sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"
],
"markers": "python_version >= '3.7'",
"version": "==23.1.0"
},
"certifi": { "certifi": {
"hashes": [ "hashes": [
"sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082", "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082",
@ -92,128 +100,128 @@
}, },
"charset-normalizer": { "charset-normalizer": {
"hashes": [ "hashes": [
"sha256:06cf46bdff72f58645434d467bf5228080801298fbba19fe268a01b4534467f5", "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027",
"sha256:0c8c61fb505c7dad1d251c284e712d4e0372cef3b067f7ddf82a7fa82e1e9a93", "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087",
"sha256:10b8dd31e10f32410751b3430996f9807fc4d1587ca69772e2aa940a82ab571a", "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786",
"sha256:1171ef1fc5ab4693c5d151ae0fdad7f7349920eabbaca6271f95969fa0756c2d", "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8",
"sha256:17a866d61259c7de1bdadef418a37755050ddb4b922df8b356503234fff7932c", "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09",
"sha256:1d6bfc32a68bc0933819cfdfe45f9abc3cae3877e1d90aac7259d57e6e0f85b1", "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185",
"sha256:1ec937546cad86d0dce5396748bf392bb7b62a9eeb8c66efac60e947697f0e58", "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574",
"sha256:223b4d54561c01048f657fa6ce41461d5ad8ff128b9678cfe8b2ecd951e3f8a2", "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e",
"sha256:2465aa50c9299d615d757c1c888bc6fef384b7c4aec81c05a0172b4400f98557", "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519",
"sha256:28f512b9a33235545fbbdac6a330a510b63be278a50071a336afc1b78781b147", "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898",
"sha256:2c092be3885a1b7899cd85ce24acedc1034199d6fca1483fa2c3a35c86e43041", "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269",
"sha256:2c4c99f98fc3a1835af8179dcc9013f93594d0670e2fa80c83aa36346ee763d2", "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3",
"sha256:31445f38053476a0c4e6d12b047b08ced81e2c7c712e5a1ad97bc913256f91b2", "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f",
"sha256:31bbaba7218904d2eabecf4feec0d07469284e952a27400f23b6628439439fa7", "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6",
"sha256:34d95638ff3613849f473afc33f65c401a89f3b9528d0d213c7037c398a51296", "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8",
"sha256:352a88c3df0d1fa886562384b86f9a9e27563d4704ee0e9d56ec6fcd270ea690", "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a",
"sha256:39b70a6f88eebe239fa775190796d55a33cfb6d36b9ffdd37843f7c4c1b5dc67", "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73",
"sha256:3c66df3f41abee950d6638adc7eac4730a306b022570f71dd0bd6ba53503ab57", "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc",
"sha256:3f70fd716855cd3b855316b226a1ac8bdb3caf4f7ea96edcccc6f484217c9597", "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714",
"sha256:3f9bc2ce123637a60ebe819f9fccc614da1bcc05798bbbaf2dd4ec91f3e08846", "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2",
"sha256:3fb765362688821404ad6cf86772fc54993ec11577cd5a92ac44b4c2ba52155b", "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc",
"sha256:45f053a0ece92c734d874861ffe6e3cc92150e32136dd59ab1fb070575189c97", "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce",
"sha256:46fb9970aa5eeca547d7aa0de5d4b124a288b42eaefac677bde805013c95725c", "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d",
"sha256:4cb50a0335382aac15c31b61d8531bc9bb657cfd848b1d7158009472189f3d62", "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e",
"sha256:4e12f8ee80aa35e746230a2af83e81bd6b52daa92a8afaef4fea4a2ce9b9f4fa", "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6",
"sha256:4f3100d86dcd03c03f7e9c3fdb23d92e32abbca07e7c13ebd7ddfbcb06f5991f", "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269",
"sha256:4f6e2a839f83a6a76854d12dbebde50e4b1afa63e27761549d006fa53e9aa80e", "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96",
"sha256:4f861d94c2a450b974b86093c6c027888627b8082f1299dfd5a4bae8e2292821", "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d",
"sha256:501adc5eb6cd5f40a6f77fbd90e5ab915c8fd6e8c614af2db5561e16c600d6f3", "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a",
"sha256:520b7a142d2524f999447b3a0cf95115df81c4f33003c51a6ab637cbda9d0bf4", "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4",
"sha256:548eefad783ed787b38cb6f9a574bd8664468cc76d1538215d510a3cd41406cb", "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77",
"sha256:555fe186da0068d3354cdf4bbcbc609b0ecae4d04c921cc13e209eece7720727", "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d",
"sha256:55602981b2dbf8184c098bc10287e8c245e351cd4fdcad050bd7199d5a8bf514", "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0",
"sha256:58e875eb7016fd014c0eea46c6fa92b87b62c0cb31b9feae25cbbe62c919f54d", "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed",
"sha256:5a3580a4fdc4ac05f9e53c57f965e3594b2f99796231380adb2baaab96e22761", "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068",
"sha256:5b70bab78accbc672f50e878a5b73ca692f45f5b5e25c8066d748c09405e6a55", "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac",
"sha256:5ceca5876032362ae73b83347be8b5dbd2d1faf3358deb38c9c88776779b2e2f", "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25",
"sha256:61f1e3fb621f5420523abb71f5771a204b33c21d31e7d9d86881b2cffe92c47c", "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8",
"sha256:633968254f8d421e70f91c6ebe71ed0ab140220469cf87a9857e21c16687c034", "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab",
"sha256:63a6f59e2d01310f754c270e4a257426fe5a591dc487f1983b3bbe793cf6bac6", "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26",
"sha256:63accd11149c0f9a99e3bc095bbdb5a464862d77a7e309ad5938fbc8721235ae", "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2",
"sha256:6db3cfb9b4fcecb4390db154e75b49578c87a3b9979b40cdf90d7e4b945656e1", "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db",
"sha256:71ef3b9be10070360f289aea4838c784f8b851be3ba58cf796262b57775c2f14", "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f",
"sha256:7ae8e5142dcc7a49168f4055255dbcced01dc1714a90a21f87448dc8d90617d1", "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5",
"sha256:7b6cefa579e1237ce198619b76eaa148b71894fb0d6bcf9024460f9bf30fd228", "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99",
"sha256:800561453acdecedaac137bf09cd719c7a440b6800ec182f077bb8e7025fb708", "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c",
"sha256:82ca51ff0fc5b641a2d4e1cc8c5ff108699b7a56d7f3ad6f6da9dbb6f0145b48", "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d",
"sha256:851cf693fb3aaef71031237cd68699dded198657ec1e76a76eb8be58c03a5d1f", "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811",
"sha256:854cc74367180beb327ab9d00f964f6d91da06450b0855cbbb09187bcdb02de5", "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa",
"sha256:87071618d3d8ec8b186d53cb6e66955ef2a0e4fa63ccd3709c0c90ac5a43520f", "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a",
"sha256:871d045d6ccc181fd863a3cd66ee8e395523ebfbc57f85f91f035f50cee8e3d4", "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03",
"sha256:8aee051c89e13565c6bd366813c386939f8e928af93c29fda4af86d25b73d8f8", "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b",
"sha256:8af5a8917b8af42295e86b64903156b4f110a30dca5f3b5aedea123fbd638bff", "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04",
"sha256:8ec8ef42c6cd5856a7613dcd1eaf21e5573b2185263d87d27c8edcae33b62a61", "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c",
"sha256:91e43805ccafa0a91831f9cd5443aa34528c0c3f2cc48c4cb3d9a7721053874b", "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001",
"sha256:9505dc359edb6a330efcd2be825fdb73ee3e628d9010597aa1aee5aa63442e97", "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458",
"sha256:985c7965f62f6f32bf432e2681173db41336a9c2611693247069288bcb0c7f8b", "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389",
"sha256:9a74041ba0bfa9bc9b9bb2cd3238a6ab3b7618e759b41bd15b5f6ad958d17605", "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99",
"sha256:9edbe6a5bf8b56a4a84533ba2b2f489d0046e755c29616ef8830f9e7d9cf5728", "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985",
"sha256:a15c1fe6d26e83fd2e5972425a772cca158eae58b05d4a25a4e474c221053e2d", "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537",
"sha256:a66bcdf19c1a523e41b8e9d53d0cedbfbac2e93c649a2e9502cb26c014d0980c", "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238",
"sha256:ae4070f741f8d809075ef697877fd350ecf0b7c5837ed68738607ee0a2c572cf", "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f",
"sha256:ae55d592b02c4349525b6ed8f74c692509e5adffa842e582c0f861751701a673", "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d",
"sha256:b578cbe580e3b41ad17b1c428f382c814b32a6ce90f2d8e39e2e635d49e498d1", "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796",
"sha256:b891a2f68e09c5ef989007fac11476ed33c5c9994449a4e2c3386529d703dc8b", "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a",
"sha256:baec8148d6b8bd5cee1ae138ba658c71f5b03e0d69d5907703e3e1df96db5e41", "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143",
"sha256:bb06098d019766ca16fc915ecaa455c1f1cd594204e7f840cd6258237b5079a8", "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8",
"sha256:bc791ec3fd0c4309a753f95bb6c749ef0d8ea3aea91f07ee1cf06b7b02118f2f", "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c",
"sha256:bd28b31730f0e982ace8663d108e01199098432a30a4c410d06fe08fdb9e93f4", "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5",
"sha256:be4d9c2770044a59715eb57c1144dedea7c5d5ae80c68fb9959515037cde2008", "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5",
"sha256:c0c72d34e7de5604df0fde3644cc079feee5e55464967d10b24b1de268deceb9", "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711",
"sha256:c0e842112fe3f1a4ffcf64b06dc4c61a88441c2f02f373367f7b4c1aa9be2ad5", "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4",
"sha256:c15070ebf11b8b7fd1bfff7217e9324963c82dbdf6182ff7050519e350e7ad9f", "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6",
"sha256:c2000c54c395d9e5e44c99dc7c20a64dc371f777faf8bae4919ad3e99ce5253e", "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c",
"sha256:c30187840d36d0ba2893bc3271a36a517a717f9fd383a98e2697ee890a37c273", "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7",
"sha256:cb7cd68814308aade9d0c93c5bd2ade9f9441666f8ba5aa9c2d4b389cb5e2a45", "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4",
"sha256:cd805513198304026bd379d1d516afbf6c3c13f4382134a2c526b8b854da1c2e", "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b",
"sha256:d0bf89afcbcf4d1bb2652f6580e5e55a840fdf87384f6063c4a4f0c95e378656", "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae",
"sha256:d9137a876020661972ca6eec0766d81aef8a5627df628b664b234b73396e727e", "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12",
"sha256:dbd95e300367aa0827496fe75a1766d198d34385a58f97683fe6e07f89ca3e3c", "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c",
"sha256:dced27917823df984fe0c80a5c4ad75cf58df0fbfae890bc08004cd3888922a2", "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae",
"sha256:de0b4caa1c8a21394e8ce971997614a17648f94e1cd0640fbd6b4d14cab13a72", "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8",
"sha256:debb633f3f7856f95ad957d9b9c781f8e2c6303ef21724ec94bea2ce2fcbd056", "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887",
"sha256:e372d7dfd154009142631de2d316adad3cc1c36c32a38b16a4751ba78da2a397", "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b",
"sha256:ecd26be9f112c4f96718290c10f4caea6cc798459a3a76636b817a0ed7874e42", "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4",
"sha256:edc0202099ea1d82844316604e17d2b175044f9bcb6b398aab781eba957224bd", "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f",
"sha256:f194cce575e59ffe442c10a360182a986535fd90b57f7debfaa5c845c409ecc3", "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5",
"sha256:f5fb672c396d826ca16a022ac04c9dce74e00a1c344f6ad1a0fdc1ba1f332213", "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33",
"sha256:f6a02a3c7950cafaadcd46a226ad9e12fc9744652cc69f9e5534f98b47f3bbcf", "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519",
"sha256:fe81b35c33772e56f4b6cf62cf4aedc1762ef7162a31e6ac7fe5e40d0149eb67" "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"
], ],
"markers": "python_full_version >= '3.7.0'", "markers": "python_full_version >= '3.7.0'",
"version": "==3.3.1" "version": "==3.3.2"
}, },
"cryptography": { "cryptography": {
"hashes": [ "hashes": [
"sha256:004b6ccc95943f6a9ad3142cfabcc769d7ee38a3f60fb0dddbfb431f818c3a67", "sha256:0c327cac00f082013c7c9fb6c46b7cc9fa3c288ca702c74773968173bda421bf",
"sha256:047c4603aeb4bbd8db2756e38f5b8bd7e94318c047cfe4efeb5d715e08b49311", "sha256:0d2a6a598847c46e3e321a7aef8af1436f11c27f1254933746304ff014664d84",
"sha256:0d9409894f495d465fe6fda92cb70e8323e9648af912d5b9141d616df40a87b8", "sha256:227ec057cd32a41c6651701abc0328135e472ed450f47c2766f23267b792a88e",
"sha256:23a25c09dfd0d9f28da2352503b23e086f8e78096b9fd585d1d14eca01613e13", "sha256:22892cc830d8b2c89ea60148227631bb96a7da0c1b722f2aac8824b1b7c0b6b8",
"sha256:2ed09183922d66c4ec5fdaa59b4d14e105c084dd0febd27452de8f6f74704143", "sha256:392cb88b597247177172e02da6b7a63deeff1937fa6fec3bbf902ebd75d97ec7",
"sha256:35c00f637cd0b9d5b6c6bd11b6c3359194a8eba9c46d4e875a3660e3b400005f", "sha256:3be3ca726e1572517d2bef99a818378bbcf7d7799d5372a46c79c29eb8d166c1",
"sha256:37480760ae08065437e6573d14be973112c9e6dcaf5f11d00147ee74f37a3829", "sha256:573eb7128cbca75f9157dcde974781209463ce56b5804983e11a1c462f0f4e88",
"sha256:3b224890962a2d7b57cf5eeb16ccaafba6083f7b811829f00476309bce2fe0fd", "sha256:580afc7b7216deeb87a098ef0674d6ee34ab55993140838b14c9b83312b37b86",
"sha256:5a0f09cefded00e648a127048119f77bc2b2ec61e736660b5789e638f43cc397", "sha256:5a70187954ba7292c7876734183e810b728b4f3965fbe571421cb2434d279179",
"sha256:5b72205a360f3b6176485a333256b9bcd48700fc755fef51c8e7e67c4b63e3ac", "sha256:73801ac9736741f220e20435f84ecec75ed70eda90f781a148f1bad546963d81",
"sha256:7e53db173370dea832190870e975a1e09c86a879b613948f09eb49324218c14d", "sha256:7d208c21e47940369accfc9e85f0de7693d9a5d843c2509b3846b2db170dfd20",
"sha256:7febc3094125fc126a7f6fb1f420d0da639f3f32cb15c8ff0dc3997c4549f51a", "sha256:8254962e6ba1f4d2090c44daf50a547cd5f0bf446dc658a8e5f8156cae0d8548",
"sha256:80907d3faa55dc5434a16579952ac6da800935cd98d14dbd62f6f042c7f5e839", "sha256:88417bff20162f635f24f849ab182b092697922088b477a7abd6664ddd82291d",
"sha256:86defa8d248c3fa029da68ce61fe735432b047e32179883bdb1e79ed9bb8195e", "sha256:a48e74dad1fb349f3dc1d449ed88e0017d792997a7ad2ec9587ed17405667e6d",
"sha256:8ac4f9ead4bbd0bc8ab2d318f97d85147167a488be0e08814a37eb2f439d5cf6", "sha256:b948e09fe5fb18517d99994184854ebd50b57248736fd4c720ad540560174ec5",
"sha256:93530900d14c37a46ce3d6c9e6fd35dbe5f5601bf6b3a5c325c7bffc030344d9", "sha256:c707f7afd813478e2019ae32a7c49cd932dd60ab2d2a93e796f68236b7e1fbf1",
"sha256:9eeb77214afae972a00dee47382d2591abe77bdae166bda672fb1e24702a3860", "sha256:d38e6031e113b7421db1de0c1b1f7739564a88f1684c6b89234fbf6c11b75147",
"sha256:b5f4dfe950ff0479f1f00eda09c18798d4f49b98f4e2006d644b3301682ebdca", "sha256:d3977f0e276f6f5bf245c403156673db103283266601405376f075c849a0b936",
"sha256:c3391bd8e6de35f6f1140e50aaeb3e2b3d6a9012536ca23ab0d9c35ec18c8a91", "sha256:da6a0ff8f1016ccc7477e6339e1d50ce5f59b88905585f77193ebd5068f1e797",
"sha256:c880eba5175f4307129784eca96f4e70b88e57aa3f680aeba3bab0e980b0f37d", "sha256:e270c04f4d9b5671ebcc792b3ba5d4488bf7c42c3c241a3748e2599776f29696",
"sha256:cecfefa17042941f94ab54f769c8ce0fe14beff2694e9ac684176a2535bf9714", "sha256:e886098619d3815e0ad5790c973afeee2c0e6e04b4da90b88e6bd06e2a0b1b72",
"sha256:e40211b4923ba5a6dc9769eab704bdb3fbb58d56c5b336d30996c24fcf12aadb", "sha256:ec3b055ff8f1dce8e6ef28f626e0972981475173d7973d63f271b29c8a2897da",
"sha256:efc8ad4e6fc4f1752ebfb58aefece8b4e3c4cae940b0994d43649bdfce8d0d4f" "sha256:fba1e91467c65fe64a82c689dc6cf58151158993b13eb7a7f3f4b7f395636723"
], ],
"markers": "python_version >= '3.7'", "markers": "python_version >= '3.7'",
"version": "==41.0.4" "version": "==41.0.5"
}, },
"defusedxml": { "defusedxml": {
"hashes": [ "hashes": [
@ -225,11 +233,11 @@
}, },
"django": { "django": {
"hashes": [ "hashes": [
"sha256:08f41f468b63335aea0d904c5729e0250300f6a1907bf293a65499496cdbc68f", "sha256:8e0f1c2c2786b5c0e39fe1afce24c926040fad47c8ea8ad30aaf1188df29fc41",
"sha256:a64d2487cdb00ad7461434320ccc38e60af9c404773a2f95ab0093b4453a3215" "sha256:e1d37c51ad26186de355cbcec16613ebdabfa9689bbade9c538835205a8abbe9"
], ],
"index": "pypi", "index": "pypi",
"version": "==4.2.6" "version": "==4.2.7"
}, },
"django-cors-headers": { "django-cors-headers": {
"hashes": [ "hashes": [
@ -239,6 +247,21 @@
"index": "pypi", "index": "pypi",
"version": "==4.3.0" "version": "==4.3.0"
}, },
"django-extra-fields": {
"hashes": [
"sha256:2334e914b346c0a19a7765bf0ff7895c46cf35d5f40315a68418f44b7ddbb33b"
],
"index": "pypi",
"version": "==3.0.2"
},
"django-simple-history": {
"hashes": [
"sha256:19bd1a87e1e2eba34dfd43eab1fcf2da5752221f343232f2372b2121c7e3b97d",
"sha256:992dcca3cddc0b67b470fc91f77292e2d2a6010d37c9eac3536e9d80e8754032"
],
"index": "pypi",
"version": "==3.4.0"
},
"django-templated-mail": { "django-templated-mail": {
"hashes": [ "hashes": [
"sha256:8db807effebb42a532622e2d142dfd453dafcd0d7794c4c3332acb90656315f9", "sha256:8db807effebb42a532622e2d142dfd453dafcd0d7794c4c3332acb90656315f9",
@ -264,11 +287,29 @@
}, },
"djoser": { "djoser": {
"hashes": [ "hashes": [
"sha256:4aa48502df870c8b5f07109ad4a749cc881c37bb5efa85cf5462ea695a0dca8c", "sha256:9deb831a1c8781ceff325699e1407b4e1be8b4588e87071621d88ba31c09349f",
"sha256:7b24718cdc51b4294b0abcf6bf0ead11aa3ca83652e351dfb04b7b8b15afa3b0" "sha256:efb91ad61e4d5b8d664db029b5947df9d34078289ef2680a1ab665e047144b74"
], ],
"index": "pypi", "index": "pypi",
"version": "==2.2.0" "version": "==2.2.2"
},
"drf-spectacular": {
"extras": [
"sidecar"
],
"hashes": [
"sha256:aee55330a774ba8a9cbdb125714d1c9ee05a8aafd3ce3be8bfd26527649aeb44",
"sha256:c0002a820b11771fdbf37853deb371947caf0159d1afeeffe7598e964bc1db94"
],
"index": "pypi",
"version": "==0.26.5"
},
"drf-spectacular-sidecar": {
"hashes": [
"sha256:3d042a6772512f4d238f0385d3430acf5f669f595fd0be2641fe6bbfb4c7b376",
"sha256:546a83c173589715e530fad211af60cbcda2db54eb9e0935d44251639332af6d"
],
"version": "==2023.10.1"
}, },
"idna": { "idna": {
"hashes": [ "hashes": [
@ -278,6 +319,30 @@
"markers": "python_version >= '3.5'", "markers": "python_version >= '3.5'",
"version": "==3.4" "version": "==3.4"
}, },
"inflection": {
"hashes": [
"sha256:1a29730d366e996aaacffb2f1f1cb9593dc38e2ddd30c91250c6dde09ea9b417",
"sha256:f38b2b640938a4f35ade69ac3d053042959b62a0f1076a5bbaa1b9526605a8a2"
],
"markers": "python_version >= '3.5'",
"version": "==0.5.1"
},
"jsonschema": {
"hashes": [
"sha256:c9ff4d7447eed9592c23a12ccee508baf0dd0d59650615e847feb6cdca74f392",
"sha256:eee9e502c788e89cb166d4d37f43084e3b64ab405c795c03d343a4dbc2c810fc"
],
"markers": "python_version >= '3.8'",
"version": "==4.19.2"
},
"jsonschema-specifications": {
"hashes": [
"sha256:05adf340b659828a004220a9613be00fa3f223f2b82002e273dee62fd50524b1",
"sha256:c91a50404e88a1f6ba40636778e2ee08f6e24c5613fe4c53ac24578a5a7f72bb"
],
"markers": "python_version >= '3.8'",
"version": "==2023.7.1"
},
"oauthlib": { "oauthlib": {
"hashes": [ "hashes": [
"sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca", "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca",
@ -286,6 +351,85 @@
"markers": "python_version >= '3.6'", "markers": "python_version >= '3.6'",
"version": "==3.2.2" "version": "==3.2.2"
}, },
"pillow": {
"hashes": [
"sha256:00f438bb841382b15d7deb9a05cc946ee0f2c352653c7aa659e75e592f6fa17d",
"sha256:0248f86b3ea061e67817c47ecbe82c23f9dd5d5226200eb9090b3873d3ca32de",
"sha256:04f6f6149f266a100374ca3cc368b67fb27c4af9f1cc8cb6306d849dcdf12616",
"sha256:062a1610e3bc258bff2328ec43f34244fcec972ee0717200cb1425214fe5b839",
"sha256:0a026c188be3b443916179f5d04548092e253beb0c3e2ee0a4e2cdad72f66099",
"sha256:0f7c276c05a9767e877a0b4c5050c8bee6a6d960d7f0c11ebda6b99746068c2a",
"sha256:1a8413794b4ad9719346cd9306118450b7b00d9a15846451549314a58ac42219",
"sha256:1ab05f3db77e98f93964697c8efc49c7954b08dd61cff526b7f2531a22410106",
"sha256:1c3ac5423c8c1da5928aa12c6e258921956757d976405e9467c5f39d1d577a4b",
"sha256:1c41d960babf951e01a49c9746f92c5a7e0d939d1652d7ba30f6b3090f27e412",
"sha256:1fafabe50a6977ac70dfe829b2d5735fd54e190ab55259ec8aea4aaea412fa0b",
"sha256:1fb29c07478e6c06a46b867e43b0bcdb241b44cc52be9bc25ce5944eed4648e7",
"sha256:24fadc71218ad2b8ffe437b54876c9382b4a29e030a05a9879f615091f42ffc2",
"sha256:2cdc65a46e74514ce742c2013cd4a2d12e8553e3a2563c64879f7c7e4d28bce7",
"sha256:2ef6721c97894a7aa77723740a09547197533146fba8355e86d6d9a4a1056b14",
"sha256:3b834f4b16173e5b92ab6566f0473bfb09f939ba14b23b8da1f54fa63e4b623f",
"sha256:3d929a19f5469b3f4df33a3df2983db070ebb2088a1e145e18facbc28cae5b27",
"sha256:41f67248d92a5e0a2076d3517d8d4b1e41a97e2df10eb8f93106c89107f38b57",
"sha256:47e5bf85b80abc03be7455c95b6d6e4896a62f6541c1f2ce77a7d2bb832af262",
"sha256:4d0152565c6aa6ebbfb1e5d8624140a440f2b99bf7afaafbdbf6430426497f28",
"sha256:50d08cd0a2ecd2a8657bd3d82c71efd5a58edb04d9308185d66c3a5a5bed9610",
"sha256:61f1a9d247317fa08a308daaa8ee7b3f760ab1809ca2da14ecc88ae4257d6172",
"sha256:6932a7652464746fcb484f7fc3618e6503d2066d853f68a4bd97193a3996e273",
"sha256:7a7e3daa202beb61821c06d2517428e8e7c1aab08943e92ec9e5755c2fc9ba5e",
"sha256:7dbaa3c7de82ef37e7708521be41db5565004258ca76945ad74a8e998c30af8d",
"sha256:7df5608bc38bd37ef585ae9c38c9cd46d7c81498f086915b0f97255ea60c2818",
"sha256:806abdd8249ba3953c33742506fe414880bad78ac25cc9a9b1c6ae97bedd573f",
"sha256:883f216eac8712b83a63f41b76ddfb7b2afab1b74abbb413c5df6680f071a6b9",
"sha256:912e3812a1dbbc834da2b32299b124b5ddcb664ed354916fd1ed6f193f0e2d01",
"sha256:937bdc5a7f5343d1c97dc98149a0be7eb9704e937fe3dc7140e229ae4fc572a7",
"sha256:9882a7451c680c12f232a422730f986a1fcd808da0fd428f08b671237237d651",
"sha256:9a92109192b360634a4489c0c756364c0c3a2992906752165ecb50544c251312",
"sha256:9d7bc666bd8c5a4225e7ac71f2f9d12466ec555e89092728ea0f5c0c2422ea80",
"sha256:a5f63b5a68daedc54c7c3464508d8c12075e56dcfbd42f8c1bf40169061ae666",
"sha256:a646e48de237d860c36e0db37ecaecaa3619e6f3e9d5319e527ccbc8151df061",
"sha256:a89b8312d51715b510a4fe9fc13686283f376cfd5abca8cd1c65e4c76e21081b",
"sha256:a92386125e9ee90381c3369f57a2a50fa9e6aa8b1cf1d9c4b200d41a7dd8e992",
"sha256:ae88931f93214777c7a3aa0a8f92a683f83ecde27f65a45f95f22d289a69e593",
"sha256:afc8eef765d948543a4775f00b7b8c079b3321d6b675dde0d02afa2ee23000b4",
"sha256:b0eb01ca85b2361b09480784a7931fc648ed8b7836f01fb9241141b968feb1db",
"sha256:b1c25762197144e211efb5f4e8ad656f36c8d214d390585d1d21281f46d556ba",
"sha256:b4005fee46ed9be0b8fb42be0c20e79411533d1fd58edabebc0dd24626882cfd",
"sha256:b920e4d028f6442bea9a75b7491c063f0b9a3972520731ed26c83e254302eb1e",
"sha256:baada14941c83079bf84c037e2d8b7506ce201e92e3d2fa0d1303507a8538212",
"sha256:bb40c011447712d2e19cc261c82655f75f32cb724788df315ed992a4d65696bb",
"sha256:c0949b55eb607898e28eaccb525ab104b2d86542a85c74baf3a6dc24002edec2",
"sha256:c9aeea7b63edb7884b031a35305629a7593272b54f429a9869a4f63a1bf04c34",
"sha256:cfe96560c6ce2f4c07d6647af2d0f3c54cc33289894ebd88cfbb3bcd5391e256",
"sha256:d27b5997bdd2eb9fb199982bb7eb6164db0426904020dc38c10203187ae2ff2f",
"sha256:d921bc90b1defa55c9917ca6b6b71430e4286fc9e44c55ead78ca1a9f9eba5f2",
"sha256:e6bf8de6c36ed96c86ea3b6e1d5273c53f46ef518a062464cd7ef5dd2cf92e38",
"sha256:eaed6977fa73408b7b8a24e8b14e59e1668cfc0f4c40193ea7ced8e210adf996",
"sha256:fa1d323703cfdac2036af05191b969b910d8f115cf53093125e4058f62012c9a",
"sha256:fe1e26e1ffc38be097f0ba1d0d07fcade2bcfd1d023cda5b29935ae8052bd793"
],
"index": "pypi",
"version": "==10.1.0"
},
"psycopg2": {
"hashes": [
"sha256:121081ea2e76729acfb0673ff33755e8703d45e926e416cb59bae3a86c6a4981",
"sha256:38a8dcc6856f569068b47de286b472b7c473ac7977243593a288ebce0dc89516",
"sha256:426f9f29bde126913a20a96ff8ce7d73fd8a216cfb323b1f04da402d452853c3",
"sha256:5e0d98cade4f0e0304d7d6f25bbfbc5bd186e07b38eac65379309c4ca3193efa",
"sha256:7e2dacf8b009a1c1e843b5213a87f7c544b2b042476ed7755be813eaf4e8347a",
"sha256:a7653d00b732afb6fc597e29c50ad28087dcb4fbfb28e86092277a559ae4e693",
"sha256:ade01303ccf7ae12c356a5e10911c9e1c51136003a9a1d92f7aa9d010fb98372",
"sha256:bac58c024c9922c23550af2a581998624d6e02350f4ae9c5f0bc642c633a2d5e",
"sha256:c92811b2d4c9b6ea0285942b2e7cac98a59e166d59c588fe5cfe1eda58e72d59",
"sha256:d1454bde93fb1e224166811694d600e746430c006fbb031ea06ecc2ea41bf156",
"sha256:d735786acc7dd25815e89cc4ad529a43af779db2e25aa7c626de864127e5a024",
"sha256:de80739447af31525feddeb8effd640782cf5998e1a4e9192ebdf829717e3913",
"sha256:ff432630e510709564c01dafdbe996cb552e0b9f3f065eb89bdce5bd31fabf4c"
],
"index": "pypi",
"version": "==2.9.9"
},
"pycparser": { "pycparser": {
"hashes": [ "hashes": [
"sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9", "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9",
@ -323,6 +467,70 @@
], ],
"version": "==2023.3.post1" "version": "==2023.3.post1"
}, },
"pyyaml": {
"hashes": [
"sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5",
"sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc",
"sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df",
"sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741",
"sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206",
"sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27",
"sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595",
"sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62",
"sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98",
"sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696",
"sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290",
"sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9",
"sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d",
"sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6",
"sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867",
"sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47",
"sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486",
"sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6",
"sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3",
"sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007",
"sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938",
"sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0",
"sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c",
"sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735",
"sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d",
"sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28",
"sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4",
"sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba",
"sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8",
"sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5",
"sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd",
"sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3",
"sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0",
"sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515",
"sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c",
"sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c",
"sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924",
"sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34",
"sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43",
"sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859",
"sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673",
"sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54",
"sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a",
"sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b",
"sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab",
"sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa",
"sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c",
"sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585",
"sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d",
"sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"
],
"markers": "python_version >= '3.6'",
"version": "==6.0.1"
},
"referencing": {
"hashes": [
"sha256:449b6669b6121a9e96a7f9e410b245d471e8d48964c67113ce9afe50c8dd7bdf",
"sha256:794ad8003c65938edcdbc027f1933215e0d0ccc0291e3ce20a4d87432b59efc0"
],
"markers": "python_version >= '3.8'",
"version": "==0.30.2"
},
"requests": { "requests": {
"hashes": [ "hashes": [
"sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f", "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f",
@ -339,6 +547,111 @@
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==1.3.1" "version": "==1.3.1"
}, },
"rpds-py": {
"hashes": [
"sha256:0525847f83f506aa1e28eb2057b696fe38217e12931c8b1b02198cfe6975e142",
"sha256:05942656cb2cb4989cd50ced52df16be94d344eae5097e8583966a1d27da73a5",
"sha256:0831d3ecdea22e4559cc1793f22e77067c9d8c451d55ae6a75bf1d116a8e7f42",
"sha256:0853da3d5e9bc6a07b2486054a410b7b03f34046c123c6561b535bb48cc509e1",
"sha256:08e6e7ff286254016b945e1ab632ee843e43d45e40683b66dd12b73791366dd1",
"sha256:0a38612d07a36138507d69646c470aedbfe2b75b43a4643f7bd8e51e52779624",
"sha256:0bedd91ae1dd142a4dc15970ed2c729ff6c73f33a40fa84ed0cdbf55de87c777",
"sha256:0c5441b7626c29dbd54a3f6f3713ec8e956b009f419ffdaaa3c80eaf98ddb523",
"sha256:0e9e976e0dbed4f51c56db10831c9623d0fd67aac02853fe5476262e5a22acb7",
"sha256:0fadfdda275c838cba5102c7f90a20f2abd7727bf8f4a2b654a5b617529c5c18",
"sha256:1096ca0bf2d3426cbe79d4ccc91dc5aaa73629b08ea2d8467375fad8447ce11a",
"sha256:171d9a159f1b2f42a42a64a985e4ba46fc7268c78299272ceba970743a67ee50",
"sha256:188912b22b6c8225f4c4ffa020a2baa6ad8fabb3c141a12dbe6edbb34e7f1425",
"sha256:1b4cf9ab9a0ae0cb122685209806d3f1dcb63b9fccdf1424fb42a129dc8c2faa",
"sha256:1e04581c6117ad9479b6cfae313e212fe0dfa226ac727755f0d539cd54792963",
"sha256:1fa73ed22c40a1bec98d7c93b5659cd35abcfa5a0a95ce876b91adbda170537c",
"sha256:2124f9e645a94ab7c853bc0a3644e0ca8ffbe5bb2d72db49aef8f9ec1c285733",
"sha256:240687b5be0f91fbde4936a329c9b7589d9259742766f74de575e1b2046575e4",
"sha256:25740fb56e8bd37692ed380e15ec734be44d7c71974d8993f452b4527814601e",
"sha256:27ccc93c7457ef890b0dd31564d2a05e1aca330623c942b7e818e9e7c2669ee4",
"sha256:281c8b219d4f4b3581b918b816764098d04964915b2f272d1476654143801aa2",
"sha256:2d34a5450a402b00d20aeb7632489ffa2556ca7b26f4a63c35f6fccae1977427",
"sha256:301bd744a1adaa2f6a5e06c98f1ac2b6f8dc31a5c23b838f862d65e32fca0d4b",
"sha256:30e5ce9f501fb1f970e4a59098028cf20676dee64fc496d55c33e04bbbee097d",
"sha256:33ab498f9ac30598b6406e2be1b45fd231195b83d948ebd4bd77f337cb6a2bff",
"sha256:35585a8cb5917161f42c2104567bb83a1d96194095fc54a543113ed5df9fa436",
"sha256:389c0e38358fdc4e38e9995e7291269a3aead7acfcf8942010ee7bc5baee091c",
"sha256:3acadbab8b59f63b87b518e09c4c64b142e7286b9ca7a208107d6f9f4c393c5c",
"sha256:3b7a64d43e2a1fa2dd46b678e00cabd9a49ebb123b339ce799204c44a593ae1c",
"sha256:3c8c0226c71bd0ce9892eaf6afa77ae8f43a3d9313124a03df0b389c01f832de",
"sha256:429349a510da82c85431f0f3e66212d83efe9fd2850f50f339341b6532c62fe4",
"sha256:466030a42724780794dea71eb32db83cc51214d66ab3fb3156edd88b9c8f0d78",
"sha256:47aeceb4363851d17f63069318ba5721ae695d9da55d599b4d6fb31508595278",
"sha256:48aa98987d54a46e13e6954880056c204700c65616af4395d1f0639eba11764b",
"sha256:4b2416ed743ec5debcf61e1242e012652a4348de14ecc7df3512da072b074440",
"sha256:4d0a675a7acbbc16179188d8c6d0afb8628604fc1241faf41007255957335a0b",
"sha256:4eb74d44776b0fb0782560ea84d986dffec8ddd94947f383eba2284b0f32e35e",
"sha256:4f8a1d990dc198a6c68ec3d9a637ba1ce489b38cbfb65440a27901afbc5df575",
"sha256:513ccbf7420c30e283c25c82d5a8f439d625a838d3ba69e79a110c260c46813f",
"sha256:5210a0018c7e09c75fa788648617ebba861ae242944111d3079034e14498223f",
"sha256:54cdfcda59251b9c2f87a05d038c2ae02121219a04d4a1e6fc345794295bdc07",
"sha256:56dd500411d03c5e9927a1eb55621e906837a83b02350a9dc401247d0353717c",
"sha256:57ec6baec231bb19bb5fd5fc7bae21231860a1605174b11585660236627e390e",
"sha256:5f1519b080d8ce0a814f17ad9fb49fb3a1d4d7ce5891f5c85fc38631ca3a8dc4",
"sha256:6174d6ad6b58a6bcf67afbbf1723420a53d06c4b89f4c50763d6fa0a6ac9afd2",
"sha256:68172622a5a57deb079a2c78511c40f91193548e8ab342c31e8cb0764d362459",
"sha256:6915fc9fa6b3ec3569566832e1bb03bd801c12cea030200e68663b9a87974e76",
"sha256:6b75b912a0baa033350367a8a07a8b2d44fd5b90c890bfbd063a8a5f945f644b",
"sha256:6f5dcb658d597410bb7c967c1d24eaf9377b0d621358cbe9d2ff804e5dd12e81",
"sha256:6f8d7fe73d1816eeb5378409adc658f9525ecbfaf9e1ede1e2d67a338b0c7348",
"sha256:7036316cc26b93e401cedd781a579be606dad174829e6ad9e9c5a0da6e036f80",
"sha256:7188ddc1a8887194f984fa4110d5a3d5b9b5cd35f6bafdff1b649049cbc0ce29",
"sha256:761531076df51309075133a6bc1db02d98ec7f66e22b064b1d513bc909f29743",
"sha256:7979d90ee2190d000129598c2b0c82f13053dba432b94e45e68253b09bb1f0f6",
"sha256:8015835494b21aa7abd3b43fdea0614ee35ef6b03db7ecba9beb58eadf01c24f",
"sha256:81c4d1a3a564775c44732b94135d06e33417e829ff25226c164664f4a1046213",
"sha256:81cf9d306c04df1b45971c13167dc3bad625808aa01281d55f3cf852dde0e206",
"sha256:88857060b690a57d2ea8569bca58758143c8faa4639fb17d745ce60ff84c867e",
"sha256:8c567c664fc2f44130a20edac73e0a867f8e012bf7370276f15c6adc3586c37c",
"sha256:91bd2b7cf0f4d252eec8b7046fa6a43cee17e8acdfc00eaa8b3dbf2f9a59d061",
"sha256:9620650c364c01ed5b497dcae7c3d4b948daeae6e1883ae185fef1c927b6b534",
"sha256:9b007c2444705a2dc4a525964fd4dd28c3320b19b3410da6517cab28716f27d3",
"sha256:9bf9acce44e967a5103fcd820fc7580c7b0ab8583eec4e2051aec560f7b31a63",
"sha256:a239303acb0315091d54c7ff36712dba24554993b9a93941cf301391d8a997ee",
"sha256:a2baa6be130e8a00b6cbb9f18a33611ec150b4537f8563bddadb54c1b74b8193",
"sha256:a54917b7e9cd3a67e429a630e237a90b096e0ba18897bfb99ee8bd1068a5fea0",
"sha256:a689e1ded7137552bea36305a7a16ad2b40be511740b80748d3140614993db98",
"sha256:a952ae3eb460c6712388ac2ec706d24b0e651b9396d90c9a9e0a69eb27737fdc",
"sha256:aa32205358a76bf578854bf31698a86dc8b2cb591fd1d79a833283f4a403f04b",
"sha256:b2287c09482949e0ca0c0eb68b2aca6cf57f8af8c6dfd29dcd3bc45f17b57978",
"sha256:b6b0e17d39d21698185097652c611f9cf30f7c56ccec189789920e3e7f1cee56",
"sha256:b710bf7e7ae61957d5c4026b486be593ed3ec3dca3e5be15e0f6d8cf5d0a4990",
"sha256:b8e11715178f3608874508f08e990d3771e0b8c66c73eb4e183038d600a9b274",
"sha256:b92aafcfab3d41580d54aca35a8057341f1cfc7c9af9e8bdfc652f83a20ced31",
"sha256:bec29b801b4adbf388314c0d050e851d53762ab424af22657021ce4b6eb41543",
"sha256:c694bee70ece3b232df4678448fdda245fd3b1bb4ba481fb6cd20e13bb784c46",
"sha256:c6b52b7028b547866c2413f614ee306c2d4eafdd444b1ff656bf3295bf1484aa",
"sha256:cb41ad20064e18a900dd427d7cf41cfaec83bcd1184001f3d91a1f76b3fcea4e",
"sha256:cd316dbcc74c76266ba94eb021b0cc090b97cca122f50bd7a845f587ff4bf03f",
"sha256:ced40cdbb6dd47a032725a038896cceae9ce267d340f59508b23537f05455431",
"sha256:d1c562a9bb72244fa767d1c1ab55ca1d92dd5f7c4d77878fee5483a22ffac808",
"sha256:d389ff1e95b6e46ebedccf7fd1fadd10559add595ac6a7c2ea730268325f832c",
"sha256:d56b1cd606ba4cedd64bb43479d56580e147c6ef3f5d1c5e64203a1adab784a2",
"sha256:d72a4315514e5a0b9837a086cb433b004eea630afb0cc129de76d77654a9606f",
"sha256:d9e7f29c00577aff6b318681e730a519b235af292732a149337f6aaa4d1c5e31",
"sha256:dbc25baa6abb205766fb8606f8263b02c3503a55957fcb4576a6bb0a59d37d10",
"sha256:e57919c32ee295a2fca458bb73e4b20b05c115627f96f95a10f9f5acbd61172d",
"sha256:e5bbe011a2cea9060fef1bb3d668a2fd8432b8888e6d92e74c9c794d3c101595",
"sha256:e6aea5c0eb5b0faf52c7b5c4a47c8bb64437173be97227c819ffa31801fa4e34",
"sha256:e888be685fa42d8b8a3d3911d5604d14db87538aa7d0b29b1a7ea80d354c732d",
"sha256:eebaf8c76c39604d52852366249ab807fe6f7a3ffb0dd5484b9944917244cdbe",
"sha256:efbe0b5e0fd078ed7b005faa0170da4f72666360f66f0bb2d7f73526ecfd99f9",
"sha256:efddca2d02254a52078c35cadad34762adbae3ff01c6b0c7787b59d038b63e0d",
"sha256:f05450fa1cd7c525c0b9d1a7916e595d3041ac0afbed2ff6926e5afb6a781b7f",
"sha256:f12d69d568f5647ec503b64932874dade5a20255736c89936bf690951a5e79f5",
"sha256:f45321224144c25a62052035ce96cbcf264667bcb0d81823b1bbc22c4addd194",
"sha256:f62581d7e884dd01ee1707b7c21148f61f2febb7de092ae2f108743fcbef5985",
"sha256:f8832a4f83d4782a8f5a7b831c47e8ffe164e43c2c148c8160ed9a6d630bc02a",
"sha256:fa35ad36440aaf1ac8332b4a4a433d4acd28f1613f0d480995f5cfd3580e90b7"
],
"markers": "python_version >= '3.8'",
"version": "==0.12.0"
},
"social-auth-app-django": { "social-auth-app-django": {
"hashes": [ "hashes": [
"sha256:09ac02a063cb313eed5e9ef2f9ac4477c8bf5bbd685925ff3aba43f9072f1bbb", "sha256:09ac02a063cb313eed5e9ef2f9ac4477c8bf5bbd685925ff3aba43f9072f1bbb",
@ -349,11 +662,11 @@
}, },
"social-auth-core": { "social-auth-core": {
"hashes": [ "hashes": [
"sha256:9791d7c7aee2ac8517fe7a2ea2f942a8a5492b3a4ccb44a9b0dacc87d182f2aa", "sha256:3d4154f45c0bacffe54ccf4361bce7e66cf5f5cd1bb0ebb7507ad09a1b07d9d9",
"sha256:ea7a19c46b791b767e95f467881b53c5fd0d1efb40048d9ed3dbc46daa05c954" "sha256:f4ae5d8e503a401f319498bcad59fd1f6c473517eeae89c22299250f63c33365"
], ],
"markers": "python_version >= '3.6'", "markers": "python_version >= '3.8'",
"version": "==4.4.2" "version": "==4.5.0"
}, },
"sqlparse": { "sqlparse": {
"hashes": [ "hashes": [
@ -371,6 +684,14 @@
"markers": "sys_platform == 'win32'", "markers": "sys_platform == 'win32'",
"version": "==2023.3" "version": "==2023.3"
}, },
"uritemplate": {
"hashes": [
"sha256:4346edfc5c3b79f694bccd6d6099a322bbeb628dbf2cd86eea55a456ce5124f0",
"sha256:830c08b8d99bdd312ea4ead05994a38e8936266f84b9a7878232db50b044e02e"
],
"markers": "python_version >= '3.6'",
"version": "==4.1.1"
},
"urllib3": { "urllib3": {
"hashes": [ "hashes": [
"sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84", "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84",

View file

View file

@ -0,0 +1,11 @@
from django import forms
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import CustomUser
class CustomUserAdmin(UserAdmin):
model = CustomUser
admin.site.register(CustomUser, CustomUserAdmin)

View file

@ -0,0 +1,6 @@
from django.apps import AppConfig
class AccountsConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'accounts'

View file

@ -0,0 +1,46 @@
# Generated by Django 4.2.7 on 2023-11-09 11:42
import accounts.models
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='CustomUser',
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')),
('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')),
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
('first_name', models.CharField(max_length=100)),
('last_name', models.CharField(max_length=100)),
('is_active', models.BooleanField(default=False)),
('avatar', models.ImageField(null=True, upload_to=accounts.models.CustomUser._get_upload_to)),
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')),
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')),
],
options={
'verbose_name': 'user',
'verbose_name_plural': 'users',
'abstract': False,
},
managers=[
('objects', django.contrib.auth.models.UserManager()),
],
),
]

View file

@ -0,0 +1,82 @@
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.db.models.signals import post_migrate
from django.dispatch import receiver
import os
from uuid import uuid4
class CustomUser(AbstractUser):
# Function for avatar uploads
def _get_upload_to(instance, filename):
base_filename, file_extension = os.path.splitext(filename)
# Get the student ID number
ext = base_filename.split('.')[-1]
filename = '{}.{}'.format(uuid4().hex, ext)
student_id = str(instance.student_id_number)
new_filename = f"{student_id}_{filename}_{file_extension}"
return os.path.join('avatars', new_filename)
# Delete old avatar file if new one is uploaded
def save(self, *args, **kwargs):
try:
# is the object in the database yet?
this = CustomUser.objects.get(id=self.id)
if this.avatar != self.avatar:
this.avatar.delete(save=False)
except:
pass # when new photo then we do nothing, normal case
super(CustomUser, self).save(*args, **kwargs)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
# Email inherited from base user class
# Username inherited from base user class
# Password inherited from base user class
# is_admin inherited from base user class
is_active = models.BooleanField(default=False)
avatar = models.ImageField(upload_to=_get_upload_to, null=True)
@property
def full_name(self):
return f"{self.first_name} {self.last_name}"
pass
@receiver(post_migrate)
def create_superuser(sender, **kwargs):
if sender.name == 'accounts':
User = CustomUser
username = os.getenv('DJANGO_ADMIN_USERNAME')
email = os.getenv('DJANGO_ADMIN_EMAIL')
password = os.getenv('DJANGO_ADMIN_PASSWORD')
first_name = 'Admin'
last_name = 'Admin'
if not User.objects.filter(username=username).exists():
# Create the superuser with is_active set to False
superuser = User.objects.create_superuser(
username=username, email=email, password=password, first_name=first_name, last_name=last_name)
# Activate the superuser
superuser.is_active = True
print('Created admin account')
superuser.save()
username = 'usertest1'
email = os.getenv('DJANGO_ADMIN_EMAIL')
password = os.getenv('DJANGO_ADMIN_PASSWORD')
first_name = 'Test'
last_name = 'User'
if not User.objects.filter(username=username).exists():
# Create the superuser with is_active set to False
user = User.objects.create_user(
username=username, email=email, password=password, first_name=first_name, last_name=last_name)
# Activate the user
user.is_active = True
print('Created debug user account')
user.save()

View file

@ -0,0 +1,45 @@
from djoser.serializers import UserCreateSerializer as BaseUserRegistrationSerializer
from djoser.serializers import UserSerializer as BaseUserSerializer
from django.core import exceptions as django_exceptions
from rest_framework import serializers
from accounts.models import CustomUser
from rest_framework.settings import api_settings
from django.contrib.auth.password_validation import validate_password
from django.utils.encoding import smart_str
from drf_spectacular.utils import extend_schema_field
from drf_spectacular.types import OpenApiTypes
from drf_extra_fields.fields import Base64ImageField
# There can be multiple subject instances with the same name, only differing in course, year level, and semester. We filter them here
class CustomUserSerializer(BaseUserSerializer):
avatar = Base64ImageField()
class Meta(BaseUserSerializer.Meta):
model = CustomUser
fields = ('username', 'email', 'avatar', 'first_name', 'last_name',)
class UserRegistrationSerializer(serializers.ModelSerializer):
email = serializers.EmailField(required=True)
password = serializers.CharField(
write_only=True, style={'input_type': 'password', 'placeholder': 'Password'})
class Meta:
model = CustomUser # Use your custom user model here
fields = ('username', 'email', 'password', 'avatar',
'first_name', 'last_name')
def validate(self, attrs):
user = self.Meta.model(**attrs)
password = attrs.get("password")
try:
validate_password(password, user)
except django_exceptions.ValidationError as e:
serializer_error = serializers.as_serializer_error(e)
raise serializers.ValidationError(
{"password": serializer_error[api_settings.NON_FIELD_ERRORS_KEY]}
)
return super().validate(attrs)

View file

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

View file

@ -0,0 +1,7 @@
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('', include('djoser.urls')),
path('', include('djoser.urls.jwt')),
]

View file

@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.

Binary file not shown.

View file

@ -1,5 +1,6 @@
from django.urls import path, include from django.urls import path, include
urlpatterns = [ urlpatterns = [
path('accounts/', include('djoser.urls')) path('accounts/', include('accounts.urls')),
path('equipments/', include('equipments.urls'))
] ]

View file

@ -64,8 +64,13 @@ INSTALLED_APPS = [
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'rest_framework', 'rest_framework',
'rest_framework_simplejwt', 'rest_framework_simplejwt',
'simple_history',
'djoser', 'djoser',
'corsheaders' 'corsheaders',
'drf_spectacular',
'drf_spectacular_sidecar',
'accounts',
'equipments',
] ]
MIDDLEWARE = [ MIDDLEWARE = [
@ -124,6 +129,19 @@ REST_FRAMEWORK = {
'user': '1440/min' 'user': '1440/min'
}, },
'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
}
# DRF-Spectacular
SPECTACULAR_SETTINGS = {
'TITLE': 'CITC Equipment Tracker Backend',
'DESCRIPTION': 'An IT Elective 4 Project',
'VERSION': '1.0.0',
'SERVE_INCLUDE_SCHEMA': False,
'SWAGGER_UI_DIST': 'SIDECAR',
'SWAGGER_UI_FAVICON_HREF': 'SIDECAR',
'REDOC_DIST': 'SIDECAR',
# OTHER SETTINGS
} }
WSGI_APPLICATION = 'config.wsgi.application' WSGI_APPLICATION = 'config.wsgi.application'
@ -139,11 +157,21 @@ DATABASES = {
} }
} }
AUTH_USER_MODEL = 'accounts.CustomUser'
DJOSER = { DJOSER = {
'SEND_ACTIVATION_EMAIL': True, 'SEND_ACTIVATION_EMAIL': True,
'SEND_CONFIRMATION_EMAIL': True, 'SEND_CONFIRMATION_EMAIL': True,
'EMAIL': {
'activation': 'config.email.ActivationEmail'
},
'ACTIVATION_URL': 'activation/{uid}/{token}', 'ACTIVATION_URL': 'activation/{uid}/{token}',
'USER_AUTHENTICATION_RULES': ['djoser.authentication.TokenAuthenticationRule'], 'USER_AUTHENTICATION_RULES': ['djoser.authentication.TokenAuthenticationRule'],
'SERIALIZERS': {
'user': 'accounts.serializers.CustomUserSerializer',
'current_user': 'accounts.serializers.CustomUserSerializer',
'user_create': 'accounts.serializers.UserRegistrationSerializer',
},
} }
# Password validation # Password validation

View file

@ -16,8 +16,14 @@ Including another URLconf
""" """
from django.contrib import admin from django.contrib import admin
from django.urls import path, include from django.urls import path, include
from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView
urlpatterns = [ urlpatterns = [
path('admin/', admin.site.urls), path('admin/', admin.site.urls),
path('api/v1/', include('api.urls')) path('api/v1/', include('api.urls')),
path('schema/', SpectacularAPIView.as_view(), name='schema'),
path('swagger/',
SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'),
path('redoc/',
SpectacularRedocView.as_view(url_name='schema'), name='redoc'),
] ]

Binary file not shown.

View file

View file

@ -0,0 +1,5 @@
from django.contrib import admin
from .models import Equipment, EquipmentInstance
admin.site.register(Equipment)
admin.site.register(EquipmentInstance)

View file

@ -0,0 +1,6 @@
from django.apps import AppConfig
class EquipmentsConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'equipments'

View file

@ -0,0 +1,66 @@
# Generated by Django 4.2.7 on 2023-11-12 12:07
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
import simple_history.models
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Equipment',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=40)),
('description', models.TextField(max_length=512)),
('date_added', models.DateTimeField(default=django.utils.timezone.now, editable=False)),
('last_updated', models.DateTimeField(auto_now=True)),
('last_changed_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)),
],
),
migrations.CreateModel(
name='HistoricalEquipmentInstance',
fields=[
('id', models.BigIntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
('status', models.CharField(choices=[('Working', 'Working'), ('Broken', 'Broken'), ('Under Maintenance', 'Under Maintenance'), ('Decomissioned', 'Decomissioned ')], default='PENDING', max_length=20)),
('remarks', models.TextField(max_length=512)),
('date_added', models.DateTimeField(default=django.utils.timezone.now, editable=False)),
('last_updated', models.DateTimeField(blank=True, editable=False)),
('history_id', models.AutoField(primary_key=True, serialize=False)),
('history_date', models.DateTimeField(db_index=True)),
('history_change_reason', models.CharField(max_length=100, null=True)),
('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)),
('equipment', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='equipments.equipment')),
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
('last_changed_by', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'historical equipment instance',
'verbose_name_plural': 'historical equipment instances',
'ordering': ('-history_date', '-history_id'),
'get_latest_by': ('history_date', 'history_id'),
},
bases=(simple_history.models.HistoricalChanges, models.Model),
),
migrations.CreateModel(
name='EquipmentInstance',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('status', models.CharField(choices=[('Working', 'Working'), ('Broken', 'Broken'), ('Under Maintenance', 'Under Maintenance'), ('Decomissioned', 'Decomissioned ')], default='PENDING', max_length=20)),
('remarks', models.TextField(max_length=512)),
('date_added', models.DateTimeField(default=django.utils.timezone.now, editable=False)),
('last_updated', models.DateTimeField(auto_now=True)),
('equipment', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='equipments.equipment')),
('last_changed_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)),
],
),
]

View file

@ -0,0 +1,25 @@
# Generated by Django 4.2.7 on 2023-11-12 12:16
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('equipments', '0001_initial'),
]
operations = [
migrations.RemoveField(
model_name='equipment',
name='last_changed_by',
),
migrations.RemoveField(
model_name='equipmentinstance',
name='last_changed_by',
),
migrations.RemoveField(
model_name='historicalequipmentinstance',
name='last_changed_by',
),
]

View file

@ -0,0 +1,40 @@
# Generated by Django 4.2.7 on 2023-11-12 12:27
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
import simple_history.models
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('equipments', '0002_remove_equipment_last_changed_by_and_more'),
]
operations = [
migrations.CreateModel(
name='HistoricalEquipment',
fields=[
('id', models.BigIntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
('name', models.CharField(max_length=40)),
('description', models.TextField(max_length=512)),
('date_added', models.DateTimeField(default=django.utils.timezone.now, editable=False)),
('last_updated', models.DateTimeField(blank=True, editable=False)),
('history_id', models.AutoField(primary_key=True, serialize=False)),
('history_date', models.DateTimeField(db_index=True)),
('history_change_reason', models.CharField(max_length=100, null=True)),
('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)),
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'historical equipment',
'verbose_name_plural': 'historical equipments',
'ordering': ('-history_date', '-history_id'),
'get_latest_by': ('history_date', 'history_id'),
},
bases=(simple_history.models.HistoricalChanges, models.Model),
),
]

View file

@ -0,0 +1,50 @@
from django.db import models
from django.utils.timezone import now
from simple_history.models import HistoricalRecords
from django.db.models.signals import post_migrate
from django.dispatch import receiver
# Create your models here.
class Equipment(models.Model):
name = models.CharField(max_length=40)
description = models.TextField(max_length=512)
date_added = models.DateTimeField(default=now, editable=False)
last_updated = models.DateTimeField(auto_now=True, editable=False)
history = HistoricalRecords()
def __str__(self):
return f'{self.name} ID:{self.id}'
class EquipmentInstance(models.Model):
STATUS_CHOICES = (
('Working', 'Working'),
('Broken', 'Broken'),
('Under Maintenance', 'Under Maintenance'),
('Decomissioned', 'Decomissioned '),
)
equipment = models.ForeignKey(Equipment, on_delete=models.CASCADE)
status = models.CharField(
max_length=20, choices=STATUS_CHOICES, default='PENDING')
remarks = models.TextField(max_length=512)
date_added = models.DateTimeField(default=now, editable=False)
last_updated = models.DateTimeField(auto_now=True, editable=False)
history = HistoricalRecords()
def __str__(self):
return f'{self.equipment.name} ID:{self.id}'
@receiver(post_migrate)
def create_superuser(sender, **kwargs):
if sender.name == 'equipments':
EQUIPMENT, CREATED = Equipment.objects.get_or_create(
name="HP All-in-One PC", description="I5 6500 8GB RAM 1TB HDD")
if (CREATED):
print("Created sample equipment")
EQUIPMENT_INSTANCE, CREATED = EquipmentInstance.objects.get_or_create(
equipment=EQUIPMENT, status="Working", remarks="First PC of USTP!")
if (CREATED):
print("Created sample equipment instance")

View file

@ -0,0 +1,157 @@
from rest_framework import serializers
from django.contrib.auth.models import User
from .models import Equipment, EquipmentInstance
# -- Equipment Serializers
class EquipmentHistoricalRecordField(serializers.ListField):
child = serializers.DictField()
def to_representation(self, data):
return super().to_representation(data.values('name', 'description', 'history_date', 'history_user').order_by('-history_date'))
class EquipmentSerializer(serializers.HyperlinkedModelSerializer):
date_added = serializers.DateTimeField(
format="%m-%d-%Y %I:%M%p", read_only=True)
last_updated = serializers.DateTimeField(
format="%m-%d-%Y %I:%M%p", read_only=True)
last_updated_by = serializers.SerializerMethodField()
name = serializers.CharField()
description = serializers.CharField()
class Meta:
model = Equipment
fields = ('id', 'name', 'description',
'last_updated', 'last_updated_by', 'date_added')
read_only_fields = ('id', 'last_updated',
'last_updated_by', 'date_added')
def get_history_user(self, obj):
return obj.history_user.username if obj.history_user else None
def get_last_updated_by(self, obj):
return obj.history.first().history_user if obj.history.first().history_user else None
class EquipmentLogsSerializer(serializers.HyperlinkedModelSerializer):
history_date = serializers.DateTimeField(
format="%m-%d-%Y %I:%M%p", read_only=True)
history_user = serializers.SerializerMethodField()
class Meta:
model = Equipment.history.model
fields = ('history_id', 'name', 'description',
'history_date', 'history_user')
read_only_fields = ('history_id', 'id', 'name', 'description',
'history_date', 'history_user')
def get_history_user(self, obj):
return obj.history_user.username if obj.history_user else None
class EquipmentLogSerializer(serializers.HyperlinkedModelSerializer):
date_added = serializers.DateTimeField(
format="%m-%d-%Y %I:%M%p", read_only=True)
last_updated = serializers.DateTimeField(
format="%m-%d-%Y %I:%M%p", read_only=True)
last_updated_by = serializers.SerializerMethodField()
name = serializers.CharField()
description = serializers.CharField()
history = EquipmentHistoricalRecordField()
class Meta:
model = Equipment
fields = ('id', 'name', 'description',
'last_updated', 'date_added', 'last_updated_by', 'history')
read_only_fields = ('id', 'last_updated',
'date_added', 'last_updated_by', 'history')
def get_last_updated_by(self, obj):
return obj.history.first().history_user if obj.history.first().history_user else None
# -- Equipment Instance Serializers
class EquipmentInstanceHistoricalRecordField(serializers.ListField):
child = serializers.DictField()
def to_representation(self, data):
return super().to_representation(data.values('equipment', 'status', 'remarks', 'history_date', 'history_user').order_by('-history_date'))
class EquipmentInstanceSerializer(serializers.HyperlinkedModelSerializer):
equipment = serializers.PrimaryKeyRelatedField(
source='equipment.name', queryset=Equipment.objects.all())
status = serializers.CharField()
remarks = serializers.CharField()
date_added = serializers.DateTimeField(
format="%m-%d-%Y %I:%M%p", read_only=True)
last_updated = serializers.DateTimeField(
format="%m-%d-%Y %I:%M%p", read_only=True)
last_updated_by = serializers.SerializerMethodField()
# Forbid user from changing equipment field once the instance is already created
def update(self, instance, validated_data):
# Ignore any changes to 'equipment'
validated_data.pop('equipment', None)
return super().update(instance, validated_data)
class Meta:
model = EquipmentInstance
fields = ('id', 'equipment', 'status', 'remarks',
'last_updated', 'last_updated_by', 'date_added')
read_only_fields = ('id', 'last_updated',
'last_updated_by', 'date_added')
def get_history_user(self, obj):
return obj.history_user.username if obj.history_user else None
def get_last_updated_by(self, obj):
return obj.history.first().history_user if obj.history.first().history_user else None
class EquipmentInstanceLogsSerializer(serializers.HyperlinkedModelSerializer):
history_date = serializers.DateTimeField(
format="%m-%d-%Y %I:%M%p", read_only=True)
history_user = serializers.SerializerMethodField()
class Meta:
model = EquipmentInstance.history.model
fields = ('history_id', 'status', 'remarks',
'history_date', 'history_user')
read_only_fields = ('history_id', 'id', 'status', 'remarks',
'history_date', 'history_user')
def get_history_user(self, obj):
return obj.history_user.username if obj.history_user else None
class EquipmentInstanceLogSerializer(serializers.HyperlinkedModelSerializer):
equipment = serializers.PrimaryKeyRelatedField(
source='equipment.name', queryset=Equipment.objects.all())
status = serializers.CharField()
remarks = serializers.CharField()
date_added = serializers.DateTimeField(
format="%m-%d-%Y %I:%M%p", read_only=True)
last_updated = serializers.DateTimeField(
format="%m-%d-%Y %I:%M%p", read_only=True)
last_updated_by = serializers.SerializerMethodField()
history = EquipmentInstanceHistoricalRecordField()
# Forbid user from changing equipment field once the instance is already created
def update(self, instance, validated_data):
# Ignore any changes to 'equipment'
validated_data.pop('equipment', None)
return super().update(instance, validated_data)
class Meta:
model = EquipmentInstance
fields = ('id', 'equipment', 'status', 'remarks',
'last_updated', 'date_added', 'last_updated_by', 'history')
read_only_fields = ('id', 'last_updated',
'date_added', 'last_updated_by', 'history')
def get_last_updated_by(self, obj):
return obj.history.first().history_user if obj.history.first().history_user else None

View file

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

View file

@ -0,0 +1,29 @@
from django.urls import include, path
from rest_framework import routers
from . import views
router = routers.DefaultRouter()
# For viewing all equipments
router.register(r'equipments', views.EquipmentViewSet)
router.register(r'equipment_instances', views.EquipmentInstanceViewSet)
# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.
urlpatterns = [
path('', include(router.urls)),
# Logs for all equipments
path('equipments/logs', views.EquipmentsLogsViewSet.as_view()),
# Logs for each equipment
path('equipments/<int:equipment_id>/logs/',
views.EquipmentLogViewSet.as_view({'get': 'list'})),
# Last changed equipment
path('equipments/latest', views.LastUpdatedEquipmentViewSet.as_view()),
# Logs for all equipment instances
path('equipment_instances/logs', views.EquipmentInstancesLogsViewSet.as_view()),
# Logs for each equipment instance
path('equipment_instances/<int:equipment_id>/logs/',
views.EquipmentInstanceLogViewSet.as_view({'get': 'list'})),
# Last changed equipment instance
path('equipment_instances/latest',
views.LastUpdatedEquipmentInstanceViewSet.as_view())
]

View file

@ -0,0 +1,89 @@
from rest_framework.permissions import IsAuthenticated
from rest_framework import viewsets, generics
from .models import Equipment, EquipmentInstance
from . import serializers
from config.settings import DEBUG
# -- Equipment Viewsets
class EquipmentViewSet(viewsets.ModelViewSet):
if (not DEBUG):
permission_classes = [IsAuthenticated]
serializer_class = serializers.EquipmentSerializer
queryset = Equipment.objects.all().order_by('-date_added')
# For viewing all logs for all equipments
class EquipmentsLogsViewSet(generics.ListAPIView):
if (not DEBUG):
permission_classes = [IsAuthenticated]
serializer_class = serializers.EquipmentLogsSerializer
queryset = Equipment.history.all().order_by('-history_date')
# For viewing logs per individual equipment
class EquipmentLogViewSet(viewsets.ReadOnlyModelViewSet):
if (not DEBUG):
permission_classes = [IsAuthenticated]
serializer_class = serializers.EquipmentLogSerializer
def get_queryset(self):
equipment_id = self.kwargs['equipment_id']
return Equipment.objects.filter(id=equipment_id)
# Last changed equipment
class LastUpdatedEquipmentViewSet(generics.ListAPIView):
if (not DEBUG):
permission_classes = [IsAuthenticated]
serializer_class = serializers.EquipmentSerializer
queryset = Equipment.objects.all().order_by('-date_added')
def get_queryset(self):
return super().get_queryset()[:1]
# -- Equipment Instance Viewsets
class EquipmentInstanceViewSet(viewsets.ModelViewSet):
if (not DEBUG):
permission_classes = [IsAuthenticated]
serializer_class = serializers.EquipmentInstanceSerializer
queryset = EquipmentInstance.objects.all().order_by('-date_added')
# For viewing all equipment instance logs
class EquipmentInstancesLogsViewSet(generics.ListAPIView):
if (not DEBUG):
permission_classes = [IsAuthenticated]
serializer_class = serializers.EquipmentInstanceLogsSerializer
queryset = EquipmentInstance.history.all().order_by('-history_date')
# For viewing logs per individual equipment instance
class EquipmentInstanceLogViewSet(viewsets.ReadOnlyModelViewSet):
if (not DEBUG):
permission_classes = [IsAuthenticated]
serializer_class = serializers.EquipmentInstanceLogSerializer
def get_queryset(self):
equipment_id = self.kwargs['equipment_id']
return EquipmentInstance.objects.filter(id=equipment_id)
# Last changed equipment instance
class LastUpdatedEquipmentInstanceViewSet(generics.ListAPIView):
if (not DEBUG):
permission_classes = [IsAuthenticated]
serializer_class = serializers.EquipmentInstanceSerializer
queryset = EquipmentInstance.objects.all().order_by('-date_added')
def get_queryset(self):
return super().get_queryset()[:1]

View file

@ -0,0 +1,710 @@
openapi: 3.0.3
info:
title: CITC Equipment Tracker Backend
version: 1.0.0
description: An IT Elective 4 Project
paths:
/api/v1/accounts/jwt/create/:
post:
operationId: api_v1_accounts_jwt_create_create
description: |-
Takes a set of user credentials and returns an access and refresh JSON web
token pair to prove the authentication of those credentials.
tags:
- api
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/TokenObtainPair'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/TokenObtainPair'
multipart/form-data:
schema:
$ref: '#/components/schemas/TokenObtainPair'
required: true
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/TokenObtainPair'
description: ''
/api/v1/accounts/jwt/refresh/:
post:
operationId: api_v1_accounts_jwt_refresh_create
description: |-
Takes a refresh type JSON web token and returns an access type JSON web
token if the refresh token is valid.
tags:
- api
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/TokenRefresh'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/TokenRefresh'
multipart/form-data:
schema:
$ref: '#/components/schemas/TokenRefresh'
required: true
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/TokenRefresh'
description: ''
/api/v1/accounts/jwt/verify/:
post:
operationId: api_v1_accounts_jwt_verify_create
description: |-
Takes a token and indicates if it is valid. This view provides no
information about a token's fitness for a particular use.
tags:
- api
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/TokenVerify'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/TokenVerify'
multipart/form-data:
schema:
$ref: '#/components/schemas/TokenVerify'
required: true
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/TokenVerify'
description: ''
/api/v1/accounts/users/:
get:
operationId: api_v1_accounts_users_list
tags:
- api
security:
- jwtAuth: []
responses:
'200':
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/CustomUser'
description: ''
post:
operationId: api_v1_accounts_users_create
tags:
- api
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/UserRegistration'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/UserRegistration'
multipart/form-data:
schema:
$ref: '#/components/schemas/UserRegistration'
required: true
security:
- jwtAuth: []
- {}
responses:
'201':
content:
application/json:
schema:
$ref: '#/components/schemas/UserRegistration'
description: ''
/api/v1/accounts/users/{id}/:
get:
operationId: api_v1_accounts_users_retrieve
parameters:
- in: path
name: id
schema:
type: integer
description: A unique integer value identifying this user.
required: true
tags:
- api
security:
- jwtAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CustomUser'
description: ''
put:
operationId: api_v1_accounts_users_update
parameters:
- in: path
name: id
schema:
type: integer
description: A unique integer value identifying this user.
required: true
tags:
- api
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/CustomUser'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/CustomUser'
multipart/form-data:
schema:
$ref: '#/components/schemas/CustomUser'
required: true
security:
- jwtAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CustomUser'
description: ''
patch:
operationId: api_v1_accounts_users_partial_update
parameters:
- in: path
name: id
schema:
type: integer
description: A unique integer value identifying this user.
required: true
tags:
- api
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PatchedCustomUser'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/PatchedCustomUser'
multipart/form-data:
schema:
$ref: '#/components/schemas/PatchedCustomUser'
security:
- jwtAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CustomUser'
description: ''
delete:
operationId: api_v1_accounts_users_destroy
parameters:
- in: path
name: id
schema:
type: integer
description: A unique integer value identifying this user.
required: true
tags:
- api
security:
- jwtAuth: []
responses:
'204':
description: No response body
/api/v1/accounts/users/activation/:
post:
operationId: api_v1_accounts_users_activation_create
tags:
- api
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Activation'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/Activation'
multipart/form-data:
schema:
$ref: '#/components/schemas/Activation'
required: true
security:
- jwtAuth: []
- {}
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Activation'
description: ''
/api/v1/accounts/users/me/:
get:
operationId: api_v1_accounts_users_me_retrieve
tags:
- api
security:
- jwtAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CustomUser'
description: ''
put:
operationId: api_v1_accounts_users_me_update
tags:
- api
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/CustomUser'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/CustomUser'
multipart/form-data:
schema:
$ref: '#/components/schemas/CustomUser'
required: true
security:
- jwtAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CustomUser'
description: ''
patch:
operationId: api_v1_accounts_users_me_partial_update
tags:
- api
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PatchedCustomUser'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/PatchedCustomUser'
multipart/form-data:
schema:
$ref: '#/components/schemas/PatchedCustomUser'
security:
- jwtAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CustomUser'
description: ''
delete:
operationId: api_v1_accounts_users_me_destroy
tags:
- api
security:
- jwtAuth: []
responses:
'204':
description: No response body
/api/v1/accounts/users/resend_activation/:
post:
operationId: api_v1_accounts_users_resend_activation_create
tags:
- api
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/SendEmailReset'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/SendEmailReset'
multipart/form-data:
schema:
$ref: '#/components/schemas/SendEmailReset'
required: true
security:
- jwtAuth: []
- {}
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/SendEmailReset'
description: ''
/api/v1/accounts/users/reset_password/:
post:
operationId: api_v1_accounts_users_reset_password_create
tags:
- api
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/SendEmailReset'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/SendEmailReset'
multipart/form-data:
schema:
$ref: '#/components/schemas/SendEmailReset'
required: true
security:
- jwtAuth: []
- {}
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/SendEmailReset'
description: ''
/api/v1/accounts/users/reset_password_confirm/:
post:
operationId: api_v1_accounts_users_reset_password_confirm_create
tags:
- api
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PasswordResetConfirm'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/PasswordResetConfirm'
multipart/form-data:
schema:
$ref: '#/components/schemas/PasswordResetConfirm'
required: true
security:
- jwtAuth: []
- {}
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PasswordResetConfirm'
description: ''
/api/v1/accounts/users/reset_username/:
post:
operationId: api_v1_accounts_users_reset_username_create
tags:
- api
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/SendEmailReset'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/SendEmailReset'
multipart/form-data:
schema:
$ref: '#/components/schemas/SendEmailReset'
required: true
security:
- jwtAuth: []
- {}
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/SendEmailReset'
description: ''
/api/v1/accounts/users/reset_username_confirm/:
post:
operationId: api_v1_accounts_users_reset_username_confirm_create
tags:
- api
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/UsernameResetConfirm'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/UsernameResetConfirm'
multipart/form-data:
schema:
$ref: '#/components/schemas/UsernameResetConfirm'
required: true
security:
- jwtAuth: []
- {}
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/UsernameResetConfirm'
description: ''
/api/v1/accounts/users/set_password/:
post:
operationId: api_v1_accounts_users_set_password_create
tags:
- api
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/SetPassword'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/SetPassword'
multipart/form-data:
schema:
$ref: '#/components/schemas/SetPassword'
required: true
security:
- jwtAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/SetPassword'
description: ''
/api/v1/accounts/users/set_username/:
post:
operationId: api_v1_accounts_users_set_username_create
tags:
- api
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/SetUsername'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/SetUsername'
multipart/form-data:
schema:
$ref: '#/components/schemas/SetUsername'
required: true
security:
- jwtAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/SetUsername'
description: ''
components:
schemas:
Activation:
type: object
properties:
uid:
type: string
token:
type: string
required:
- token
- uid
CustomUser:
type: object
properties:
username:
type: string
readOnly: true
description: Required. 150 characters or fewer. Letters, digits and @/./+/-/_
only.
email:
type: string
format: email
title: Email address
maxLength: 254
avatar:
type: string
format: uri
first_name:
type: string
maxLength: 100
last_name:
type: string
maxLength: 100
required:
- avatar
- first_name
- last_name
- username
PasswordResetConfirm:
type: object
properties:
uid:
type: string
token:
type: string
new_password:
type: string
required:
- new_password
- token
- uid
PatchedCustomUser:
type: object
properties:
username:
type: string
readOnly: true
description: Required. 150 characters or fewer. Letters, digits and @/./+/-/_
only.
email:
type: string
format: email
title: Email address
maxLength: 254
avatar:
type: string
format: uri
first_name:
type: string
maxLength: 100
last_name:
type: string
maxLength: 100
SendEmailReset:
type: object
properties:
email:
type: string
format: email
required:
- email
SetPassword:
type: object
properties:
new_password:
type: string
current_password:
type: string
required:
- current_password
- new_password
SetUsername:
type: object
properties:
current_password:
type: string
new_username:
type: string
title: Username
description: Required. 150 characters or fewer. Letters, digits and @/./+/-/_
only.
pattern: ^[\w.@+-]+$
maxLength: 150
required:
- current_password
- new_username
TokenObtainPair:
type: object
properties:
username:
type: string
writeOnly: true
password:
type: string
writeOnly: true
access:
type: string
readOnly: true
refresh:
type: string
readOnly: true
required:
- access
- password
- refresh
- username
TokenRefresh:
type: object
properties:
access:
type: string
readOnly: true
refresh:
type: string
writeOnly: true
required:
- access
- refresh
TokenVerify:
type: object
properties:
token:
type: string
writeOnly: true
required:
- token
UserRegistration:
type: object
properties:
username:
type: string
description: Required. 150 characters or fewer. Letters, digits and @/./+/-/_
only.
pattern: ^[\w.@+-]+$
maxLength: 150
email:
type: string
format: email
password:
type: string
writeOnly: true
avatar:
type: string
format: uri
nullable: true
first_name:
type: string
maxLength: 100
last_name:
type: string
maxLength: 100
required:
- email
- first_name
- last_name
- password
- username
UsernameResetConfirm:
type: object
properties:
new_username:
type: string
title: Username
description: Required. 150 characters or fewer. Letters, digits and @/./+/-/_
only.
pattern: ^[\w.@+-]+$
maxLength: 150
required:
- new_username
securitySchemes:
jwtAuth:
type: http
scheme: bearer
bearerFormat: JWT