ckeditor в админке, урлы для конт и осайте
parent
3b3595d6b8
commit
9d92bcac90
|
@ -262,19 +262,19 @@ sqlalchemy = ">=2.0.16"
|
|||
|
||||
[[package]]
|
||||
name = "flask-wtf"
|
||||
version = "1.1.1"
|
||||
version = "1.1.2"
|
||||
description = "Form rendering, validation, and CSRF protection for Flask with WTForms."
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "Flask-WTF-1.1.1.tar.gz", hash = "sha256:41c4244e9ae626d63bed42ae4785b90667b885b1535d5a4095e1f63060d12aa9"},
|
||||
{file = "Flask_WTF-1.1.1-py3-none-any.whl", hash = "sha256:7887d6f1ebb3e17bf648647422f0944c9a469d0fcf63e3b66fb9a83037e38b2c"},
|
||||
{file = "flask_wtf-1.1.2-py3-none-any.whl", hash = "sha256:134f45f3155ebdbb2b44fe8e5b498a0956d34a16b10a53fadcb7a865c0b3cea2"},
|
||||
{file = "flask_wtf-1.1.2.tar.gz", hash = "sha256:b51cfa7ad14e03de432a6268e8341354939d0beebf30fce66f8617a93e55e2a0"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
Flask = "*"
|
||||
flask = "*"
|
||||
itsdangerous = "*"
|
||||
WTForms = "*"
|
||||
wtforms = "*"
|
||||
|
||||
[package.extras]
|
||||
email = ["email-validator"]
|
||||
|
@ -389,18 +389,18 @@ files = [
|
|||
|
||||
[[package]]
|
||||
name = "importlib-resources"
|
||||
version = "6.0.1"
|
||||
version = "6.1.0"
|
||||
description = "Read resources from Python packages"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "importlib_resources-6.0.1-py3-none-any.whl", hash = "sha256:134832a506243891221b88b4ae1213327eea96ceb4e407a00d790bb0626f45cf"},
|
||||
{file = "importlib_resources-6.0.1.tar.gz", hash = "sha256:4359457e42708462b9626a04657c6208ad799ceb41e5c58c57ffa0e6a098a5d4"},
|
||||
{file = "importlib_resources-6.1.0-py3-none-any.whl", hash = "sha256:aa50258bbfa56d4e33fbd8aa3ef48ded10d1735f11532b8df95388cc6bdb7e83"},
|
||||
{file = "importlib_resources-6.1.0.tar.gz", hash = "sha256:9d48dcccc213325e810fd723e7fbb45ccb39f6cf5c31f00cf2b965f5f10f3cb9"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
|
||||
testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-ruff"]
|
||||
docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"]
|
||||
testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-ruff", "zipp (>=3.17)"]
|
||||
|
||||
[[package]]
|
||||
name = "itsdangerous"
|
||||
|
@ -548,22 +548,22 @@ totp = ["cryptography"]
|
|||
|
||||
[[package]]
|
||||
name = "psycopg2"
|
||||
version = "2.9.7"
|
||||
version = "2.9.8"
|
||||
description = "psycopg2 - Python-PostgreSQL Database Adapter"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
{file = "psycopg2-2.9.7-cp310-cp310-win32.whl", hash = "sha256:1a6a2d609bce44f78af4556bea0c62a5e7f05c23e5ea9c599e07678995609084"},
|
||||
{file = "psycopg2-2.9.7-cp310-cp310-win_amd64.whl", hash = "sha256:b22ed9c66da2589a664e0f1ca2465c29b75aaab36fa209d4fb916025fb9119e5"},
|
||||
{file = "psycopg2-2.9.7-cp311-cp311-win32.whl", hash = "sha256:44d93a0109dfdf22fe399b419bcd7fa589d86895d3931b01fb321d74dadc68f1"},
|
||||
{file = "psycopg2-2.9.7-cp311-cp311-win_amd64.whl", hash = "sha256:91e81a8333a0037babfc9fe6d11e997a9d4dac0f38c43074886b0d9dead94fe9"},
|
||||
{file = "psycopg2-2.9.7-cp37-cp37m-win32.whl", hash = "sha256:d1210fcf99aae6f728812d1d2240afc1dc44b9e6cba526a06fb8134f969957c2"},
|
||||
{file = "psycopg2-2.9.7-cp37-cp37m-win_amd64.whl", hash = "sha256:e9b04cbef584310a1ac0f0d55bb623ca3244c87c51187645432e342de9ae81a8"},
|
||||
{file = "psycopg2-2.9.7-cp38-cp38-win32.whl", hash = "sha256:d5c5297e2fbc8068d4255f1e606bfc9291f06f91ec31b2a0d4c536210ac5c0a2"},
|
||||
{file = "psycopg2-2.9.7-cp38-cp38-win_amd64.whl", hash = "sha256:8275abf628c6dc7ec834ea63f6f3846bf33518907a2b9b693d41fd063767a866"},
|
||||
{file = "psycopg2-2.9.7-cp39-cp39-win32.whl", hash = "sha256:c7949770cafbd2f12cecc97dea410c514368908a103acf519f2a346134caa4d5"},
|
||||
{file = "psycopg2-2.9.7-cp39-cp39-win_amd64.whl", hash = "sha256:b6bd7d9d3a7a63faae6edf365f0ed0e9b0a1aaf1da3ca146e6b043fb3eb5d723"},
|
||||
{file = "psycopg2-2.9.7.tar.gz", hash = "sha256:f00cc35bd7119f1fed17b85bd1007855194dde2cbd8de01ab8ebb17487440ad8"},
|
||||
{file = "psycopg2-2.9.8-cp310-cp310-win32.whl", hash = "sha256:2f8594f92bbb5d8b59ffec04e2686c416401e2d4297de1193f8e75235937e71d"},
|
||||
{file = "psycopg2-2.9.8-cp310-cp310-win_amd64.whl", hash = "sha256:f9ecbf504c4eaff90139d5c9b95d47275f2b2651e14eba56392b4041fbf4c2b3"},
|
||||
{file = "psycopg2-2.9.8-cp311-cp311-win32.whl", hash = "sha256:65f81e72136d8b9ac8abf5206938d60f50da424149a43b6073f1546063c0565e"},
|
||||
{file = "psycopg2-2.9.8-cp311-cp311-win_amd64.whl", hash = "sha256:f7e62095d749359b7854143843f27edd7dccfcd3e1d833b880562aa5702d92b0"},
|
||||
{file = "psycopg2-2.9.8-cp37-cp37m-win32.whl", hash = "sha256:81b21424023a290a40884c7f8b0093ba6465b59bd785c18f757e76945f65594c"},
|
||||
{file = "psycopg2-2.9.8-cp37-cp37m-win_amd64.whl", hash = "sha256:67c2f32f3aba79afb15799575e77ee2db6b46b8acf943c21d34d02d4e1041d50"},
|
||||
{file = "psycopg2-2.9.8-cp38-cp38-win32.whl", hash = "sha256:287a64ef168ef7fb9f382964705ff664b342bfff47e7242bf0a04ef203269dd5"},
|
||||
{file = "psycopg2-2.9.8-cp38-cp38-win_amd64.whl", hash = "sha256:dcde3cad4920e29e74bf4e76c072649764914facb2069e6b7fa1ddbebcd49e9f"},
|
||||
{file = "psycopg2-2.9.8-cp39-cp39-win32.whl", hash = "sha256:d4ad050ea50a16731d219c3a85e8f2debf49415a070f0b8331ccc96c81700d9b"},
|
||||
{file = "psycopg2-2.9.8-cp39-cp39-win_amd64.whl", hash = "sha256:d39bb3959788b2c9d7bf5ff762e29f436172b241cd7b47529baac77746fd7918"},
|
||||
{file = "psycopg2-2.9.8.tar.gz", hash = "sha256:3da6488042a53b50933244085f3f91803f1b7271f970f3e5536efa69314f6a49"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -579,52 +579,52 @@ files = [
|
|||
|
||||
[[package]]
|
||||
name = "sqlalchemy"
|
||||
version = "2.0.20"
|
||||
version = "2.0.21"
|
||||
description = "Database Abstraction Library"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "SQLAlchemy-2.0.20-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:759b51346aa388c2e606ee206c0bc6f15a5299f6174d1e10cadbe4530d3c7a98"},
|
||||
{file = "SQLAlchemy-2.0.20-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1506e988ebeaaf316f183da601f24eedd7452e163010ea63dbe52dc91c7fc70e"},
|
||||
{file = "SQLAlchemy-2.0.20-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5768c268df78bacbde166b48be788b83dddaa2a5974b8810af422ddfe68a9bc8"},
|
||||
{file = "SQLAlchemy-2.0.20-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a3f0dd6d15b6dc8b28a838a5c48ced7455c3e1fb47b89da9c79cc2090b072a50"},
|
||||
{file = "SQLAlchemy-2.0.20-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:243d0fb261f80a26774829bc2cee71df3222587ac789b7eaf6555c5b15651eed"},
|
||||
{file = "SQLAlchemy-2.0.20-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6eb6d77c31e1bf4268b4d61b549c341cbff9842f8e115ba6904249c20cb78a61"},
|
||||
{file = "SQLAlchemy-2.0.20-cp310-cp310-win32.whl", hash = "sha256:bcb04441f370cbe6e37c2b8d79e4af9e4789f626c595899d94abebe8b38f9a4d"},
|
||||
{file = "SQLAlchemy-2.0.20-cp310-cp310-win_amd64.whl", hash = "sha256:d32b5ffef6c5bcb452723a496bad2d4c52b346240c59b3e6dba279f6dcc06c14"},
|
||||
{file = "SQLAlchemy-2.0.20-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:dd81466bdbc82b060c3c110b2937ab65ace41dfa7b18681fdfad2f37f27acdd7"},
|
||||
{file = "SQLAlchemy-2.0.20-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6fe7d61dc71119e21ddb0094ee994418c12f68c61b3d263ebaae50ea8399c4d4"},
|
||||
{file = "SQLAlchemy-2.0.20-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4e571af672e1bb710b3cc1a9794b55bce1eae5aed41a608c0401885e3491179"},
|
||||
{file = "SQLAlchemy-2.0.20-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3364b7066b3c7f4437dd345d47271f1251e0cfb0aba67e785343cdbdb0fff08c"},
|
||||
{file = "SQLAlchemy-2.0.20-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1be86ccea0c965a1e8cd6ccf6884b924c319fcc85765f16c69f1ae7148eba64b"},
|
||||
{file = "SQLAlchemy-2.0.20-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1d35d49a972649b5080557c603110620a86aa11db350d7a7cb0f0a3f611948a0"},
|
||||
{file = "SQLAlchemy-2.0.20-cp311-cp311-win32.whl", hash = "sha256:27d554ef5d12501898d88d255c54eef8414576f34672e02fe96d75908993cf53"},
|
||||
{file = "SQLAlchemy-2.0.20-cp311-cp311-win_amd64.whl", hash = "sha256:411e7f140200c02c4b953b3dbd08351c9f9818d2bd591b56d0fa0716bd014f1e"},
|
||||
{file = "SQLAlchemy-2.0.20-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3c6aceebbc47db04f2d779db03afeaa2c73ea3f8dcd3987eb9efdb987ffa09a3"},
|
||||
{file = "SQLAlchemy-2.0.20-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7d3f175410a6db0ad96b10bfbb0a5530ecd4fcf1e2b5d83d968dd64791f810ed"},
|
||||
{file = "SQLAlchemy-2.0.20-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea8186be85da6587456c9ddc7bf480ebad1a0e6dcbad3967c4821233a4d4df57"},
|
||||
{file = "SQLAlchemy-2.0.20-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c3d99ba99007dab8233f635c32b5cd24fb1df8d64e17bc7df136cedbea427897"},
|
||||
{file = "SQLAlchemy-2.0.20-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:76fdfc0f6f5341987474ff48e7a66c3cd2b8a71ddda01fa82fedb180b961630a"},
|
||||
{file = "SQLAlchemy-2.0.20-cp37-cp37m-win32.whl", hash = "sha256:d3793dcf5bc4d74ae1e9db15121250c2da476e1af8e45a1d9a52b1513a393459"},
|
||||
{file = "SQLAlchemy-2.0.20-cp37-cp37m-win_amd64.whl", hash = "sha256:79fde625a0a55220d3624e64101ed68a059c1c1f126c74f08a42097a72ff66a9"},
|
||||
{file = "SQLAlchemy-2.0.20-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:599ccd23a7146e126be1c7632d1d47847fa9f333104d03325c4e15440fc7d927"},
|
||||
{file = "SQLAlchemy-2.0.20-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1a58052b5a93425f656675673ef1f7e005a3b72e3f2c91b8acca1b27ccadf5f4"},
|
||||
{file = "SQLAlchemy-2.0.20-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79543f945be7a5ada9943d555cf9b1531cfea49241809dd1183701f94a748624"},
|
||||
{file = "SQLAlchemy-2.0.20-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63e73da7fb030ae0a46a9ffbeef7e892f5def4baf8064786d040d45c1d6d1dc5"},
|
||||
{file = "SQLAlchemy-2.0.20-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3ce5e81b800a8afc870bb8e0a275d81957e16f8c4b62415a7b386f29a0cb9763"},
|
||||
{file = "SQLAlchemy-2.0.20-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:cb0d3e94c2a84215532d9bcf10229476ffd3b08f481c53754113b794afb62d14"},
|
||||
{file = "SQLAlchemy-2.0.20-cp38-cp38-win32.whl", hash = "sha256:8dd77fd6648b677d7742d2c3cc105a66e2681cc5e5fb247b88c7a7b78351cf74"},
|
||||
{file = "SQLAlchemy-2.0.20-cp38-cp38-win_amd64.whl", hash = "sha256:6f8a934f9dfdf762c844e5164046a9cea25fabbc9ec865c023fe7f300f11ca4a"},
|
||||
{file = "SQLAlchemy-2.0.20-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:26a3399eaf65e9ab2690c07bd5cf898b639e76903e0abad096cd609233ce5208"},
|
||||
{file = "SQLAlchemy-2.0.20-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4cde2e1096cbb3e62002efdb7050113aa5f01718035ba9f29f9d89c3758e7e4e"},
|
||||
{file = "SQLAlchemy-2.0.20-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1b09ba72e4e6d341bb5bdd3564f1cea6095d4c3632e45dc69375a1dbe4e26ec"},
|
||||
{file = "SQLAlchemy-2.0.20-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b74eeafaa11372627ce94e4dc88a6751b2b4d263015b3523e2b1e57291102f0"},
|
||||
{file = "SQLAlchemy-2.0.20-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:77d37c1b4e64c926fa3de23e8244b964aab92963d0f74d98cbc0783a9e04f501"},
|
||||
{file = "SQLAlchemy-2.0.20-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:eefebcc5c555803065128401a1e224a64607259b5eb907021bf9b175f315d2a6"},
|
||||
{file = "SQLAlchemy-2.0.20-cp39-cp39-win32.whl", hash = "sha256:3423dc2a3b94125094897118b52bdf4d37daf142cbcf26d48af284b763ab90e9"},
|
||||
{file = "SQLAlchemy-2.0.20-cp39-cp39-win_amd64.whl", hash = "sha256:5ed61e3463021763b853628aef8bc5d469fe12d95f82c74ef605049d810f3267"},
|
||||
{file = "SQLAlchemy-2.0.20-py3-none-any.whl", hash = "sha256:63a368231c53c93e2b67d0c5556a9836fdcd383f7e3026a39602aad775b14acf"},
|
||||
{file = "SQLAlchemy-2.0.20.tar.gz", hash = "sha256:ca8a5ff2aa7f3ade6c498aaafce25b1eaeabe4e42b73e25519183e4566a16fc6"},
|
||||
{file = "SQLAlchemy-2.0.21-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1e7dc99b23e33c71d720c4ae37ebb095bebebbd31a24b7d99dfc4753d2803ede"},
|
||||
{file = "SQLAlchemy-2.0.21-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7f0c4ee579acfe6c994637527c386d1c22eb60bc1c1d36d940d8477e482095d4"},
|
||||
{file = "SQLAlchemy-2.0.21-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f7d57a7e140efe69ce2d7b057c3f9a595f98d0bbdfc23fd055efdfbaa46e3a5"},
|
||||
{file = "SQLAlchemy-2.0.21-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ca38746eac23dd7c20bec9278d2058c7ad662b2f1576e4c3dbfcd7c00cc48fa"},
|
||||
{file = "SQLAlchemy-2.0.21-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3cf229704074bce31f7f47d12883afee3b0a02bb233a0ba45ddbfe542939cca4"},
|
||||
{file = "SQLAlchemy-2.0.21-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fb87f763b5d04a82ae84ccff25554ffd903baafba6698e18ebaf32561f2fe4aa"},
|
||||
{file = "SQLAlchemy-2.0.21-cp310-cp310-win32.whl", hash = "sha256:89e274604abb1a7fd5c14867a412c9d49c08ccf6ce3e1e04fffc068b5b6499d4"},
|
||||
{file = "SQLAlchemy-2.0.21-cp310-cp310-win_amd64.whl", hash = "sha256:e36339a68126ffb708dc6d1948161cea2a9e85d7d7b0c54f6999853d70d44430"},
|
||||
{file = "SQLAlchemy-2.0.21-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bf8eebccc66829010f06fbd2b80095d7872991bfe8415098b9fe47deaaa58063"},
|
||||
{file = "SQLAlchemy-2.0.21-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b977bfce15afa53d9cf6a632482d7968477625f030d86a109f7bdfe8ce3c064a"},
|
||||
{file = "SQLAlchemy-2.0.21-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ff3dc2f60dbf82c9e599c2915db1526d65415be323464f84de8db3e361ba5b9"},
|
||||
{file = "SQLAlchemy-2.0.21-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44ac5c89b6896f4740e7091f4a0ff2e62881da80c239dd9408f84f75a293dae9"},
|
||||
{file = "SQLAlchemy-2.0.21-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:87bf91ebf15258c4701d71dcdd9c4ba39521fb6a37379ea68088ce8cd869b446"},
|
||||
{file = "SQLAlchemy-2.0.21-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b69f1f754d92eb1cc6b50938359dead36b96a1dcf11a8670bff65fd9b21a4b09"},
|
||||
{file = "SQLAlchemy-2.0.21-cp311-cp311-win32.whl", hash = "sha256:af520a730d523eab77d754f5cf44cc7dd7ad2d54907adeb3233177eeb22f271b"},
|
||||
{file = "SQLAlchemy-2.0.21-cp311-cp311-win_amd64.whl", hash = "sha256:141675dae56522126986fa4ca713739d00ed3a6f08f3c2eb92c39c6dfec463ce"},
|
||||
{file = "SQLAlchemy-2.0.21-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7614f1eab4336df7dd6bee05bc974f2b02c38d3d0c78060c5faa4cd1ca2af3b8"},
|
||||
{file = "SQLAlchemy-2.0.21-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d59cb9e20d79686aa473e0302e4a82882d7118744d30bb1dfb62d3c47141b3ec"},
|
||||
{file = "SQLAlchemy-2.0.21-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a95aa0672e3065d43c8aa80080cdd5cc40fe92dc873749e6c1cf23914c4b83af"},
|
||||
{file = "SQLAlchemy-2.0.21-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:8c323813963b2503e54d0944813cd479c10c636e3ee223bcbd7bd478bf53c178"},
|
||||
{file = "SQLAlchemy-2.0.21-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:419b1276b55925b5ac9b4c7044e999f1787c69761a3c9756dec6e5c225ceca01"},
|
||||
{file = "SQLAlchemy-2.0.21-cp37-cp37m-win32.whl", hash = "sha256:4615623a490e46be85fbaa6335f35cf80e61df0783240afe7d4f544778c315a9"},
|
||||
{file = "SQLAlchemy-2.0.21-cp37-cp37m-win_amd64.whl", hash = "sha256:cca720d05389ab1a5877ff05af96551e58ba65e8dc65582d849ac83ddde3e231"},
|
||||
{file = "SQLAlchemy-2.0.21-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b4eae01faee9f2b17f08885e3f047153ae0416648f8e8c8bd9bc677c5ce64be9"},
|
||||
{file = "SQLAlchemy-2.0.21-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3eb7c03fe1cd3255811cd4e74db1ab8dca22074d50cd8937edf4ef62d758cdf4"},
|
||||
{file = "SQLAlchemy-2.0.21-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c2d494b6a2a2d05fb99f01b84cc9af9f5f93bf3e1e5dbdafe4bed0c2823584c1"},
|
||||
{file = "SQLAlchemy-2.0.21-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b19ae41ef26c01a987e49e37c77b9ad060c59f94d3b3efdfdbf4f3daaca7b5fe"},
|
||||
{file = "SQLAlchemy-2.0.21-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:fc6b15465fabccc94bf7e38777d665b6a4f95efd1725049d6184b3a39fd54880"},
|
||||
{file = "SQLAlchemy-2.0.21-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:014794b60d2021cc8ae0f91d4d0331fe92691ae5467a00841f7130fe877b678e"},
|
||||
{file = "SQLAlchemy-2.0.21-cp38-cp38-win32.whl", hash = "sha256:0268256a34806e5d1c8f7ee93277d7ea8cc8ae391f487213139018b6805aeaf6"},
|
||||
{file = "SQLAlchemy-2.0.21-cp38-cp38-win_amd64.whl", hash = "sha256:73c079e21d10ff2be54a4699f55865d4b275fd6c8bd5d90c5b1ef78ae0197301"},
|
||||
{file = "SQLAlchemy-2.0.21-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:785e2f2c1cb50d0a44e2cdeea5fd36b5bf2d79c481c10f3a88a8be4cfa2c4615"},
|
||||
{file = "SQLAlchemy-2.0.21-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c111cd40910ffcb615b33605fc8f8e22146aeb7933d06569ac90f219818345ef"},
|
||||
{file = "SQLAlchemy-2.0.21-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9cba4e7369de663611ce7460a34be48e999e0bbb1feb9130070f0685e9a6b66"},
|
||||
{file = "SQLAlchemy-2.0.21-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50a69067af86ec7f11a8e50ba85544657b1477aabf64fa447fd3736b5a0a4f67"},
|
||||
{file = "SQLAlchemy-2.0.21-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ccb99c3138c9bde118b51a289d90096a3791658da9aea1754667302ed6564f6e"},
|
||||
{file = "SQLAlchemy-2.0.21-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:513fd5b6513d37e985eb5b7ed89da5fd9e72354e3523980ef00d439bc549c9e9"},
|
||||
{file = "SQLAlchemy-2.0.21-cp39-cp39-win32.whl", hash = "sha256:f9fefd6298433b6e9188252f3bff53b9ff0443c8fde27298b8a2b19f6617eeb9"},
|
||||
{file = "SQLAlchemy-2.0.21-cp39-cp39-win_amd64.whl", hash = "sha256:2e617727fe4091cedb3e4409b39368f424934c7faa78171749f704b49b4bb4ce"},
|
||||
{file = "SQLAlchemy-2.0.21-py3-none-any.whl", hash = "sha256:ea7da25ee458d8f404b93eb073116156fd7d8c2a776d8311534851f28277b4ce"},
|
||||
{file = "SQLAlchemy-2.0.21.tar.gz", hash = "sha256:05b971ab1ac2994a14c56b35eaaa91f86ba080e9ad481b20d99d77f381bb6258"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
|
|
|
@ -80,6 +80,10 @@ def create_app(test_config=None):
|
|||
|
||||
app.register_blueprint(bp_blog)
|
||||
|
||||
from pyproger.errors import bp as bp_errors
|
||||
|
||||
app.register_blueprint(bp_errors)
|
||||
|
||||
@security.context_processor
|
||||
def security_context_processor():
|
||||
return dict(
|
||||
|
|
|
@ -1,20 +1,32 @@
|
|||
import locale
|
||||
|
||||
from flask import (redirect, render_template, render_template_string, request,
|
||||
session, url_for)
|
||||
from flask import (
|
||||
abort,
|
||||
current_app,
|
||||
redirect,
|
||||
render_template,
|
||||
request,
|
||||
session,
|
||||
url_for,
|
||||
)
|
||||
|
||||
from ..dbase.database import (get_all_posts_by_tag, get_paginated_posts,
|
||||
get_post, get_tags)
|
||||
from ..dbase.database import (
|
||||
get_all_posts_by_tag,
|
||||
get_paginated_posts,
|
||||
get_post,
|
||||
get_tags,
|
||||
)
|
||||
from .blog import bp
|
||||
|
||||
locale.setlocale(locale.LC_ALL, "")
|
||||
|
||||
|
||||
@bp.route("/", methods=["GET"], defaults={"page": 1})
|
||||
@bp.route("/<int:page>", methods=["GET"])
|
||||
@bp.route("/<int:page>")
|
||||
def index(page=1):
|
||||
session["back_url"] = request.url
|
||||
per_page = 2
|
||||
per_page = current_app.config.get("POSTS_ON_PAGE")
|
||||
|
||||
posts, total_pages = get_paginated_posts(page, per_page)
|
||||
list_pages = [
|
||||
x for x in range(1, total_pages + 1) if x >= page - 2 and x <= page + 2
|
||||
|
@ -36,6 +48,10 @@ def post(slug=None):
|
|||
back_url = session.get("back_url")
|
||||
if slug is not None:
|
||||
current_post = get_post(slug)
|
||||
|
||||
if current_post is None:
|
||||
return abort(404)
|
||||
|
||||
return render_template(
|
||||
"blog/postview.html",
|
||||
title=f"pyproger - {current_post.Post.title}",
|
||||
|
@ -44,7 +60,7 @@ def post(slug=None):
|
|||
back_url=back_url,
|
||||
)
|
||||
else:
|
||||
return render_template_string("noup")
|
||||
abort(404)
|
||||
|
||||
|
||||
@bp.route("/tags/")
|
||||
|
@ -59,13 +75,17 @@ def get_all_tags():
|
|||
|
||||
|
||||
@bp.route("/tag/", methods=["GET"], defaults={"page": 1})
|
||||
@bp.route("/tag/<path:tag>", methods=["GET"])
|
||||
def get_posts_by_tag(page=1):
|
||||
tag = request.args.get("tag")
|
||||
@bp.route("/tag/<path:tag>")
|
||||
def get_posts_by_tag(page=1, tag=None):
|
||||
if tag is None:
|
||||
return redirect(url_for(".get_all_tags"))
|
||||
per_page = 2
|
||||
tag = request.args.get("tag")
|
||||
if tag is None:
|
||||
return redirect(url_for(".get_all_tags"))
|
||||
per_page = current_app.config.get("POSTS_ON_PAGE")
|
||||
|
||||
posts, total_pages = get_all_posts_by_tag(tag, page, per_page)
|
||||
if posts is None:
|
||||
abort(404)
|
||||
list_pages = [
|
||||
x for x in range(1, total_pages + 1) if x >= page - 2 and x <= page + 2
|
||||
]
|
||||
|
@ -78,3 +98,25 @@ def get_posts_by_tag(page=1):
|
|||
total_pages=total_pages,
|
||||
list_pages=list_pages,
|
||||
)
|
||||
|
||||
|
||||
@bp.route("/about")
|
||||
def about():
|
||||
return render_template(
|
||||
"blog/page.html",
|
||||
title="pyproger - О сайте",
|
||||
menu_title="pyproger",
|
||||
content_head="О сайте",
|
||||
content_body="описание",
|
||||
)
|
||||
|
||||
|
||||
@bp.route("/contacts")
|
||||
def contacts():
|
||||
return render_template(
|
||||
"blog/page.html",
|
||||
title="pyproger - Контакты",
|
||||
menu_title="pyproger",
|
||||
content_head="Контакты",
|
||||
content_body="описание",
|
||||
)
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
import os
|
||||
|
||||
# Тема оформления админ панели
|
||||
FLASK_ADMIN_SWATCH = "slate"
|
||||
# Create secret key so we can use sessions
|
||||
|
||||
# python3: secrets.token_urlsafe()
|
||||
SECRET_KEY = "hxfjbcfry52"
|
||||
|
||||
# Create in-memory database
|
||||
# Настройки подключения к бд
|
||||
SQLALCHEMY_DATABASE_URI = "postgresql+psycopg2://pi3c:@localhost/pyproger"
|
||||
# For debug - show every DB query
|
||||
SQLALCHEMY_ECHO = False
|
||||
|
||||
# Flask-Security config
|
||||
# Настройки Flask-Security
|
||||
SECURITY_URL_PREFIX = "/admin"
|
||||
SECURITY_PASSWORD_HASH = "pbkdf2_sha512"
|
||||
SECURITY_PASSWORD_SALT = "ATGUOHAELKiubahiughaerGOJAEGj"
|
||||
SECURITY_TRACKABLE = True
|
||||
|
||||
# Flask-Security URLs, overridden because they don't put a / at the end
|
||||
SECURITY_LOGIN_URL = "/login/"
|
||||
SECURITY_LOGOUT_URL = "/logout/"
|
||||
SECURITY_REGISTER_URL = "/register/"
|
||||
|
@ -26,18 +26,23 @@ SECURITY_POST_LOGOUT_VIEW = "/admin/"
|
|||
SECURITY_POST_REGISTER_VIEW = "/admin/"
|
||||
SECURITY_POST_RESET_VIEW = "/admin/"
|
||||
|
||||
# Flask-Security features
|
||||
SECURITY_REGISTERABLE = False
|
||||
SECURITY_CHANGEABLE = True
|
||||
SECURITY_RECOVERABLE = False
|
||||
SQLALCHEMY_TRACK_MODIFICATIONS = False
|
||||
|
||||
# For demo - no email
|
||||
SECURITY_SEND_REGISTER_EMAIL = False
|
||||
SECURITY_SEND_PASSWORD_CHANGE_EMAIL = False
|
||||
SECURITY_SEND_PASSWORD_RESET_EMAIL = False
|
||||
SECURITY_SEND_PASSWORD_RESET_NOTICE_EMAIL = False
|
||||
|
||||
# Flask-Babel
|
||||
# Настройки Flask-Babel необходимые для русификации админки
|
||||
LANGUAGES = ["ru"]
|
||||
BABEL_TRANSLATION_DIRECTORIES = os.path.join(os.path.curdir, "translations")
|
||||
|
||||
CKEDITOR_PKG_TYPE = "full"
|
||||
CKEDITOR_SERVE_LOCAL = True
|
||||
CKEDITOR_ENABLE_CODESNIPPET = True
|
||||
CKEDITOR_CODE_THEME = "monokai_sublime"
|
||||
# Настройки блога
|
||||
POSTS_ON_PAGE = 6
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
from logging import error
|
||||
|
||||
from . import db
|
||||
from .models import Post, Tag, User
|
||||
|
||||
|
@ -44,5 +42,6 @@ def get_all_posts_by_tag(tag, page, per_page):
|
|||
total_pages = (
|
||||
posts_query.total // per_page + [0, 1][posts_query.total % per_page != 0]
|
||||
)
|
||||
print(posts_query)
|
||||
if posts_query.total == 0:
|
||||
return None, None
|
||||
return posts_query, total_pages
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
from flask import Blueprint
|
||||
|
||||
bp = Blueprint(
|
||||
"errors",
|
||||
__name__,
|
||||
)
|
||||
|
||||
from . import routes
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
from flask import render_template, url_for
|
||||
|
||||
from . import bp
|
||||
|
||||
|
||||
@bp.app_errorhandler(404)
|
||||
def handle_404(err):
|
||||
return (
|
||||
render_template(
|
||||
"errors/404.html",
|
||||
title="pyproger - Страница не найдена",
|
||||
menu_title="pyproger",
|
||||
),
|
||||
404,
|
||||
)
|
|
@ -1,14 +1,6 @@
|
|||
{% extends 'admin/model/edit.html' %}
|
||||
|
||||
{% block tail %}
|
||||
{{ super() }}
|
||||
{{ ckeditor.load() }}
|
||||
{#
|
||||
if you have set the configuration variables more than CKEDITOR_SERVE_LOCAL and CKEDITOR_PKG_TYPE,
|
||||
or you need to config the CKEditor textarea, use the line below to register the configuration.
|
||||
The name value should be the name of the CKEditor form field.
|
||||
#}
|
||||
{{ ckeditor.config(name='Title') }}
|
||||
|
||||
{{ ckeditor.config(name='Text') }}
|
||||
{{ super() }}
|
||||
{{ ckeditor.load() }}
|
||||
{% endblock %}
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
<nav class="page-header navbar p-2 navbar-expand-lg bg-dark border-bottom border-bottom-dark rounded-bottom-4"
|
||||
data-bs-theme="dark">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="{{ url_for(".index")}}">
|
||||
<a class="navbar-brand" href="{{ url_for("bp_blog.index")}}">
|
||||
{% block menu_title %}
|
||||
|
||||
{% endblock menu_title %}</a>
|
||||
|
@ -34,8 +34,24 @@
|
|||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||
<ul class="text-body navbar-nav me-auto mb-2 mb-lg-0">
|
||||
text
|
||||
<ul class="text-body navbar-nav me-auto mb-2 mb-lg-0 p-3">
|
||||
<li>
|
||||
<a class="link-offset-2 link-underline link-underline-opacity-0 text-white"
|
||||
href="{{ url_for('bp_blog.index')}}">Главная
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="link-offset-2 link-underline link-underline-opacity-0 text-white"
|
||||
href="{{ url_for('bp_blog.get_all_tags')}}">Статьи по темам</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="link-offset-2 link-underline link-underline-opacity-0 text-white"
|
||||
href="{{ url_for('bp_blog.about') }}">О сайте</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="link-offset-2 link-underline link-underline-opacity-0 text-white"
|
||||
href="{{ url_for('bp_blog.contacts') }}">Контакты</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -101,20 +117,20 @@
|
|||
<ul class="list-unstyled mb-0">
|
||||
<li>
|
||||
<a class="link-offset-2 link-underline link-underline-opacity-0 text-white"
|
||||
href="{{ url_for('.index')}}">Главная
|
||||
href="{{ url_for('bp_blog.index')}}">Главная
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="link-offset-2 link-underline link-underline-opacity-0 text-white"
|
||||
href="{{ url_for('.get_all_tags')}}">Тэги статей</a>
|
||||
href="{{ url_for('bp_blog.get_all_tags')}}">Статьи по темам</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="link-offset-2 link-underline link-underline-opacity-0 text-white"
|
||||
href="#!">О сайте</a>
|
||||
href="{{ url_for('bp_blog.about') }}">О сайте</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="link-offset-2 link-underline link-underline-opacity-0 text-white"
|
||||
href="#">Контакты</a>
|
||||
href="{{ url_for('bp_blog.contacts') }}">Контакты</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
@ -9,29 +9,30 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="container">
|
||||
{% for p in posts %}
|
||||
<a href="{{ url_for(".post", slug=p.Post.slug )}}" class="list-group-item list-group-item-action border-0">
|
||||
<h5 class="post-title">{{ p.Post.title | safe }}</h5>
|
||||
{{ p.Post.description | safe}}
|
||||
</a>
|
||||
<small>
|
||||
|
||||
{% for t in p.Post.tags %}
|
||||
<a class="link-offset-2 link-offset-3-hover link-underline link-underline-opacity-0 link-underline-opacity-75-hover" href="{{url_for(".get_posts_by_tag", tag=t.tag )}}">
|
||||
#{{t.tag}}
|
||||
</a>
|
||||
{% endfor %}<br>
|
||||
Опубликовал
|
||||
<a href="mailto:{{p.User.email}}">
|
||||
{{ p.User.username}}
|
||||
<div class="containet-fluid p-3">
|
||||
<a href="{{ url_for(".post", slug=p.Post.slug )}}" class="list-group-item list-group-item-action border-0">
|
||||
<h5 class="post-title">{{ p.Post.title | safe }}</h5>
|
||||
{{ p.Post.description | safe}}
|
||||
</a>
|
||||
<small>
|
||||
{% for t in p.Post.tags %}
|
||||
<a class="link-offset-2 link-offset-3-hover link-underline link-underline-opacity-0 link-underline-opacity-75-hover" href="{{url_for(".get_posts_by_tag", tag=t.tag )}}">
|
||||
#{{t.tag}}
|
||||
</a>
|
||||
{{ p.Post.create_datetime.strftime('%d %B, %Y') }}
|
||||
</small>
|
||||
{% endfor %}
|
||||
{% endfor %}<br>
|
||||
|
||||
<nav class="container">
|
||||
<ul class="pagination justify-content-start"
|
||||
Опубликовал
|
||||
<a href="mailto:{{p.User.email}}">{{ p.User.username}}</a>
|
||||
{{ p.Post.create_datetime.strftime('%d %B, %Y') }}
|
||||
</small>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<nav class="container p-3">
|
||||
<ul class="pagination justify-content-center"
|
||||
{% if posts.has_prev %}
|
||||
<li class="page-item"><a class="page-link" href="{{ url_for(".index", page=posts.prev_num)}}"><<</a></li>
|
||||
{% else %}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
{% extends 'blog/base.html' %}
|
||||
|
||||
{% block title %}
|
||||
{{title}}
|
||||
{% endblock %}
|
||||
|
||||
{% block menu_title %}
|
||||
{{ menu_title }}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<!-- Main Content-->
|
||||
<div class="conteiner ">
|
||||
<div class="conteiner-fluid text-center fs-2 p-3">
|
||||
{{ content_head }}
|
||||
</div>
|
||||
|
||||
<div class="conteiner-fluid text-start p-3">
|
||||
{{ content_body | safe}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
|
@ -9,14 +9,9 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="conteiner px-4 px-lg-5">
|
||||
<br>
|
||||
<div class="conteiner p-4 px-lg-5">
|
||||
<h4>{{ post.Post.title | safe }}</h4>
|
||||
{{ post.Post.text | safe }}
|
||||
<a class="link-offset-2 link-offset-3-hover link-underline link-underline-opacity-0 link-underline-opacity-75-hover" href="{{ back_url }}">
|
||||
Назад
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
{% extends 'blog/base.html' %}
|
||||
|
||||
{% block title %}{{title}}{% endblock title %}
|
||||
|
||||
{% block menu_title %} {{ menu_title }} {% endblock menu_title %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container-fluid p-3">
|
||||
<div class="row text-center p-2">
|
||||
<div class="fs-4">Страница не найдена</div>
|
||||
</div>
|
||||
|
||||
<div class="row text-center p-1">
|
||||
<strong class="fs-1"><404></strong>
|
||||
</div>
|
||||
|
||||
<div class="row text-center p-1">
|
||||
<div class="fs-6">Запрашиваемая Вами страница не найдена</div>
|
||||
<div class="fs-6">Можете выбрать статьи по темам, перейдя в соответствующий раздел
|
||||
<a class="link-offset-2 link-offset-3-hover link-underline link-underline-opacity-0 link-underline-opacity-75-hover"
|
||||
href="{{ url_for('bp_blog.get_all_tags')}}">по ссылке</a></div>
|
||||
<div class="fs-6">или просмотреть все статьи на <a class="link-offset-2 link-offset-3-hover link-underline link-underline-opacity-0 link-underline-opacity-75-hover"
|
||||
href="{{ url_for('bp_blog.index')}}">главной странице</a></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{% endblock content%}
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
import os
|
||||
|
||||
from flask import Blueprint, request
|
||||
from flask import Blueprint, current_app, request
|
||||
from flask_babel import Babel
|
||||
|
||||
|
||||
def get_locale():
|
||||
translations = ["ru"]
|
||||
translations = current_app.config.get("LANGUAGES")
|
||||
return request.accept_languages.best_match(translations)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue