Flask-Exts 0.1.7__tar.gz → 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {flask_exts-0.1.7 → flask_exts-0.2.0}/CHANGES.rst +22 -2
- {flask_exts-0.1.7 → flask_exts-0.2.0}/PKG-INFO +3 -2
- flask_exts-0.2.0/docs/conf.py +62 -0
- flask_exts-0.1.7/docs/usage.rst → flask_exts-0.2.0/docs/configure.rst +14 -40
- flask_exts-0.1.7/docs/translation.rst → flask_exts-0.2.0/docs/develop.rst +53 -12
- {flask_exts-0.1.7 → flask_exts-0.2.0}/docs/index.rst +22 -5
- flask_exts-0.2.0/docs/requirements.txt +2 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/examples/README.rst +24 -24
- flask_exts-0.2.0/examples/admin/fileadmin/admin_app.py +17 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/examples/bootstrap4/app.py +2 -2
- {flask_exts-0.1.7 → flask_exts-0.2.0}/examples/bootstrap4/templates/mybase.html +1 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/examples/bootstrap5/app.py +4 -4
- {flask_exts-0.1.7 → flask_exts-0.2.0}/examples/bootstrap5/templates/mybase.html +1 -0
- flask_exts-0.2.0/examples/demo/__init__.py +1 -0
- flask_exts-0.2.0/examples/demo/make_app.py +52 -0
- flask_exts-0.2.0/examples/demo/models/__init__.py +16 -0
- flask_exts-0.2.0/examples/demo/models/user.py +16 -0
- flask_exts-0.2.0/examples/demo/sample.sqlite +0 -0
- flask_exts-0.2.0/examples/demo/templates/my/index.html +6 -0
- flask_exts-0.2.0/examples/demo/user_center.py +54 -0
- flask_exts-0.2.0/examples/demo/views/my_view.py +10 -0
- flask_exts-0.2.0/examples/simple.py +17 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/pyproject.toml +1 -0
- flask_exts-0.2.0/src/flask_exts/__about__.py +1 -0
- flask_exts-0.2.0/src/flask_exts/admin/actions.py +121 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/admin/admin.py +59 -40
- flask_exts-0.2.0/src/flask_exts/admin/file_admin/__init__.py +1 -0
- flask_exts-0.2.0/src/flask_exts/admin/file_admin/base_file_admin.py +1162 -0
- flask_exts-0.2.0/src/flask_exts/admin/file_admin/local_file_admin.py +15 -0
- flask_exts-0.2.0/src/flask_exts/admin/file_admin/local_file_storage.py +122 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/admin/menu.py +3 -4
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/admin/view.py +24 -48
- flask_exts-0.1.7/src/flask_exts/admin/admin_index_view.py → flask_exts-0.2.0/src/flask_exts/admin/views/index_view.py +15 -10
- flask_exts-0.2.0/src/flask_exts/admin/views/user_view.py +129 -0
- flask_exts-0.2.0/src/flask_exts/forms/__init__.py +1 -0
- flask_exts-0.2.0/src/flask_exts/forms/fields/__init__.py +4 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/forms/fields/datetime.py +4 -4
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/forms/fields/select.py +3 -3
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/forms/fields/taglist.py +2 -3
- flask_exts-0.2.0/src/flask_exts/forms/form/__init__.py +2 -0
- flask_exts-0.2.0/src/flask_exts/forms/form/base_form.py +16 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/forms/form/csrf.py +5 -7
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/forms/form/flask_form.py +1 -11
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/forms/form/meta.py +9 -5
- flask_exts-0.2.0/src/flask_exts/forms/form/session_csrf.py +31 -0
- flask_exts-0.2.0/src/flask_exts/forms/utils.py +32 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/forms/widgets/recaptcha.py +1 -5
- flask_exts-0.2.0/src/flask_exts/forms/widgets/select.py +77 -0
- flask_exts-0.2.0/src/flask_exts/forms/widgets/xeditable.py +115 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/manager.py +6 -4
- flask_exts-0.2.0/src/flask_exts/static/admin/css/admin.css +110 -0
- flask_exts-0.2.0/src/flask_exts/static/admin/css/rediscli.css +48 -0
- flask_exts-0.2.0/src/flask_exts/static/admin/css/submenu.css +18 -0
- flask_exts-0.2.0/src/flask_exts/static/admin/js/actions.js +51 -0
- flask_exts-0.2.0/src/flask_exts/static/admin/js/bs4_filters.js +202 -0
- flask_exts-0.2.0/src/flask_exts/static/admin/js/details_filter.js +10 -0
- flask_exts-0.2.0/src/flask_exts/static/admin/js/filters.js +195 -0
- flask_exts-0.2.0/src/flask_exts/static/admin/js/form.js +667 -0
- flask_exts-0.2.0/src/flask_exts/static/admin/js/helpers.js +12 -0
- flask_exts-0.2.0/src/flask_exts/static/admin/js/modal.js +5 -0
- flask_exts-0.2.0/src/flask_exts/static/admin/js/rediscli.js +121 -0
- flask_exts-0.2.0/src/flask_exts/static/logo.png +0 -0
- flask_exts-0.2.0/src/flask_exts/static/vendor/jquery/jquery.min.js +2 -0
- flask_exts-0.2.0/src/flask_exts/template/__init__.py +35 -0
- flask_exts-0.2.0/src/flask_exts/template/theme.py +56 -0
- flask_exts-0.2.0/src/flask_exts/template/utils.py +61 -0
- flask_exts-0.2.0/src/flask_exts/templates/admin/actions.html +58 -0
- flask_exts-0.1.7/examples/admin/simple/templates/myadmin.html → flask_exts-0.2.0/src/flask_exts/templates/admin/admin.html +2 -1
- flask_exts-0.2.0/src/flask_exts/templates/admin/base.html +46 -0
- flask_exts-0.2.0/src/flask_exts/templates/admin/file/form.html +9 -0
- flask_exts-0.2.0/src/flask_exts/templates/admin/file/list.html +192 -0
- flask_exts-0.2.0/src/flask_exts/templates/admin/file/modals/form.html +13 -0
- flask_exts-0.2.0/src/flask_exts/templates/admin/index.html +6 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/templates/admin/layout.html +27 -25
- flask_exts-0.2.0/src/flask_exts/templates/admin/lib.html +276 -0
- flask_exts-0.2.0/src/flask_exts/templates/admin/master.html +1 -0
- flask_exts-0.2.0/src/flask_exts/templates/admin/user/index.html +7 -0
- flask_exts-0.2.0/src/flask_exts/templates/admin/user/list.html +7 -0
- flask_exts-0.2.0/src/flask_exts/templates/admin/user/login.html +19 -0
- flask_exts-0.2.0/src/flask_exts/templates/admin/user/register.html +20 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/templates/base.html +1 -2
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/templates/bootstrap4/form.html +2 -2
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/templates/bootstrap5/form.html +4 -4
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/templates/layout.html +6 -7
- flask_exts-0.2.0/src/flask_exts/templates/macro/form.html +16 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/templates/macro/icon.html +1 -1
- flask_exts-0.2.0/src/flask_exts/templates/macro/message.html +17 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/templates/macro/table.html +5 -4
- flask_exts-0.2.0/src/flask_exts/users/__init__.py +15 -0
- flask_exts-0.2.0/src/flask_exts/users/default_usercenter.py +51 -0
- flask_exts-0.2.0/src/flask_exts/users/forms/__init__.py +2 -0
- flask_exts-0.2.0/src/flask_exts/users/forms/login.py +6 -0
- flask_exts-0.2.0/src/flask_exts/users/forms/mixins.py +29 -0
- flask_exts-0.2.0/src/flask_exts/users/forms/profile.py +11 -0
- flask_exts-0.2.0/src/flask_exts/users/forms/register.py +6 -0
- flask_exts-0.2.0/src/flask_exts/users/usercenter.py +19 -0
- flask_exts-0.2.0/src/flask_exts/utils/__init__.py +9 -0
- flask_exts-0.2.0/tests/admin/fileadmin/test_fileadmin.py +238 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/tests/admin/test_base.py +138 -152
- flask_exts-0.2.0/tests/admin/test_user_view.py +65 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/tests/conftest.py +1 -6
- flask_exts-0.2.0/tests/forms/test_fields.py +76 -0
- flask_exts-0.2.0/tests/forms/test_form.py +37 -0
- flask_exts-0.1.7/tests/forms/test_upload_file.py → flask_exts-0.2.0/tests/forms/test_uploadfile.py +24 -17
- {flask_exts-0.1.7 → flask_exts-0.2.0}/tests/funcs.py +1 -1
- flask_exts-0.2.0/tests/template/bootstrap4/__init__.py +0 -0
- {flask_exts-0.1.7/tests/templating → flask_exts-0.2.0/tests/template}/bootstrap4/test_render_form.py +1 -1
- flask_exts-0.2.0/tests/template/bootstrap5/__init__.py +0 -0
- {flask_exts-0.1.7/tests/templating → flask_exts-0.2.0/tests/template}/bootstrap5/conftest.py +5 -4
- {flask_exts-0.1.7/tests/templating → flask_exts-0.2.0/tests/template}/bootstrap5/test_base.py +1 -2
- {flask_exts-0.1.7/tests/templating → flask_exts-0.2.0/tests/template}/bootstrap5/test_render_form.py +4 -4
- {flask_exts-0.1.7/tests/templating/element → flask_exts-0.2.0/tests/template/macros}/test_render_nav_item.py +0 -1
- {flask_exts-0.1.7/tests/templating → flask_exts-0.2.0/tests/template}/test_base.py +3 -4
- flask_exts-0.2.0/tests/templates/mock.html +1 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/tests/test_babel.py +18 -12
- {flask_exts-0.1.7 → flask_exts-0.2.0}/tests/test_base.py +5 -4
- flask_exts-0.1.7/docs/api.rst +0 -4
- flask_exts-0.1.7/docs/conf.py +0 -36
- flask_exts-0.1.7/docs/develop.rst +0 -46
- flask_exts-0.1.7/docs/fields.rst +0 -36
- flask_exts-0.1.7/docs/forms.rst +0 -9
- flask_exts-0.1.7/docs/requirements.txt +0 -3
- flask_exts-0.1.7/docs/templating.rst +0 -29
- flask_exts-0.1.7/examples/admin/simple/admin_app.py +0 -25
- flask_exts-0.1.7/examples/admin/simple/templates/admin/index.html +0 -22
- flask_exts-0.1.7/examples/admin/simple/templates/anotheradmin.html +0 -5
- flask_exts-0.1.7/examples/admin/simple/templates/test.html +0 -5
- flask_exts-0.1.7/examples/start/__init__.py +0 -1
- flask_exts-0.1.7/examples/start/make_app.py +0 -24
- flask_exts-0.1.7/examples/start/models/__init__.py +0 -24
- flask_exts-0.1.7/examples/start/register_blueprints.py +0 -36
- flask_exts-0.1.7/examples/start/templates/upload.html +0 -15
- flask_exts-0.1.7/examples/update-icons.py +0 -49
- flask_exts-0.1.7/requirements/develop.in +0 -1
- flask_exts-0.1.7/src/flask_exts/__about__.py +0 -1
- flask_exts-0.1.7/src/flask_exts/forms/__init__.py +0 -3
- flask_exts-0.1.7/src/flask_exts/forms/fields/__init__.py +0 -2
- flask_exts-0.1.7/src/flask_exts/forms/form/__init__.py +0 -2
- flask_exts-0.1.7/src/flask_exts/forms/form/base_form.py +0 -5
- flask_exts-0.1.7/src/flask_exts/forms/form/secure_form.py +0 -33
- flask_exts-0.1.7/src/flask_exts/forms/widgets/select.py +0 -26
- flask_exts-0.1.7/src/flask_exts/forms/widgets/template.py +0 -25
- flask_exts-0.1.7/src/flask_exts/static/vendor/jquery/jquery.slim.min.js +0 -2
- flask_exts-0.1.7/src/flask_exts/templates/admin/base.html +0 -41
- flask_exts-0.1.7/src/flask_exts/templates/admin/index.html +0 -2
- flask_exts-0.1.7/src/flask_exts/templates/admin/master.html +0 -1
- flask_exts-0.1.7/src/flask_exts/templates/demo.html +0 -7
- flask_exts-0.1.7/src/flask_exts/templates/macro/form.html +0 -5
- flask_exts-0.1.7/src/flask_exts/templating/__init__.py +0 -40
- flask_exts-0.1.7/src/flask_exts/templating/theme.py +0 -136
- flask_exts-0.1.7/src/flask_exts/utils/__init__.py +0 -4
- flask_exts-0.1.7/src/flask_exts/utils/csrf.py +0 -130
- flask_exts-0.1.7/src/flask_exts/utils/form.py +0 -63
- flask_exts-0.1.7/tests/forms/test_field_list.py +0 -41
- flask_exts-0.1.7/tests/forms/test_form.py +0 -59
- flask_exts-0.1.7/tests/templates/mock.html +0 -1
- flask_exts-0.1.7/tests/utils/test_csrf.py +0 -17
- {flask_exts-0.1.7 → flask_exts-0.2.0}/.github/workflows/release.yml +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/.gitignore +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/.readthedocs.yaml +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/LICENSE.rst +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/README.rst +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/babel/babel.cfg +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/babel/babel.sh +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/babel/crowdin_pull.sh +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/babel/crowdin_push.sh +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/babel/messages.pot +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/docs/Makefile +0 -0
- {flask_exts-0.1.7/src/flask_exts/static → flask_exts-0.2.0/docs/_static}/logo.png +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/docs/changes.rst +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/docs/examples.rst +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/docs/make.bat +0 -0
- {flask_exts-0.1.7/examples/admin/simple → flask_exts-0.2.0/examples/admin/fileadmin}/__init__.py +0 -0
- {flask_exts-0.1.7/examples/admin/simple → flask_exts-0.2.0/examples/admin/fileadmin}/make_app.py +0 -0
- /flask_exts-0.1.7/src/flask_exts/forms/widgets/__init__.py → /flask_exts-0.2.0/examples/admin/fileadmin/tmp/bbb/a.txt +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/examples/bootstrap4/static/favicon.ico +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/examples/bootstrap4/templates/bootswatch.html +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/examples/bootstrap4/templates/flash.html +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/examples/bootstrap4/templates/form.html +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/examples/bootstrap4/templates/icon.html +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/examples/bootstrap4/templates/icons.html +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/examples/bootstrap4/templates/index.html +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/examples/bootstrap4/templates/nav.html +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/examples/bootstrap4/templates/pagination.html +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/examples/bootstrap4/templates/table.html +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/examples/bootstrap5/static/favicon.ico +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/examples/bootstrap5/templates/bootswatch.html +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/examples/bootstrap5/templates/flash.html +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/examples/bootstrap5/templates/form.html +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/examples/bootstrap5/templates/icon.html +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/examples/bootstrap5/templates/icons.html +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/examples/bootstrap5/templates/index.html +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/examples/bootstrap5/templates/nav.html +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/examples/bootstrap5/templates/pagination.html +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/examples/bootstrap5/templates/table.html +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/requirements/build.in +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/requirements/test.in +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/__init__.py +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/admin/__init__.py +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/admin/wraps.py +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/babel/__init__.py +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/babel/selector.py +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/forms/fields/file.py +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/forms/fields/json.py +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/forms/fields/recaptcha.py +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/forms/fields/switch.py +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/forms/rules.py +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/forms/validators/__init__.py +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/forms/validators/field_list.py +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/forms/validators/file.py +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/forms/validators/recaptcha.py +0 -0
- {flask_exts-0.1.7/src/flask_exts/plugins → flask_exts-0.2.0/src/flask_exts/forms/widgets}/__init__.py +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/forms/widgets/datetime.py +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/forms/widgets/file.py +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/static/vendor/bootstrap-icons/bootstrap-icons.svg +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/static/vendor/bootstrap4/bootstrap.bundle.min.js +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/static/vendor/bootstrap4/bootstrap.min.css +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/static/vendor/bootstrap5/bootstrap.bundle.min.js +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/static/vendor/bootstrap5/bootstrap.min.css +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/templates/bootstrap4/message.html +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/templates/bootstrap5/message.html +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/templates/macro/nav.html +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/templates/macro/pagination.html +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/templates/macro/static.html +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/translations/__init__.py +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/translations/en/LC_MESSAGES/messages.mo +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/translations/en/LC_MESSAGES/messages.po +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/translations/zh_CN/LC_MESSAGES/messages.mo +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/translations/zh_CN/LC_MESSAGES/messages.po +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/utils/g.py +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/src/flask_exts/utils/url.py +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/tests/__init__.py +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/tests/admin/__init__.py +0 -0
- {flask_exts-0.1.7/tests/templating → flask_exts-0.2.0/tests/admin/fileadmin}/__init__.py +0 -0
- /flask_exts-0.1.7/tests/templating/bootstrap4/__init__.py → /flask_exts-0.2.0/tests/admin/fileadmin/files/dummy.txt +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/tests/data/copyleft.gif +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/tests/data/copyleft.jpeg +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/tests/data/copyleft.jpg +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/tests/data/copyleft.png +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/tests/data/copyleft.tiff +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/tests/forms/test_filefield.py +0 -0
- {flask_exts-0.1.7/tests/templating/bootstrap5 → flask_exts-0.2.0/tests/template}/__init__.py +0 -0
- {flask_exts-0.1.7/tests/templating → flask_exts-0.2.0/tests/template}/bootstrap4/conftest.py +0 -0
- {flask_exts-0.1.7/tests/templating → flask_exts-0.2.0/tests/template}/bootstrap4/test_render_field.py +0 -0
- {flask_exts-0.1.7/tests/templating → flask_exts-0.2.0/tests/template}/bootstrap4/test_render_form_row.py +0 -0
- {flask_exts-0.1.7/tests/templating → flask_exts-0.2.0/tests/template}/bootstrap4/test_render_hidden_errors.py +0 -0
- {flask_exts-0.1.7/tests/templating → flask_exts-0.2.0/tests/template}/bootstrap4/test_render_icon.py +0 -0
- {flask_exts-0.1.7/tests/templating → flask_exts-0.2.0/tests/template}/bootstrap4/test_render_messages.py +0 -0
- {flask_exts-0.1.7/tests/templating → flask_exts-0.2.0/tests/template}/bootstrap4/test_render_pager.py +0 -0
- {flask_exts-0.1.7/tests/templating → flask_exts-0.2.0/tests/template}/bootstrap4/test_render_pagination.py +0 -0
- {flask_exts-0.1.7/tests/templating → flask_exts-0.2.0/tests/template}/bootstrap4/test_render_table.py +0 -0
- {flask_exts-0.1.7/tests/templating → flask_exts-0.2.0/tests/template}/bootstrap5/test_pagination.py +0 -0
- {flask_exts-0.1.7/tests/templating → flask_exts-0.2.0/tests/template}/bootstrap5/test_render_form_row.py +0 -0
- {flask_exts-0.1.7/tests/templating → flask_exts-0.2.0/tests/template}/bootstrap5/test_render_messages.py +0 -0
- {flask_exts-0.1.7/tests/templating → flask_exts-0.2.0/tests/template}/conftest.py +0 -0
- {flask_exts-0.1.7/tests/templating/element → flask_exts-0.2.0/tests/template/macros}/test_render_breadcrumb_item.py +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/tests/templates/method.html +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/tests/translations/en/LC_MESSAGES/messages.mo +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/tests/translations/en/LC_MESSAGES/messages.po +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/tests/translations/messages.pot +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/tests/translations/zh_CN/LC_MESSAGES/messages.mo +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/tests/translations/zh_CN/LC_MESSAGES/messages.po +0 -0
- {flask_exts-0.1.7 → flask_exts-0.2.0}/tests/utils/test_url.py +0 -0
|
@@ -1,9 +1,30 @@
|
|
|
1
|
+
v0.2.0
|
|
2
|
+
------
|
|
3
|
+
|
|
4
|
+
Released 2025-01-07
|
|
5
|
+
|
|
6
|
+
- update templates.macros
|
|
7
|
+
|
|
8
|
+
v0.1.9
|
|
9
|
+
------
|
|
10
|
+
|
|
11
|
+
Released 2024-12-01
|
|
12
|
+
|
|
13
|
+
- add index_view
|
|
14
|
+
|
|
15
|
+
v0.1.8
|
|
16
|
+
------
|
|
17
|
+
|
|
18
|
+
Released 2024-11-24
|
|
19
|
+
|
|
20
|
+
- add user_view
|
|
21
|
+
|
|
1
22
|
v0.1.7
|
|
2
23
|
------
|
|
3
24
|
|
|
4
25
|
Released 2024-10-13
|
|
5
26
|
|
|
6
|
-
- add theme for
|
|
27
|
+
- add theme for template
|
|
7
28
|
- admin view framework
|
|
8
29
|
|
|
9
30
|
v0.1.6
|
|
@@ -14,7 +35,6 @@ Released 2024-09-14
|
|
|
14
35
|
- merge translations of wtforms, flask_exts and app into flask_babel.get_translations()
|
|
15
36
|
- update FileField and ImageField
|
|
16
37
|
- add url for template.static
|
|
17
|
-
- use namespace ns.bootstrap to control bootstrap's css and js
|
|
18
38
|
|
|
19
39
|
v0.1.5
|
|
20
40
|
------
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: Flask-Exts
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Flask extensions with admin, SQLAlchemy, babel, forms, fields, widgets, and so on.
|
|
5
5
|
Project-URL: Documentation, https://flask-exts.readthedocs.io
|
|
6
6
|
Project-URL: Source, https://github.com/ojso/flask-exts
|
|
@@ -42,6 +42,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
42
42
|
Classifier: Topic :: Software Development :: Build Tools
|
|
43
43
|
Requires-Python: >=3.10
|
|
44
44
|
Requires-Dist: flask-babel>=4.0
|
|
45
|
+
Requires-Dist: flask-login>=0.6
|
|
45
46
|
Requires-Dist: flask-sqlalchemy>=3.0
|
|
46
47
|
Requires-Dist: flask>=3.0
|
|
47
48
|
Requires-Dist: wtforms>=3.0
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Configuration file for the Sphinx documentation builder.
|
|
2
|
+
#
|
|
3
|
+
# This file only contains a selection of the most common options. For a full
|
|
4
|
+
# list see the documentation:
|
|
5
|
+
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
|
6
|
+
|
|
7
|
+
# -- Path setup --------------------------------------------------------------
|
|
8
|
+
|
|
9
|
+
# If extensions (or modules to document with autodoc) are in another directory,
|
|
10
|
+
# add these directories to sys.path here. If the directory is relative to the
|
|
11
|
+
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
|
12
|
+
#
|
|
13
|
+
# import os
|
|
14
|
+
# import sys
|
|
15
|
+
# sys.path.insert(0, os.path.abspath('.'))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# -- Project information -----------------------------------------------------
|
|
19
|
+
|
|
20
|
+
project = 'Flask-Exts'
|
|
21
|
+
copyright = '2024, David Dong Hua'
|
|
22
|
+
author = 'David Dong Hua'
|
|
23
|
+
|
|
24
|
+
# -- General configuration ---------------------------------------------------
|
|
25
|
+
# -- General configuration
|
|
26
|
+
|
|
27
|
+
extensions = [
|
|
28
|
+
"sphinx.ext.duration",
|
|
29
|
+
"sphinx.ext.doctest",
|
|
30
|
+
"sphinx.ext.autodoc",
|
|
31
|
+
"sphinx.ext.autosummary",
|
|
32
|
+
"sphinx.ext.intersphinx",
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
intersphinx_mapping = {
|
|
36
|
+
"rtd": ("https://docs.readthedocs.io/en/stable/", None),
|
|
37
|
+
"python": ("https://docs.python.org/3/", None),
|
|
38
|
+
"sphinx": ("https://www.sphinx-doc.org/en/master/", None),
|
|
39
|
+
}
|
|
40
|
+
intersphinx_disabled_domains = ["std"]
|
|
41
|
+
|
|
42
|
+
templates_path = ["_templates"]
|
|
43
|
+
|
|
44
|
+
# -- Options for EPUB output
|
|
45
|
+
epub_show_urls = "footnote"
|
|
46
|
+
|
|
47
|
+
# List of patterns, relative to source directory, that match files and
|
|
48
|
+
# directories to ignore when looking for source files.
|
|
49
|
+
# This pattern also affects html_static_path and html_extra_path.
|
|
50
|
+
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
|
|
51
|
+
|
|
52
|
+
# -- Options for HTML output -------------------------------------------------
|
|
53
|
+
|
|
54
|
+
# The theme to use for HTML and HTML Help pages. See the documentation for
|
|
55
|
+
# a list of builtin themes.
|
|
56
|
+
#
|
|
57
|
+
html_theme = "sphinx_rtd_theme"
|
|
58
|
+
|
|
59
|
+
# Add any paths that contain custom static files (such as style sheets) here,
|
|
60
|
+
# relative to this directory. They are copied after the builtin static files,
|
|
61
|
+
# so a file named "default.css" will overwrite the builtin "default.css".
|
|
62
|
+
html_static_path = ["_static"]
|
|
@@ -1,17 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
.. _installation:
|
|
6
|
-
|
|
7
|
-
Installation
|
|
8
|
-
==============
|
|
9
|
-
|
|
10
|
-
To use Flask-Exts, first install it using pip:
|
|
11
|
-
|
|
12
|
-
.. code-block:: console
|
|
13
|
-
|
|
14
|
-
(.venv) $ pip install flask-exts
|
|
1
|
+
==========
|
|
2
|
+
Configure
|
|
3
|
+
==========
|
|
15
4
|
|
|
16
5
|
Configuration
|
|
17
6
|
==============
|
|
@@ -23,38 +12,23 @@ Configuration
|
|
|
23
12
|
Default is ``None``.
|
|
24
13
|
``BABEL_DEFAULT_TIMEZONE`` Set to ``Asia/Shanghai`` to babel's default timezone.
|
|
25
14
|
Default is ``None``.
|
|
26
|
-
``
|
|
15
|
+
``CSRF_ENABLED`` Set to ``False`` to enable form's CSRF .
|
|
27
16
|
Default is ``True``.
|
|
28
|
-
``TEMPLATE_THEME`` Set to ``theme`` to create custom theme
|
|
29
|
-
Default is ``templating.theme.DefaultTheme()``
|
|
30
|
-
``JQUERY_JS_URL`` Set to ``jquery js url`` to active ``jquery``.
|
|
31
|
-
Default is in ``jsdelivr``.
|
|
32
|
-
``BOOTSTRAP_CSS_URL`` Set to ``bootstrap css url`` to active ``bootstrap css``.
|
|
33
|
-
Default is in ``jsdelivr``.
|
|
34
|
-
``BOOTSTRAP_JS_URL`` Set to ``bootstrap js url`` to active ``bootstrap js``.
|
|
35
|
-
Default is in ``jsdelivr``.
|
|
36
|
-
``ICON_SPRITE_URL`` Set to ``icon url`` to active ``icon``.
|
|
37
|
-
Default is in ``/template/static/vendor/bootstrap-icons/bootstrap-icons.svg``.
|
|
38
|
-
``CSRF_ENABLED`` Set to ``True`` to enable form's CSRF .
|
|
39
|
-
Default is ``False``.
|
|
40
17
|
``CSRF_SECRET_KEY`` Random data for generating secure tokens.
|
|
41
18
|
If this is not set then ``SECRET_KEY`` is used.
|
|
42
19
|
``CSRF_FIELD_NAME`` Name of the form field and session key that holds the CSRF token.
|
|
43
20
|
Default is ``csrf_token``.
|
|
44
21
|
``CSRF_TIME_LIMIT`` Max age in seconds for CSRF tokens.
|
|
45
22
|
Default is ``1800``.
|
|
23
|
+
``TEMPLATE_ENABLED`` Set to ``False`` to disable templating extension.
|
|
24
|
+
Default is ``True``.
|
|
25
|
+
``TEMPLATE_THEME`` Set to ``theme`` to create custom theme
|
|
26
|
+
Default is ``template.theme.BootstrapTheme(4)``
|
|
27
|
+
``USER_ENABLED`` Set to ``False`` to disable ``User`` support.
|
|
28
|
+
Default is ``True``.
|
|
29
|
+
``USER_CENTER`` set to ``user center`` to create custom user_center
|
|
30
|
+
Default is ``users.user_center.DefaultUserCenter()``
|
|
31
|
+
``FLASK_LOGIN_ENABLED`` Set to ``False`` to disable ``Flask-Login``.
|
|
32
|
+
Default is ``True``.
|
|
46
33
|
========================== =====================================================================
|
|
47
34
|
|
|
48
|
-
Start
|
|
49
|
-
======
|
|
50
|
-
|
|
51
|
-
.. code-block:: python
|
|
52
|
-
|
|
53
|
-
from flask_exts import Manager
|
|
54
|
-
from flask import Flask
|
|
55
|
-
|
|
56
|
-
manager = Manager()
|
|
57
|
-
app = Flask(__name__)
|
|
58
|
-
|
|
59
|
-
# init Manager
|
|
60
|
-
manager.init_app(app)
|
|
@@ -1,10 +1,56 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
=======
|
|
2
|
+
Develop
|
|
3
|
+
=======
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
Install
|
|
6
|
+
=======
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
.. code-block:: console
|
|
9
|
+
|
|
10
|
+
$ pip install -e .
|
|
11
|
+
$ pip install -r requirements/develop.in
|
|
12
|
+
|
|
13
|
+
Test
|
|
14
|
+
====
|
|
15
|
+
Tests are run with `pytest <https://pytest.org/>`_.
|
|
16
|
+
To run the tests, from the project directory:
|
|
17
|
+
|
|
18
|
+
.. code-block:: console
|
|
19
|
+
|
|
20
|
+
# requirements
|
|
21
|
+
$ pip install -r requirements/test.in
|
|
22
|
+
|
|
23
|
+
# update translation
|
|
24
|
+
$ pybabel compile -d src/flask_exts/translations -D messages
|
|
25
|
+
$ pybabel compile -d tests/translations
|
|
26
|
+
|
|
27
|
+
# test
|
|
28
|
+
$ pytest
|
|
29
|
+
|
|
30
|
+
Docs
|
|
31
|
+
====
|
|
32
|
+
|
|
33
|
+
.. code-block:: console
|
|
34
|
+
|
|
35
|
+
$ pip install -r docs/requirements.txt
|
|
36
|
+
$ cd docs
|
|
37
|
+
$ make html
|
|
38
|
+
|
|
39
|
+
Publish
|
|
40
|
+
=======
|
|
41
|
+
|
|
42
|
+
.. code-block:: console
|
|
43
|
+
|
|
44
|
+
$ pip install -r requirements/build.in
|
|
45
|
+
$ python -m build
|
|
46
|
+
|
|
47
|
+
Translation
|
|
48
|
+
=============
|
|
49
|
+
|
|
50
|
+
pybabel
|
|
51
|
+
-------------
|
|
52
|
+
|
|
53
|
+
.. code-block:: console
|
|
8
54
|
|
|
9
55
|
# extract messages from source files and generate a POT file
|
|
10
56
|
pybabel extract -F babel.cfg -o babel/messages.pot src/
|
|
@@ -27,7 +73,7 @@ pybabel::
|
|
|
27
73
|
tests
|
|
28
74
|
-----
|
|
29
75
|
|
|
30
|
-
|
|
76
|
+
.. code-block:: console
|
|
31
77
|
|
|
32
78
|
|
|
33
79
|
cd tests/
|
|
@@ -47,9 +93,4 @@ pybabel::
|
|
|
47
93
|
|
|
48
94
|
# compile message catalogs to MO files
|
|
49
95
|
|
|
50
|
-
pybabel compile -d translations
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
96
|
+
pybabel compile -d translations
|
|
@@ -8,16 +8,33 @@ Welcome to Flask-Exts's documentation!
|
|
|
8
8
|
|
|
9
9
|
**Flask-Exts** is a Flask extensions with admin, SQLAlchemy, babel, forms, fields, widgets, and so on.
|
|
10
10
|
|
|
11
|
+
.. _installation:
|
|
12
|
+
|
|
13
|
+
Installation
|
|
14
|
+
==============
|
|
15
|
+
|
|
16
|
+
To use Flask-Exts, first install it using pip:
|
|
17
|
+
|
|
18
|
+
.. code-block:: console
|
|
19
|
+
|
|
20
|
+
(.venv) $ pip install flask-exts
|
|
21
|
+
|
|
22
|
+
Examples
|
|
23
|
+
===========
|
|
24
|
+
|
|
25
|
+
``python simple.py`` to run a simple example.
|
|
26
|
+
|
|
27
|
+
.. literalinclude:: ../examples/simple.py
|
|
28
|
+
:language: python
|
|
29
|
+
|
|
30
|
+
More examples, please click :doc:`examples`.
|
|
31
|
+
|
|
11
32
|
.. toctree::
|
|
12
33
|
:maxdepth: 2
|
|
13
34
|
:caption: Contents:
|
|
14
35
|
|
|
15
|
-
|
|
16
|
-
api
|
|
17
|
-
forms
|
|
18
|
-
templating
|
|
36
|
+
configure
|
|
19
37
|
develop
|
|
20
|
-
translation
|
|
21
38
|
examples
|
|
22
39
|
changes
|
|
23
40
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Examples
|
|
3
3
|
========================
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Download
|
|
6
6
|
=========
|
|
7
7
|
|
|
8
8
|
Type these commands in the terminal:
|
|
@@ -14,50 +14,50 @@ Type these commands in the terminal:
|
|
|
14
14
|
$ python3 -m venv venv
|
|
15
15
|
$ source venv/bin/activate
|
|
16
16
|
$ pip install flask-exts
|
|
17
|
-
|
|
18
17
|
|
|
19
|
-
Run the
|
|
20
|
-
|
|
18
|
+
Run the examples
|
|
19
|
+
===============================
|
|
21
20
|
|
|
22
|
-
Type the command in the terminal:
|
|
21
|
+
Type the command in the terminal, then go to http://localhost:5000.
|
|
23
22
|
|
|
24
|
-
|
|
23
|
+
Start
|
|
24
|
+
----------
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
simple
|
|
27
|
+
---------
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
-----------------
|
|
29
|
+
run only one file.
|
|
30
30
|
|
|
31
31
|
.. code-block:: bash
|
|
32
32
|
|
|
33
|
-
$
|
|
33
|
+
$ python simple.py
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
demo
|
|
36
36
|
-----------------
|
|
37
37
|
|
|
38
|
+
With sqlite db.
|
|
39
|
+
|
|
38
40
|
.. code-block:: bash
|
|
39
41
|
|
|
40
|
-
$ flask --app
|
|
41
|
-
|
|
42
|
-
Now go to http://localhost:5000.
|
|
42
|
+
$ flask --app demo run --debug --port=5000
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
Bootstrap 4
|
|
45
45
|
-----------------
|
|
46
46
|
|
|
47
47
|
.. code-block:: bash
|
|
48
|
-
|
|
49
|
-
$ flask --app admin/simple run
|
|
50
|
-
|
|
51
|
-
Now go to http://localhost:5000.
|
|
52
48
|
|
|
49
|
+
$ flask --app bootstrap4/app.py run
|
|
53
50
|
|
|
54
|
-
|
|
51
|
+
Bootstrap 5
|
|
55
52
|
-----------------
|
|
56
53
|
|
|
57
|
-
When Bootstrap-Flask updates the icon file, the overview page can be upgraded with:
|
|
58
|
-
|
|
59
|
-
|
|
60
54
|
.. code-block:: bash
|
|
55
|
+
|
|
56
|
+
$ flask --app bootstrap5/app.py run
|
|
61
57
|
|
|
62
|
-
|
|
58
|
+
fileadmin
|
|
59
|
+
-----------------
|
|
63
60
|
|
|
61
|
+
.. code-block:: bash
|
|
62
|
+
|
|
63
|
+
$ flask --app admin/fileadmin run
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import os.path as op
|
|
2
|
+
from flask_exts.admin import Admin
|
|
3
|
+
from flask_exts.admin.file_admin import LocalFileAdmin
|
|
4
|
+
|
|
5
|
+
class FileAdmin(LocalFileAdmin):
|
|
6
|
+
upload_modal = True
|
|
7
|
+
rename_modal = True
|
|
8
|
+
|
|
9
|
+
# Create admin interface
|
|
10
|
+
admin = Admin(name="Example: File Admin Views")
|
|
11
|
+
|
|
12
|
+
# Create file admin view
|
|
13
|
+
path = op.join(op.dirname(__file__), "tmp")
|
|
14
|
+
file_admin_view = FileAdmin(path, name="TmpFiles")
|
|
15
|
+
# file_admin_view.rename_modal=True
|
|
16
|
+
|
|
17
|
+
admin.add_view(file_admin_view)
|
|
@@ -6,7 +6,7 @@ from wtforms.validators import DataRequired, Length, Regexp
|
|
|
6
6
|
from wtforms.fields import *
|
|
7
7
|
from flask_sqlalchemy import SQLAlchemy
|
|
8
8
|
from flask_exts.forms.form import FlaskForm
|
|
9
|
-
from flask_exts.forms.fields
|
|
9
|
+
from flask_exts.forms.fields import SwitchField
|
|
10
10
|
from flask_exts import Manager
|
|
11
11
|
|
|
12
12
|
manager = Manager()
|
|
@@ -32,7 +32,7 @@ class ExampleForm(FlaskForm):
|
|
|
32
32
|
email = EmailField()
|
|
33
33
|
url = URLField()
|
|
34
34
|
telephone = TelField()
|
|
35
|
-
image = FileField(render_kw={'class': 'my-class'}, validators=[Regexp('.+\.jpg$')]) # add your class
|
|
35
|
+
image = FileField(render_kw={'class': 'my-class'}, validators=[Regexp(r'.+\.jpg$')]) # add your class
|
|
36
36
|
option = RadioField(choices=[('dog', 'Dog'), ('cat', 'Cat'), ('bird', 'Bird'), ('alien', 'Alien')])
|
|
37
37
|
select = SelectField(choices=[('dog', 'Dog'), ('cat', 'Cat'), ('bird', 'Bird'), ('alien', 'Alien')])
|
|
38
38
|
select_multiple = SelectMultipleField(choices=[('dog', 'Dog'), ('cat', 'Cat'), ('bird', 'Bird'), ('alien', 'Alien')])
|
|
@@ -7,11 +7,11 @@ from wtforms.fields import *
|
|
|
7
7
|
from flask_sqlalchemy import SQLAlchemy
|
|
8
8
|
|
|
9
9
|
from flask_exts.forms.form import FlaskForm
|
|
10
|
-
from flask_exts.forms.fields
|
|
10
|
+
from flask_exts.forms.fields import SwitchField
|
|
11
11
|
from flask_exts import Manager
|
|
12
|
-
from flask_exts.
|
|
12
|
+
from flask_exts.template.theme import BootstrapTheme
|
|
13
13
|
|
|
14
|
-
theme =
|
|
14
|
+
theme = BootstrapTheme(version=5)
|
|
15
15
|
|
|
16
16
|
manager = Manager()
|
|
17
17
|
app = Flask(__name__)
|
|
@@ -47,7 +47,7 @@ class ExampleForm(FlaskForm):
|
|
|
47
47
|
url = URLField()
|
|
48
48
|
telephone = TelField()
|
|
49
49
|
image = FileField(
|
|
50
|
-
render_kw={"class": "my-class"}, validators=[Regexp(".+\.jpg$")]
|
|
50
|
+
render_kw={"class": "my-class"}, validators=[Regexp(r".+\.jpg$")]
|
|
51
51
|
) # add your class
|
|
52
52
|
option = RadioField(
|
|
53
53
|
choices=[("dog", "Dog"), ("cat", "Cat"), ("bird", "Bird"), ("alien", "Alien")]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .make_app import create_app
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import os.path
|
|
2
|
+
from flask import Flask
|
|
3
|
+
from flask_exts import Manager
|
|
4
|
+
from flask_exts.admin import Admin
|
|
5
|
+
from .models import db
|
|
6
|
+
from .user_center import UserCenter
|
|
7
|
+
from .views.my_view import myview
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def get_sqlite_path():
|
|
11
|
+
app_dir = os.path.realpath(os.path.dirname(__file__))
|
|
12
|
+
database_path = os.path.join(app_dir, "sample.sqlite")
|
|
13
|
+
return database_path
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def build_sample_db(app):
|
|
17
|
+
# db.drop_all()
|
|
18
|
+
db.create_all()
|
|
19
|
+
user_center = app.config["USER_CENTER"]
|
|
20
|
+
user_center.register_user("admin", "admin", "admin@example.com")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def create_app():
|
|
24
|
+
app = Flask(__name__)
|
|
25
|
+
app.config["SECRET_KEY"] = "dev"
|
|
26
|
+
# app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///:memory:"
|
|
27
|
+
app.config["DATABASE_FILE"] = get_sqlite_path()
|
|
28
|
+
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///" + app.config["DATABASE_FILE"]
|
|
29
|
+
|
|
30
|
+
app.config["USER_CENTER"] = UserCenter()
|
|
31
|
+
|
|
32
|
+
init_app(app)
|
|
33
|
+
|
|
34
|
+
return app
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def init_app(app: Flask):
|
|
38
|
+
from .models import init_db
|
|
39
|
+
|
|
40
|
+
init_db(app)
|
|
41
|
+
|
|
42
|
+
manager = Manager()
|
|
43
|
+
manager.init_app(app)
|
|
44
|
+
|
|
45
|
+
admin = Admin(name="Demo")
|
|
46
|
+
admin.init_app(app)
|
|
47
|
+
admin.add_view(myview)
|
|
48
|
+
|
|
49
|
+
if not os.path.exists(app.config["DATABASE_FILE"]):
|
|
50
|
+
with app.app_context():
|
|
51
|
+
build_sample_db(app)
|
|
52
|
+
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from flask_sqlalchemy import SQLAlchemy
|
|
2
|
+
from sqlalchemy.orm import DeclarativeBase
|
|
3
|
+
from sqlalchemy import select
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Base(DeclarativeBase):
|
|
7
|
+
pass
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
db = SQLAlchemy(model_class=Base)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def init_db(app):
|
|
14
|
+
db.init_app(app)
|
|
15
|
+
|
|
16
|
+
from . import user
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
from sqlalchemy.orm import Mapped
|
|
3
|
+
from sqlalchemy.orm import mapped_column
|
|
4
|
+
from flask_login import UserMixin
|
|
5
|
+
from . import db
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class User(db.Model, UserMixin):
|
|
9
|
+
id: Mapped[int] = mapped_column(primary_key=True)
|
|
10
|
+
username: Mapped[str]
|
|
11
|
+
email: Mapped[str]
|
|
12
|
+
password: Mapped[str]
|
|
13
|
+
created_at: Mapped[datetime] = mapped_column(default=datetime.now)
|
|
14
|
+
updated_at: Mapped[datetime] = mapped_column(
|
|
15
|
+
default=datetime.now, onupdate=datetime.now
|
|
16
|
+
)
|
|
Binary file
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
from werkzeug.security import generate_password_hash, check_password_hash
|
|
2
|
+
from flask_exts.users.default_usercenter import DefaultUserCenter
|
|
3
|
+
from .models import db,select
|
|
4
|
+
from .models.user import User
|
|
5
|
+
|
|
6
|
+
class UserCenter(DefaultUserCenter):
|
|
7
|
+
user_class = User
|
|
8
|
+
|
|
9
|
+
def __init__(self):
|
|
10
|
+
self.users = []
|
|
11
|
+
|
|
12
|
+
def user_loader(self, user_id):
|
|
13
|
+
user = db.session.get(User, int(user_id))
|
|
14
|
+
return user
|
|
15
|
+
|
|
16
|
+
def get_users(self):
|
|
17
|
+
stmt = select(User).order_by("id")
|
|
18
|
+
users = db.session.execute(stmt).scalars()
|
|
19
|
+
return users
|
|
20
|
+
|
|
21
|
+
def get_user_by_id(self, id):
|
|
22
|
+
user = db.session.get(User, id)
|
|
23
|
+
return user
|
|
24
|
+
|
|
25
|
+
def login_user_by_username_password(self, username, password):
|
|
26
|
+
stmt = select(User).filter_by(username=username)
|
|
27
|
+
user = db.session.execute(stmt).scalar()
|
|
28
|
+
if user is None:
|
|
29
|
+
return (None, "invalid username")
|
|
30
|
+
elif not check_password_hash(user.password, password):
|
|
31
|
+
return (None, "invalid password")
|
|
32
|
+
else:
|
|
33
|
+
return (user, None)
|
|
34
|
+
|
|
35
|
+
def register_user(self, username, password, email):
|
|
36
|
+
stmt_filter_username = select(User).filter_by(username=username)
|
|
37
|
+
user_filter_username = db.session.execute(stmt_filter_username).scalar()
|
|
38
|
+
if user_filter_username is not None:
|
|
39
|
+
return (None, "invalid username")
|
|
40
|
+
|
|
41
|
+
stmt_filter_email = select(User).filter_by(email=email)
|
|
42
|
+
user_filter_email = db.session.execute(stmt_filter_email).scalar()
|
|
43
|
+
if user_filter_email is not None:
|
|
44
|
+
return (None, "invalid email")
|
|
45
|
+
|
|
46
|
+
user = self.user_class(username=username)
|
|
47
|
+
user.password = generate_password_hash(password)
|
|
48
|
+
user.email = email
|
|
49
|
+
db.session.add(user)
|
|
50
|
+
db.session.commit()
|
|
51
|
+
return (user, None)
|
|
52
|
+
|
|
53
|
+
def remove_user(self, user_id):
|
|
54
|
+
return NotImplemented
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# simple.py
|
|
2
|
+
|
|
3
|
+
from flask import Flask
|
|
4
|
+
from flask_exts import Manager
|
|
5
|
+
from flask_exts.admin import Admin
|
|
6
|
+
|
|
7
|
+
app = Flask(__name__)
|
|
8
|
+
app.config["SECRET_KEY"] = "dev"
|
|
9
|
+
# Manager init
|
|
10
|
+
manager = Manager()
|
|
11
|
+
manager.init_app(app)
|
|
12
|
+
# Admin init for index_view and user_view
|
|
13
|
+
admin = Admin()
|
|
14
|
+
admin.init_app(app)
|
|
15
|
+
|
|
16
|
+
if __name__ == "__main__":
|
|
17
|
+
app.run(debug=True)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.2.0"
|