Flask-Exts 0.2.1__tar.gz → 0.2.3__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.2.1 → flask_exts-0.2.3}/.gitignore +3 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/CHANGES.rst +23 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/PKG-INFO +7 -4
- {flask_exts-0.2.1 → flask_exts-0.2.3}/README.rst +3 -3
- {flask_exts-0.2.1 → flask_exts-0.2.3}/docs/configure.rst +3 -14
- {flask_exts-0.2.1 → flask_exts-0.2.3}/docs/index.rst +8 -1
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap4/app.py +3 -5
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap5/app.py +9 -8
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap5/templates/pagination.html +1 -1
- flask_exts-0.2.3/examples/demo/admin_views.py +31 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/build_sample.py +24 -2
- flask_exts-0.2.3/examples/demo/file_op.py +13 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/make_app.py +21 -18
- flask_exts-0.2.3/examples/demo/models/__init__.py +12 -0
- flask_exts-0.2.1/examples/sqla-custom-inline-forms/models/model.py → flask_exts-0.2.3/examples/demo/models/location_image.py +21 -5
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/models/tree.py +3 -2
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/models/user.py +3 -3
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/models/user_keyword.py +4 -4
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/views/author_view.py +2 -4
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/views/keyword_view.py +1 -2
- flask_exts-0.2.1/examples/sqla-custom-inline-forms/views/image_view.py → flask_exts-0.2.3/examples/demo/views/location_image_view.py +6 -7
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/views/post_view.py +8 -2
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/views/tag_view.py +1 -2
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/views/tree_view.py +15 -8
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/views/user_view.py +2 -3
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/fileadmin/make_app.py +6 -6
- flask_exts-0.2.3/examples/instance/config.py +3 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/rediscli.py +2 -1
- flask_exts-0.2.3/examples/simple.py +27 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/pyproject.toml +7 -0
- flask_exts-0.2.3/src/flask_exts/__about__.py +1 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/admin/__init__.py +0 -1
- flask_exts-0.2.3/src/flask_exts/admin/admin.py +15 -0
- flask_exts-0.2.3/src/flask_exts/admin/base_admin.py +125 -0
- flask_exts-0.2.3/src/flask_exts/admin/menu.py +280 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/admin/model/filters.py +27 -72
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/admin/model/form.py +3 -3
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/admin/model/typefmt.py +4 -5
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/admin/model/view.py +13 -23
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/admin/sqla/ajax.py +42 -20
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/admin/sqla/form.py +22 -47
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/admin/sqla/typefmt.py +0 -12
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/admin/sqla/view.py +333 -272
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/admin/view.py +26 -46
- flask_exts-0.2.3/src/flask_exts/commands.py +34 -0
- {flask_exts-0.2.1/examples/sqla-custom-inline-forms/models → flask_exts-0.2.3/src/flask_exts/datastore/sqla}/__init__.py +2 -7
- flask_exts-0.2.3/src/flask_exts/datastore/sqla/models/role.py +15 -0
- flask_exts-0.2.3/src/flask_exts/datastore/sqla/models/user.py +70 -0
- flask_exts-0.2.3/src/flask_exts/datastore/sqla/models/user_profile.py +29 -0
- flask_exts-0.2.3/src/flask_exts/datastore/sqla/models/webauthn.py +38 -0
- flask_exts-0.2.3/src/flask_exts/datastore/sqla/orm.py +12 -0
- flask_exts-0.2.3/src/flask_exts/email/base.py +43 -0
- flask_exts-0.2.3/src/flask_exts/email/sender.py +6 -0
- flask_exts-0.2.3/src/flask_exts/email/smtp.py +41 -0
- flask_exts-0.2.3/src/flask_exts/email/verify_email_sender.py +12 -0
- flask_exts-0.2.3/src/flask_exts/forms/login.py +13 -0
- {flask_exts-0.2.1/src/flask_exts/users → flask_exts-0.2.3/src/flask_exts}/forms/profile.py +1 -1
- flask_exts-0.2.1/src/flask_exts/users/forms/mixins.py → flask_exts-0.2.3/src/flask_exts/forms/register.py +2 -9
- flask_exts-0.2.3/src/flask_exts/manager.py +83 -0
- flask_exts-0.2.3/src/flask_exts/proxies.py +22 -0
- flask_exts-0.2.3/src/flask_exts/security/__init__.py +6 -0
- flask_exts-0.2.3/src/flask_exts/security/authorizer/base.py +21 -0
- flask_exts-0.2.3/src/flask_exts/security/authorizer/casbin_authorizer.py +111 -0
- flask_exts-0.2.3/src/flask_exts/security/authorizer/sqlalchemy_adapter.py +245 -0
- flask_exts-0.2.3/src/flask_exts/security/core.py +29 -0
- flask_exts-0.2.3/src/flask_exts/security/email_verification.py +83 -0
- flask_exts-0.2.3/src/flask_exts/security/hasher.py +22 -0
- flask_exts-0.2.3/src/flask_exts/security/principal/identity.py +37 -0
- flask_exts-0.2.3/src/flask_exts/security/principal/identity_context.py +52 -0
- flask_exts-0.2.3/src/flask_exts/security/principal/permission.py +297 -0
- flask_exts-0.2.3/src/flask_exts/security/principal/principal.py +197 -0
- flask_exts-0.2.3/src/flask_exts/security/serializer.py +50 -0
- flask_exts-0.2.3/src/flask_exts/signals.py +7 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/js/filters.js +18 -8
- flask_exts-0.2.3/src/flask_exts/static/js/form.js +680 -0
- flask_exts-0.2.3/src/flask_exts/static/js/helper.js +7 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/js/modal.js +4 -1
- flask_exts-0.2.3/src/flask_exts/static/js/security/base64.js +127 -0
- flask_exts-0.2.3/src/flask_exts/static/js/security/webauthn.js +193 -0
- {flask_exts-0.2.1/src/flask_exts/static/vendor/x-editable → flask_exts-0.2.3/src/flask_exts/static/vendor/vanilla-editor}/css/bootstrap-editable.css +0 -4
- flask_exts-0.2.3/src/flask_exts/static/vendor/vanilla-editor/js/bootstrap-editable.min.js +1 -0
- flask_exts-0.2.3/src/flask_exts/template/base.py +48 -0
- {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/fields/__init__.py +2 -1
- {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/fields/datetime.py +6 -2
- {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/fields/sqla.py +4 -4
- {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/form/base_form.py +1 -1
- flask_exts-0.2.3/src/flask_exts/template/form/csrf.py +65 -0
- flask_exts-0.2.3/src/flask_exts/template/form/form_opts.py +6 -0
- {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/form/meta.py +2 -25
- {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template/form}/utils.py +0 -9
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/template/utils.py +0 -16
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/admin/base.html +13 -6
- flask_exts-0.2.3/src/flask_exts/templates/admin/index.html +11 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/admin/model/list.html +3 -10
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/admin/model/modals/create.html +0 -3
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/admin/model/modals/details.html +0 -1
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/admin/model/modals/edit.html +0 -5
- flask_exts-0.2.3/src/flask_exts/templates/index.html +22 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/macro/actions.html +1 -4
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/macro/inline.html +2 -2
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/macro/layout.html +1 -3
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/macro/menu.html +12 -20
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/macro/row_actions.html +5 -5
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/macro/vendor.html +2 -2
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/views/file/list.html +4 -9
- flask_exts-0.2.3/src/flask_exts/templates/views/user/verify_email.html +9 -0
- flask_exts-0.2.1/src/flask_exts/_types.py → flask_exts-0.2.3/src/flask_exts/types.py +1 -1
- flask_exts-0.2.3/src/flask_exts/usercenter/base_user.py +7 -0
- flask_exts-0.2.3/src/flask_exts/usercenter/base_usercenter.py +40 -0
- flask_exts-0.2.3/src/flask_exts/usercenter/sqla_usercenter.py +101 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/utils/__init__.py +1 -1
- flask_exts-0.2.3/src/flask_exts/utils/authorize.py +21 -0
- flask_exts-0.2.3/src/flask_exts/utils/decorators.py +47 -0
- flask_exts-0.2.3/src/flask_exts/utils/flask.py +16 -0
- flask_exts-0.2.3/src/flask_exts/utils/jwt.py +34 -0
- flask_exts-0.2.3/src/flask_exts/utils/request_user.py +64 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/utils/sqla.py +0 -5
- flask_exts-0.2.1/src/flask_exts/utils/flask.py → flask_exts-0.2.3/src/flask_exts/utils/url.py +0 -14
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/views/file_view/base_file_view.py +4 -5
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/views/index_view.py +6 -5
- flask_exts-0.2.3/src/flask_exts/views/rediscli_view.py +190 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/views/user_view.py +32 -29
- flask_exts-0.2.3/tests/__init__.py +1 -0
- flask_exts-0.2.3/tests/admin/__init__.py +0 -0
- flask_exts-0.2.3/tests/admin/customer/conftest.py +44 -0
- flask_exts-0.2.3/tests/admin/customer/test_admin.py +97 -0
- flask_exts-0.2.3/tests/admin/sqla/__init__.py +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/admin/sqla/test_basic.py +589 -944
- flask_exts-0.2.3/tests/admin/sqla/test_form_rules.py +86 -0
- flask_exts-0.2.3/tests/admin/sqla/test_inlineform.py +196 -0
- flask_exts-0.2.3/tests/admin/sqla/test_multi_pk.py +132 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/admin/sqla/test_translation.py +9 -9
- flask_exts-0.2.3/tests/admin/test_base.py +153 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/admin/test_model.py +80 -79
- flask_exts-0.2.3/tests/conftest.py +46 -0
- flask_exts-0.2.3/tests/email/test_base.py +18 -0
- flask_exts-0.2.3/tests/email/test_smtp.py +24 -0
- flask_exts-0.2.3/tests/models/__init__.py +6 -0
- flask_exts-0.2.3/tests/models/message.py +15 -0
- flask_exts-0.2.3/tests/models/model1.py +175 -0
- flask_exts-0.2.3/tests/models/multpk.py +7 -0
- flask_exts-0.2.3/tests/models/polymorphic.py +35 -0
- flask_exts-0.2.3/tests/models/tree.py +7 -0
- flask_exts-0.2.3/tests/models/user.py +41 -0
- flask_exts-0.2.3/tests/security/authorizer/__init__.py +0 -0
- flask_exts-0.2.3/tests/security/authorizer/casbin_adapter/rbac_model.conf +14 -0
- flask_exts-0.2.3/tests/security/authorizer/casbin_adapter/rbac_policy.csv +6 -0
- flask_exts-0.2.3/tests/security/authorizer/casbin_adapter/test_sqlalchemy_adapter.py +392 -0
- flask_exts-0.2.3/tests/security/authorizer/casbin_files/authz_policy.csv +11 -0
- flask_exts-0.2.3/tests/security/authorizer/casbin_files/rbac_model.conf +14 -0
- flask_exts-0.2.3/tests/security/authorizer/casbin_files/rbac_policy.csv +8 -0
- flask_exts-0.2.3/tests/security/authorizer/test_casbin_auth.py +148 -0
- flask_exts-0.2.3/tests/security/test_core.py +41 -0
- flask_exts-0.2.3/tests/security/test_principal.py +705 -0
- flask_exts-0.2.3/tests/template/__init__.py +0 -0
- flask_exts-0.2.3/tests/template/bootstrap4/__init__.py +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/template/bootstrap4/test_render_field.py +17 -21
- {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/template/bootstrap4/test_render_form.py +40 -48
- {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/template/bootstrap4/test_render_form_row.py +10 -14
- {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/template/bootstrap4/test_render_hidden_errors.py +3 -4
- {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/template/bootstrap4/test_render_icon_sprite.py +25 -30
- {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/template/bootstrap4/test_render_messages.py +15 -19
- flask_exts-0.2.3/tests/template/bootstrap4/test_render_pager.py +35 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/template/bootstrap4/test_render_pagination.py +12 -18
- {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/template/bootstrap4/test_render_table.py +51 -115
- flask_exts-0.2.3/tests/template/bootstrap5/__init__.py +0 -0
- flask_exts-0.2.3/tests/template/bootstrap5/conftest.py +21 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/template/bootstrap5/test_base.py +2 -2
- {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/template/bootstrap5/test_render_form.py +31 -37
- {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/template/bootstrap5/test_render_form_row.py +4 -5
- {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/template/bootstrap5/test_render_messages.py +2 -3
- {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/template/bootstrap5/test_render_pagination.py +8 -13
- {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/template/conftest.py +1 -1
- flask_exts-0.2.1/tests/forms/test_form.py → flask_exts-0.2.3/tests/template/forms/test_csrf.py +4 -3
- {flask_exts-0.2.1/tests → flask_exts-0.2.3/tests/template}/forms/test_fields.py +3 -3
- {flask_exts-0.2.1/tests → flask_exts-0.2.3/tests/template}/forms/test_filefield.py +1 -1
- {flask_exts-0.2.1/tests → flask_exts-0.2.3/tests/template}/forms/test_uploadfile.py +3 -3
- {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/template/macros/test_render_breadcrumb_item.py +4 -6
- {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/template/macros/test_render_nav_item.py +4 -6
- {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/template/test_base.py +2 -2
- flask_exts-0.2.3/tests/templates/mock.html +1 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/test_babel.py +7 -6
- flask_exts-0.2.3/tests/test_base.py +27 -0
- flask_exts-0.2.3/tests/test_flask.py +34 -0
- flask_exts-0.2.3/tests/usercenter/test_sqla_usercenter.py +34 -0
- flask_exts-0.2.3/tests/utils/test_request_user.py +80 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/utils/test_url.py +1 -1
- flask_exts-0.2.3/tests/views/files/dummy.txt +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/views/test_file_view.py +26 -28
- flask_exts-0.2.3/tests/views/test_user_view.py +96 -0
- flask_exts-0.2.1/examples/demo/admin_views.py +0 -26
- flask_exts-0.2.1/examples/demo/models/__init__.py +0 -24
- flask_exts-0.2.1/examples/demo/templates/admin/index.html +0 -4
- flask_exts-0.2.1/examples/demo/user_center.py +0 -54
- flask_exts-0.2.1/examples/multiple_admins/app.py +0 -34
- flask_exts-0.2.1/examples/multiple_admins/templates/admin/index.html +0 -7
- flask_exts-0.2.1/examples/multiple_admins/templates/first.html +0 -4
- flask_exts-0.2.1/examples/multiple_admins/templates/second.html +0 -4
- flask_exts-0.2.1/examples/simple.py +0 -13
- flask_exts-0.2.1/examples/sqla-custom-inline-forms/__init__.py +0 -1
- flask_exts-0.2.1/examples/sqla-custom-inline-forms/data.py +0 -23
- flask_exts-0.2.1/examples/sqla-custom-inline-forms/make_app.py +0 -83
- flask_exts-0.2.1/examples/sqla-custom-inline-forms/templates/admin/admin.html +0 -5
- flask_exts-0.2.1/src/flask_exts/__about__.py +0 -1
- flask_exts-0.2.1/src/flask_exts/admin/admin.py +0 -263
- flask_exts-0.2.1/src/flask_exts/admin/menu.py +0 -168
- flask_exts-0.2.1/src/flask_exts/forms/__init__.py +0 -3
- flask_exts-0.2.1/src/flask_exts/forms/form/__init__.py +0 -2
- flask_exts-0.2.1/src/flask_exts/forms/form/csrf.py +0 -57
- flask_exts-0.2.1/src/flask_exts/manager.py +0 -39
- flask_exts-0.2.1/src/flask_exts/static/js/form.js +0 -665
- flask_exts-0.2.1/src/flask_exts/static/js/helpers.js +0 -12
- flask_exts-0.2.1/src/flask_exts/static/vendor/x-editable/js/bootstrap-editable.min.js +0 -2
- flask_exts-0.2.1/src/flask_exts/template/__init__.py +0 -37
- flask_exts-0.2.1/src/flask_exts/templates/admin/admin.html +0 -5
- flask_exts-0.2.1/src/flask_exts/templates/admin/index.html +0 -6
- flask_exts-0.2.1/src/flask_exts/users/__init__.py +0 -15
- flask_exts-0.2.1/src/flask_exts/users/default_usercenter.py +0 -51
- flask_exts-0.2.1/src/flask_exts/users/forms/__init__.py +0 -2
- flask_exts-0.2.1/src/flask_exts/users/forms/login.py +0 -6
- flask_exts-0.2.1/src/flask_exts/users/forms/register.py +0 -6
- flask_exts-0.2.1/src/flask_exts/users/usercenter.py +0 -19
- flask_exts-0.2.1/src/flask_exts/views/rediscli_view.py +0 -191
- flask_exts-0.2.1/tests/admin/sqla/conftest.py +0 -20
- flask_exts-0.2.1/tests/admin/sqla/test_form_rules.py +0 -96
- flask_exts-0.2.1/tests/admin/sqla/test_inlineform.py +0 -289
- flask_exts-0.2.1/tests/admin/sqla/test_multi_pk.py +0 -173
- flask_exts-0.2.1/tests/admin/test_base.py +0 -248
- flask_exts-0.2.1/tests/conftest.py +0 -33
- flask_exts-0.2.1/tests/template/bootstrap4/conftest.py +0 -17
- flask_exts-0.2.1/tests/template/bootstrap4/test_render_pager.py +0 -42
- flask_exts-0.2.1/tests/template/bootstrap5/conftest.py +0 -18
- flask_exts-0.2.1/tests/test_base.py +0 -18
- flask_exts-0.2.1/tests/views/test_user_view.py +0 -58
- {flask_exts-0.2.1 → flask_exts-0.2.3}/.github/workflows/release.yml +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/.readthedocs.yaml +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/LICENSE.rst +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/babel/babel.cfg +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/babel/babel.sh +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/babel/messages.pot +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/docs/Makefile +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/docs/_static/logo.png +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/docs/changes.rst +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/docs/conf.py +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/docs/develop.rst +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/docs/examples.rst +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/docs/make.bat +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/docs/requirements.txt +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/README.rst +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap4/static/favicon.ico +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap4/templates/bootswatch.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap4/templates/flash.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap4/templates/form.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap4/templates/icon.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap4/templates/icons.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap4/templates/index.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap4/templates/mybase.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap4/templates/nav.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap4/templates/pagination.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap4/templates/table.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap5/static/favicon.ico +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap5/templates/bootswatch.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap5/templates/flash.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap5/templates/form.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap5/templates/icon.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap5/templates/icons.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap5/templates/index.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap5/templates/mybase.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap5/templates/nav.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap5/templates/table.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/__init__.py +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/models/author.py +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/models/keyword.py +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/models/post.py +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/models/post_tag.py +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/models/tag.py +0 -0
- {flask_exts-0.2.1/examples/sqla-custom-inline-forms → flask_exts-0.2.3/examples/demo}/templates/field_list.html +0 -0
- {flask_exts-0.2.1/examples/sqla-custom-inline-forms → flask_exts-0.2.3/examples/demo}/templates/locations.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/templates/my/index.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/templates/tree_list.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/views/my_view.py +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/fileadmin/__init__.py +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/fileadmin/file_view.py +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/fileadmin/tmp/bbb/a.txt +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/requirements/build.in +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/requirements/test.in +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/__init__.py +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/admin/actions.py +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/admin/model/__init__.py +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/admin/model/ajax.py +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/admin/row_action.py +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/admin/sqla/__init__.py +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/admin/sqla/filters.py +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/babel/__init__.py +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/babel/selector.py +0 -0
- {flask_exts-0.2.1/src/flask_exts/translations → flask_exts-0.2.3/src/flask_exts/datastore}/__init__.py +0 -0
- {flask_exts-0.2.1/tests/admin → flask_exts-0.2.3/src/flask_exts/datastore/sqla/models}/__init__.py +0 -0
- {flask_exts-0.2.1/tests/admin/sqla → flask_exts-0.2.3/src/flask_exts/email}/__init__.py +0 -0
- {flask_exts-0.2.1/tests/template → flask_exts-0.2.3/src/flask_exts/forms}/__init__.py +0 -0
- {flask_exts-0.2.1/tests/template/bootstrap4 → flask_exts-0.2.3/src/flask_exts/security/authorizer}/__init__.py +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/css/admin.css +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/css/rediscli.css +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/js/actions.js +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/js/details_filter.js +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/js/rediscli.js +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/logo.png +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/vendor/bootstrap-icons/bootstrap-icons.svg +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/vendor/bootstrap-icons/font/bootstrap-icons.css +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/vendor/bootstrap-icons/font/bootstrap-icons.json +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/vendor/bootstrap-icons/font/bootstrap-icons.min.css +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/vendor/bootstrap-icons/font/bootstrap-icons.scss +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/vendor/bootstrap-icons/font/fonts/bootstrap-icons.woff +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/vendor/bootstrap-icons/font/fonts/bootstrap-icons.woff2 +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/vendor/bootstrap4/bootstrap.bundle.min.js +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/vendor/bootstrap4/bootstrap.min.css +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/vendor/bootstrap5/bootstrap.bundle.min.js +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/vendor/bootstrap5/bootstrap.min.css +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/vendor/daterangepicker/daterangepicker.css +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/vendor/daterangepicker/daterangepicker.js +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/vendor/jquery/jquery.min.js +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/vendor/moment.min.js +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/vendor/select2/select2.min.css +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/vendor/select2/select2.min.js +0 -0
- {flask_exts-0.2.1/src/flask_exts/static/vendor/x-editable → flask_exts-0.2.3/src/flask_exts/static/vendor/vanilla-editor}/img/clear.png +0 -0
- {flask_exts-0.2.1/src/flask_exts/static/vendor/x-editable → flask_exts-0.2.3/src/flask_exts/static/vendor/vanilla-editor}/img/loading.gif +0 -0
- {flask_exts-0.2.1/tests → flask_exts-0.2.3/src/flask_exts/template}/__init__.py +0 -0
- {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/fields/ajax_select.py +0 -0
- {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/fields/file.py +0 -0
- {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/fields/inline.py +0 -0
- {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/fields/json.py +0 -0
- {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/fields/recaptcha.py +0 -0
- {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/fields/select.py +0 -0
- {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/fields/switch.py +0 -0
- {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/fields/taglist.py +0 -0
- {flask_exts-0.2.1/tests/template/bootstrap5 → flask_exts-0.2.3/src/flask_exts/template/form}/__init__.py +0 -0
- {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/form/flask_form.py +0 -0
- {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/form/session_csrf.py +0 -0
- {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/rules.py +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/template/theme.py +0 -0
- {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/validators/__init__.py +0 -0
- {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/validators/field_list.py +0 -0
- {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/validators/file.py +0 -0
- {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/validators/recaptcha.py +0 -0
- {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/validators/sqla.py +0 -0
- {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/widgets/__init__.py +0 -0
- {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/widgets/checkbox.py +0 -0
- {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/widgets/datetime.py +0 -0
- {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/widgets/file.py +0 -0
- {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/widgets/inline.py +0 -0
- {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/widgets/recaptcha.py +0 -0
- {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/widgets/render_template.py +0 -0
- {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/widgets/select.py +0 -0
- {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/widgets/xeditable.py +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/admin/master.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/admin/model/create.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/admin/model/details.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/admin/model/edit.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/base.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/bootstrap4/form.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/bootstrap4/message.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/bootstrap4/pagination.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/bootstrap5/form.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/bootstrap5/message.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/layout.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/macro/form.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/macro/icon.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/macro/message.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/macro/nav.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/macro/pagination.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/macro/table.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/views/file/form.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/views/file/modals/form.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/views/rediscli/console.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/views/rediscli/response.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/views/user/index.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/views/user/list.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/views/user/login.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/views/user/register.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/widgets/inline_field_list.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/widgets/inline_form.html +0 -0
- /flask_exts-0.2.1/src/flask_exts/utils/url.py → /flask_exts-0.2.3/src/flask_exts/translations/__init__.py +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/translations/en/LC_MESSAGES/messages.mo +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/translations/en/LC_MESSAGES/messages.po +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/translations/zh_CN/LC_MESSAGES/messages.mo +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/translations/zh_CN/LC_MESSAGES/messages.po +0 -0
- /flask_exts-0.2.1/tests/views/files/dummy.txt → /flask_exts-0.2.3/src/flask_exts/usercenter/__init__.py +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/utils/tools.py +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/views/file_view/__init__.py +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/views/file_view/local_file_storage.py +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/views/file_view/local_file_view.py +0 -0
- {flask_exts-0.2.1/tests → flask_exts-0.2.3/tests/admin/customer}/templates/mock.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/admin/sqla/templates/another_macro.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/admin/sqla/templates/macro.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/data/copyleft.gif +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/data/copyleft.jpeg +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/data/copyleft.jpg +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/data/copyleft.png +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/data/copyleft.tiff +0 -0
- /flask_exts-0.2.1/tests/funcs.py → /flask_exts-0.2.3/tests/helper.py +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/templates/method.html +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/translations/en/LC_MESSAGES/messages.mo +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/translations/en/LC_MESSAGES/messages.po +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/translations/zh_CN/LC_MESSAGES/messages.po +0 -0
- {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/views/test_rediscli_view.py +0 -0
|
@@ -1,3 +1,26 @@
|
|
|
1
|
+
v0.2.3
|
|
2
|
+
------
|
|
3
|
+
|
|
4
|
+
Released 2025-08-28
|
|
5
|
+
|
|
6
|
+
- move form into template
|
|
7
|
+
- add folder email
|
|
8
|
+
- add security.email_verification
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
v0.2.2
|
|
12
|
+
------
|
|
13
|
+
|
|
14
|
+
Released 2025-04-09
|
|
15
|
+
|
|
16
|
+
- fix datetimepicker
|
|
17
|
+
- set session = db.session as default if ModelView of sqla init session is None
|
|
18
|
+
- set session = db.session as default if QueryAjaxModelLoader init session is None
|
|
19
|
+
- fix select.ajax for select2@4.1.0
|
|
20
|
+
- fix select in modal
|
|
21
|
+
- add casbin
|
|
22
|
+
- add module: security
|
|
23
|
+
|
|
1
24
|
v0.2.1
|
|
2
25
|
------
|
|
3
26
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: Flask-Exts
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
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
|
|
@@ -41,11 +41,14 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
41
41
|
Classifier: Programming Language :: Python :: 3.11
|
|
42
42
|
Classifier: Topic :: Software Development :: Build Tools
|
|
43
43
|
Requires-Python: >=3.10
|
|
44
|
+
Requires-Dist: casbin>=1.0
|
|
44
45
|
Requires-Dist: flask-babel>=4.0
|
|
45
46
|
Requires-Dist: flask-login>=0.6
|
|
46
47
|
Requires-Dist: flask-sqlalchemy>=3.0
|
|
47
48
|
Requires-Dist: flask>=3.0
|
|
49
|
+
Requires-Dist: pyjwt>=2.0
|
|
48
50
|
Requires-Dist: tablib>=3.0
|
|
51
|
+
Requires-Dist: webauthn>=2.0
|
|
49
52
|
Requires-Dist: wtforms>=3.0
|
|
50
53
|
Provides-Extra: rediscli
|
|
51
54
|
Requires-Dist: redis>=4.0.0; extra == 'rediscli'
|
|
@@ -56,10 +59,10 @@ Flask Exts
|
|
|
56
59
|
|
|
57
60
|
Flask-Exts is mainly inspired by:
|
|
58
61
|
|
|
59
|
-
- `
|
|
60
|
-
- `Flask-
|
|
62
|
+
- `Flask-Admin <https://github.com/pallets-eco/flask-admin/>`_
|
|
63
|
+
- `Flask-Security <https://github.com/pallets-eco/flask-security/>`_
|
|
61
64
|
|
|
62
|
-
Flask-Exts is
|
|
65
|
+
Flask-Exts is partially rewrited from above and well tested.
|
|
63
66
|
|
|
64
67
|
License
|
|
65
68
|
-------
|
|
@@ -3,10 +3,10 @@ Flask Exts
|
|
|
3
3
|
|
|
4
4
|
Flask-Exts is mainly inspired by:
|
|
5
5
|
|
|
6
|
-
- `
|
|
7
|
-
- `Flask-
|
|
6
|
+
- `Flask-Admin <https://github.com/pallets-eco/flask-admin/>`_
|
|
7
|
+
- `Flask-Security <https://github.com/pallets-eco/flask-security/>`_
|
|
8
8
|
|
|
9
|
-
Flask-Exts is
|
|
9
|
+
Flask-Exts is partially rewrited from above and well tested.
|
|
10
10
|
|
|
11
11
|
License
|
|
12
12
|
-------
|
|
@@ -6,8 +6,6 @@ Configuration
|
|
|
6
6
|
==============
|
|
7
7
|
|
|
8
8
|
========================== =====================================================================
|
|
9
|
-
``BABEL_ENABLED`` Set to ``False`` to disable babel extension.
|
|
10
|
-
Default is ``True``.
|
|
11
9
|
``BABEL_ACCEPT_LANGUAGES`` Set to ``en;zh`` to bebel's accept languages.
|
|
12
10
|
Default is ``None``.
|
|
13
11
|
``BABEL_DEFAULT_TIMEZONE`` Set to ``Asia/Shanghai`` to babel's default timezone.
|
|
@@ -20,17 +18,8 @@ Configuration
|
|
|
20
18
|
Default is ``csrf_token``.
|
|
21
19
|
``CSRF_TIME_LIMIT`` Max age in seconds for CSRF tokens.
|
|
22
20
|
Default is ``1800``.
|
|
23
|
-
``
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
Default is ``template.theme.BootstrapTheme(4)``
|
|
27
|
-
``USER_ENABLED`` Set to ``False`` to disable ``User`` support.
|
|
28
|
-
Default is ``True``.
|
|
29
|
-
``ADMIN_ENABLED`` Set to ``False`` to disable ``Admin`` support.
|
|
30
|
-
Default is ``True``.
|
|
31
|
-
``USER_CENTER`` set to ``user center`` to create custom user_center
|
|
32
|
-
Default is ``users.user_center.DefaultUserCenter()``
|
|
33
|
-
``FLASK_LOGIN_ENABLED`` Set to ``False`` to disable ``Flask-Login``.
|
|
34
|
-
Default is ``True``.
|
|
21
|
+
``VERIFY_EMAIL_SENDER`` Email address used to send verification emails.
|
|
22
|
+
It is a dict for smtp with keys: host,port,user,password.
|
|
23
|
+
Default is None.
|
|
35
24
|
========================== =====================================================================
|
|
36
25
|
|
|
@@ -6,7 +6,14 @@
|
|
|
6
6
|
Welcome to Flask-Exts's documentation!
|
|
7
7
|
======================================
|
|
8
8
|
|
|
9
|
-
**Flask-Exts** is a Flask extensions with
|
|
9
|
+
**Flask-Exts** is a Flask extensions with SQLAlchemy, babel, forms, fields, widgets, and so on.
|
|
10
|
+
|
|
11
|
+
Flask-Exts is mainly inspired by:
|
|
12
|
+
|
|
13
|
+
- `Flask-Admin <https://github.com/pallets-eco/flask-admin/>`_
|
|
14
|
+
- `Flask-Security <https://github.com/pallets-eco/flask-security/>`_
|
|
15
|
+
|
|
16
|
+
Flask-Exts is partially rewrited from above and well tested.
|
|
10
17
|
|
|
11
18
|
.. _installation:
|
|
12
19
|
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
1
|
from enum import Enum
|
|
3
2
|
from flask import Flask, render_template, request, flash, redirect, url_for
|
|
4
3
|
from markupsafe import Markup
|
|
5
4
|
from wtforms.validators import DataRequired, Length, Regexp
|
|
6
5
|
from wtforms.fields import *
|
|
7
|
-
from
|
|
8
|
-
from flask_exts.
|
|
9
|
-
from flask_exts.forms.fields import SwitchField
|
|
6
|
+
from flask_exts.template.form.flask_form import FlaskForm
|
|
7
|
+
from flask_exts.template.fields import SwitchField
|
|
10
8
|
from flask_exts import Manager
|
|
9
|
+
from flask_exts.datastore.sqla import db
|
|
11
10
|
|
|
12
11
|
manager = Manager()
|
|
13
12
|
|
|
@@ -16,7 +15,6 @@ app.secret_key = 'dev'
|
|
|
16
15
|
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:'
|
|
17
16
|
app.config['ADMIN_ENABLED'] = False
|
|
18
17
|
manager.init_app(app)
|
|
19
|
-
db = SQLAlchemy(app)
|
|
20
18
|
|
|
21
19
|
class ExampleForm(FlaskForm):
|
|
22
20
|
"""An example form that contains all the supported bootstrap style form fields."""
|
|
@@ -1,29 +1,30 @@
|
|
|
1
1
|
from enum import Enum
|
|
2
2
|
from flask import Flask, render_template, request, flash, redirect, url_for
|
|
3
|
-
from flask import current_app
|
|
4
3
|
from markupsafe import Markup
|
|
5
4
|
from wtforms.validators import DataRequired, Length, Regexp
|
|
6
5
|
from wtforms.fields import *
|
|
7
|
-
from flask_sqlalchemy import SQLAlchemy
|
|
8
6
|
|
|
9
|
-
from flask_exts.
|
|
10
|
-
from flask_exts.
|
|
7
|
+
from flask_exts.template.form.flask_form import FlaskForm
|
|
8
|
+
from flask_exts.template.fields import SwitchField
|
|
11
9
|
from flask_exts import Manager
|
|
12
10
|
from flask_exts.template.theme import BootstrapTheme
|
|
11
|
+
from flask_exts.datastore.sqla import db
|
|
13
12
|
|
|
14
|
-
theme = BootstrapTheme(version=5)
|
|
15
13
|
|
|
16
|
-
manager = Manager()
|
|
17
14
|
app = Flask(__name__)
|
|
18
15
|
app.secret_key = "dev"
|
|
19
16
|
|
|
20
17
|
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
|
|
21
18
|
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///:memory:"
|
|
22
19
|
# set bootstrap5
|
|
23
|
-
app.config["TEMPLATE_THEME"] = theme
|
|
24
20
|
app.config['ADMIN_ENABLED'] = False
|
|
21
|
+
|
|
22
|
+
class MyManager(Manager):
|
|
23
|
+
def get_theme(self):
|
|
24
|
+
return BootstrapTheme(5)
|
|
25
|
+
|
|
26
|
+
manager = MyManager()
|
|
25
27
|
manager.init_app(app)
|
|
26
|
-
db = SQLAlchemy(app)
|
|
27
28
|
|
|
28
29
|
|
|
29
30
|
class ExampleForm(FlaskForm):
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from .views.my_view import myview
|
|
2
|
+
from .views.user_view import userview
|
|
3
|
+
from .views.keyword_view import keywordview
|
|
4
|
+
from .views.tree_view import treeview
|
|
5
|
+
from .views.tag_view import tagview
|
|
6
|
+
from .views.author_view import authorview
|
|
7
|
+
from .views.post_view import postview
|
|
8
|
+
from .views.location_image_view import locationview
|
|
9
|
+
from flask_exts.admin.menu import MenuLink
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def add_views(app):
|
|
13
|
+
admin = app.extensions["manager"].admin
|
|
14
|
+
|
|
15
|
+
admin.add_view(myview)
|
|
16
|
+
admin.add_view(userview)
|
|
17
|
+
admin.add_view(keywordview)
|
|
18
|
+
admin.add_view(authorview)
|
|
19
|
+
admin.add_view(tagview)
|
|
20
|
+
admin.add_view(postview)
|
|
21
|
+
admin.add_view(treeview)
|
|
22
|
+
admin.add_view(locationview)
|
|
23
|
+
admin.menu.add_link(
|
|
24
|
+
MenuLink(name="locationlist", url="/locationlist", category="List")
|
|
25
|
+
)
|
|
26
|
+
admin.menu.add_category(name="Links")
|
|
27
|
+
admin.menu.add_link(MenuLink(name="Back Home", url="/", category="Links"))
|
|
28
|
+
admin.menu.add_sub_category(name='External',parent_name='Links')
|
|
29
|
+
# admin.menu.add_link(
|
|
30
|
+
# MenuLink(name="External link", url="http://www.example.com/", category="External")
|
|
31
|
+
# )
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import random
|
|
2
2
|
import datetime
|
|
3
|
+
from flask_exts.proxies import _usercenter
|
|
3
4
|
from .models import db
|
|
4
5
|
from .models.author import Author
|
|
5
6
|
from .models.author import AVAILABLE_USER_TYPES
|
|
@@ -7,11 +8,30 @@ from .models.tag import Tag
|
|
|
7
8
|
from .models.post import Post
|
|
8
9
|
from .models.tree import Tree
|
|
9
10
|
from .models.keyword import Keyword
|
|
10
|
-
from .models.user import
|
|
11
|
+
from .models.user import MyUser
|
|
12
|
+
from .models.location_image import ImageType
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def build_user_admin():
|
|
16
|
+
u, _ = _usercenter.create_user(
|
|
17
|
+
username="admin", password="admin", email="admin@example.com"
|
|
18
|
+
)
|
|
19
|
+
r, _ = _usercenter.create_role(name="admin")
|
|
20
|
+
_usercenter.user_add_role(u, r)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def build_sample_image_type():
|
|
24
|
+
|
|
25
|
+
# Add some image types for the form_ajax_refs inside the inline_model
|
|
26
|
+
image_types = ("JPEG", "PNG", "GIF")
|
|
27
|
+
for image_type in image_types:
|
|
28
|
+
itype = ImageType(name=image_type)
|
|
29
|
+
db.session.add(itype)
|
|
30
|
+
db.session.commit()
|
|
11
31
|
|
|
12
32
|
|
|
13
33
|
def build_sample_userkeyword():
|
|
14
|
-
user_log =
|
|
34
|
+
user_log = MyUser()
|
|
15
35
|
user_log.username = "log"
|
|
16
36
|
user_log.email = "log"
|
|
17
37
|
user_log.password = "log"
|
|
@@ -215,5 +235,7 @@ def build_sample_db():
|
|
|
215
235
|
build_sample_userkeyword()
|
|
216
236
|
build_sample_tree()
|
|
217
237
|
build_sample_post()
|
|
238
|
+
build_user_admin()
|
|
239
|
+
build_sample_image_type()
|
|
218
240
|
|
|
219
241
|
return
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import os.path as op
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
# Figure out base upload path
|
|
5
|
+
static_path = op.join(op.dirname(__file__), "static")
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def remove_image(image_path):
|
|
9
|
+
os.remove(op.join(static_path, image_path))
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def save_image(file_data, image_path):
|
|
13
|
+
file_data.save(op.join(static_path, image_path))
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import os.path as op
|
|
2
2
|
from flask import Flask
|
|
3
3
|
from flask_exts import Manager
|
|
4
|
-
|
|
4
|
+
|
|
5
|
+
class MyManager(Manager):
|
|
6
|
+
def get_admin_class(self):
|
|
7
|
+
from flask_exts.admin.admin import Admin
|
|
8
|
+
return Admin
|
|
5
9
|
|
|
6
10
|
|
|
7
11
|
def get_sqlite_path():
|
|
@@ -10,44 +14,43 @@ def get_sqlite_path():
|
|
|
10
14
|
return database_path
|
|
11
15
|
|
|
12
16
|
|
|
13
|
-
def register_users(app):
|
|
14
|
-
user_center = app.config["USER_CENTER"]
|
|
15
|
-
user_center.register_user("admin", "admin", "admin@example.com")
|
|
16
|
-
|
|
17
|
-
|
|
18
17
|
def create_app():
|
|
19
|
-
app = Flask(__name__)
|
|
18
|
+
app = Flask(__name__, instance_relative_config=True)
|
|
20
19
|
app.config["SECRET_KEY"] = "dev"
|
|
21
|
-
|
|
20
|
+
app.config.from_pyfile('config.py',silent=True)
|
|
21
|
+
app.config.from_pyfile('config_prod.py',silent=True)
|
|
22
22
|
# app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///:memory:"
|
|
23
23
|
# app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://'
|
|
24
24
|
# app.config["SQLALCHEMY_ECHO"] = True
|
|
25
25
|
app.config["DATABASE_FILE"] = get_sqlite_path()
|
|
26
26
|
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///" + app.config["DATABASE_FILE"]
|
|
27
|
-
|
|
28
|
-
app.config["USER_CENTER"] = UserCenter()
|
|
29
|
-
|
|
30
27
|
init_app(app)
|
|
31
|
-
|
|
32
28
|
return app
|
|
33
29
|
|
|
34
30
|
|
|
35
31
|
def init_app(app: Flask):
|
|
32
|
+
manager = MyManager()
|
|
33
|
+
manager.init_app(app)
|
|
36
34
|
|
|
37
|
-
from .models import
|
|
38
|
-
|
|
39
|
-
init_db(app)
|
|
35
|
+
from .models import init_models
|
|
40
36
|
|
|
41
|
-
|
|
42
|
-
manager.init_app(app)
|
|
37
|
+
init_models()
|
|
43
38
|
|
|
44
39
|
from .admin_views import add_views
|
|
45
40
|
|
|
46
41
|
add_views(app)
|
|
47
42
|
|
|
43
|
+
@app.route("/locationlist")
|
|
44
|
+
def location_list():
|
|
45
|
+
from .models.location_image import Location
|
|
46
|
+
from flask import render_template
|
|
47
|
+
from .models import db
|
|
48
|
+
|
|
49
|
+
locations = db.session.query(Location).all()
|
|
50
|
+
return render_template("locations.html", locations=locations)
|
|
51
|
+
|
|
48
52
|
if not op.exists(app.config["DATABASE_FILE"]):
|
|
49
53
|
with app.app_context():
|
|
50
54
|
from .build_sample import build_sample_db
|
|
51
55
|
|
|
52
56
|
build_sample_db()
|
|
53
|
-
register_users(app)
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
from . import db
|
|
2
2
|
from typing import Optional
|
|
3
|
+
from typing import List
|
|
3
4
|
from sqlalchemy import ForeignKey
|
|
4
5
|
from sqlalchemy.orm import relationship
|
|
5
6
|
from sqlalchemy.orm import Mapped
|
|
6
7
|
from sqlalchemy.orm import mapped_column
|
|
7
|
-
|
|
8
|
+
from sqlalchemy import event
|
|
9
|
+
from ..file_op import remove_image
|
|
8
10
|
|
|
9
11
|
class Location(db.Model):
|
|
10
12
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
11
13
|
name: Mapped[str]
|
|
14
|
+
images: Mapped[List["LocationImage"]] = relationship(
|
|
15
|
+
"LocationImage", back_populates="location", cascade="all, delete-orphan"
|
|
16
|
+
)
|
|
12
17
|
|
|
13
18
|
|
|
14
19
|
class ImageType(db.Model):
|
|
@@ -33,10 +38,21 @@ class LocationImage(db.Model):
|
|
|
33
38
|
alt: Mapped[str]
|
|
34
39
|
path: Mapped[str]
|
|
35
40
|
|
|
36
|
-
location_id
|
|
37
|
-
location: Mapped["Location"] = relationship(
|
|
41
|
+
location_id = mapped_column(ForeignKey("location.id"))
|
|
42
|
+
location: Mapped["Location"] = relationship(back_populates="images")
|
|
43
|
+
|
|
44
|
+
image_type_id = mapped_column(ForeignKey("image_type.id"))
|
|
45
|
+
image_type: Mapped["ImageType"] = relationship()
|
|
46
|
+
|
|
38
47
|
|
|
39
|
-
image_type_id: Mapped[int] = mapped_column(ForeignKey("image_type.id"))
|
|
40
|
-
image_type: Mapped["ImageType"] = relationship(backref='images')
|
|
41
48
|
|
|
42
49
|
|
|
50
|
+
# Register after_delete handler which will delete image file after model gets deleted
|
|
51
|
+
@event.listens_for(Location, "after_delete")
|
|
52
|
+
def _handle_image_delete(mapper, conn, target):
|
|
53
|
+
for location_image in target.images:
|
|
54
|
+
try:
|
|
55
|
+
if location_image.path:
|
|
56
|
+
remove_image(location_image.path)
|
|
57
|
+
except:
|
|
58
|
+
pass
|
|
@@ -5,6 +5,7 @@ from sqlalchemy.orm import relationship
|
|
|
5
5
|
from sqlalchemy.orm import Mapped
|
|
6
6
|
from sqlalchemy.orm import mapped_column
|
|
7
7
|
|
|
8
|
+
|
|
8
9
|
class Tree(db.Model):
|
|
9
10
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
10
11
|
name: Mapped[str]
|
|
@@ -12,7 +13,7 @@ class Tree(db.Model):
|
|
|
12
13
|
# recursive relationship
|
|
13
14
|
parent_id: Mapped[Optional[int]] = mapped_column(ForeignKey("tree.id"))
|
|
14
15
|
parent = relationship("Tree", back_populates="children", remote_side=id)
|
|
15
|
-
children = relationship("Tree",back_populates="parent")
|
|
16
|
+
children = relationship("Tree", back_populates="parent")
|
|
16
17
|
|
|
17
18
|
def __str__(self):
|
|
18
|
-
return "{}".format(self.name)
|
|
19
|
+
return "{}".format(self.name)
|
|
@@ -5,12 +5,12 @@ from sqlalchemy.orm import mapped_column
|
|
|
5
5
|
from sqlalchemy.orm import relationship
|
|
6
6
|
from sqlalchemy.ext.associationproxy import association_proxy
|
|
7
7
|
from sqlalchemy.ext.associationproxy import AssociationProxy
|
|
8
|
-
from flask_login import UserMixin
|
|
9
8
|
from . import db
|
|
10
9
|
from .keyword import Keyword
|
|
11
10
|
from .user_keyword import UserKeywordAssociation
|
|
12
11
|
|
|
13
|
-
class
|
|
12
|
+
class MyUser(db.Model):
|
|
13
|
+
__tablename__="myuser"
|
|
14
14
|
id: Mapped[int] = mapped_column(primary_key=True)
|
|
15
15
|
username: Mapped[str]
|
|
16
16
|
email: Mapped[str]
|
|
@@ -21,7 +21,7 @@ class User(db.Model, UserMixin):
|
|
|
21
21
|
)
|
|
22
22
|
|
|
23
23
|
user_keyword_associations: Mapped[List["UserKeywordAssociation"]] = relationship(
|
|
24
|
-
back_populates="
|
|
24
|
+
back_populates="myuser",
|
|
25
25
|
cascade="all, delete-orphan",
|
|
26
26
|
)
|
|
27
27
|
|
|
@@ -10,17 +10,17 @@ from .keyword import Keyword
|
|
|
10
10
|
|
|
11
11
|
class UserKeywordAssociation(db.Model):
|
|
12
12
|
__tablename__ = "user_keyword"
|
|
13
|
-
|
|
13
|
+
myuser_id = mapped_column(ForeignKey("myuser.id"), primary_key=True)
|
|
14
14
|
keyword_id = mapped_column(ForeignKey("keyword.id"), primary_key=True)
|
|
15
15
|
special_key: Mapped[Optional[str]]
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
myuser: Mapped["MyUser"] = relationship(back_populates="user_keyword_associations")
|
|
18
18
|
keyword: Mapped[Keyword] = relationship()
|
|
19
19
|
|
|
20
20
|
# Reference to the "keyword" column inside the "Keyword" object.
|
|
21
21
|
keyword_value = association_proxy('keyword', 'keyword')
|
|
22
22
|
|
|
23
|
-
def __init__(self, keyword=None,
|
|
24
|
-
self.
|
|
23
|
+
def __init__(self, keyword=None, myuser=None, special_key=None):
|
|
24
|
+
self.myuser = myuser
|
|
25
25
|
self.keyword = keyword
|
|
26
26
|
self.special_key = special_key
|
|
@@ -4,12 +4,10 @@ from flask_babel import gettext
|
|
|
4
4
|
from flask_exts.admin.sqla.filters import BaseSQLAFilter
|
|
5
5
|
from flask_exts.admin.sqla.filters import FilterEqual
|
|
6
6
|
from flask_exts.admin.sqla import ModelView
|
|
7
|
-
from ..models import
|
|
8
|
-
from ..models.author import Author,AVAILABLE_USER_TYPES
|
|
7
|
+
from ..models.author import Author, AVAILABLE_USER_TYPES
|
|
9
8
|
from ..models.post import Post
|
|
10
9
|
|
|
11
10
|
|
|
12
|
-
|
|
13
11
|
# Custom filter class
|
|
14
12
|
class FilterLastNameBrown(BaseSQLAFilter):
|
|
15
13
|
def apply(self, query, value, alias=None):
|
|
@@ -133,4 +131,4 @@ class AuthorView(ModelView):
|
|
|
133
131
|
return form
|
|
134
132
|
|
|
135
133
|
|
|
136
|
-
authorview = AuthorView(Author
|
|
134
|
+
authorview = AuthorView(Author)
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
from flask_exts.admin.sqla import ModelView
|
|
2
|
-
from ..models import db
|
|
3
2
|
from ..models.keyword import Keyword
|
|
4
3
|
|
|
5
4
|
|
|
@@ -7,4 +6,4 @@ class KeywordView(ModelView):
|
|
|
7
6
|
column_list = ("id", "keyword")
|
|
8
7
|
|
|
9
8
|
|
|
10
|
-
keywordview = KeywordView(Keyword
|
|
9
|
+
keywordview = KeywordView(Keyword)
|
|
@@ -3,13 +3,13 @@ from flask import request
|
|
|
3
3
|
from flask import current_app
|
|
4
4
|
from wtforms.fields import FileField
|
|
5
5
|
from flask_exts.admin.sqla.ajax import QueryAjaxModelLoader
|
|
6
|
-
from flask_exts.
|
|
6
|
+
from flask_exts.template.widgets.render_template import RenderTemplateWidget
|
|
7
7
|
from flask_exts.admin.model.form import InlineFormAdmin
|
|
8
8
|
from flask_exts.admin.sqla import ModelView
|
|
9
9
|
from flask_exts.admin.sqla.form import InlineModelConverter
|
|
10
|
-
from flask_exts.
|
|
11
|
-
from ..models import
|
|
12
|
-
from ..
|
|
10
|
+
from flask_exts.template.fields.sqla import InlineModelFormList
|
|
11
|
+
from ..models.location_image import ImageType, Location, LocationImage
|
|
12
|
+
from ..file_op import save_image
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
# This widget uses custom template for inline field list
|
|
@@ -41,7 +41,6 @@ class LocationImageInlineModelForm(InlineFormAdmin):
|
|
|
41
41
|
form_ajax_refs = {
|
|
42
42
|
"image_type": QueryAjaxModelLoader(
|
|
43
43
|
name="image_type",
|
|
44
|
-
session=db.session,
|
|
45
44
|
model=ImageType,
|
|
46
45
|
fields=("name",),
|
|
47
46
|
order_by="name",
|
|
@@ -62,7 +61,7 @@ class LocationImageInlineModelForm(InlineFormAdmin):
|
|
|
62
61
|
|
|
63
62
|
if file_data:
|
|
64
63
|
model.path = secure_filename(file_data.filename)
|
|
65
|
-
|
|
64
|
+
save_image(file_data, model.path)
|
|
66
65
|
|
|
67
66
|
|
|
68
67
|
# Administrative class
|
|
@@ -72,7 +71,7 @@ class LocationView(ModelView):
|
|
|
72
71
|
inline_models = (LocationImageInlineModelForm(),)
|
|
73
72
|
|
|
74
73
|
def __init__(self):
|
|
75
|
-
super().__init__(Location,
|
|
74
|
+
super().__init__(Location, name="Locations")
|
|
76
75
|
|
|
77
76
|
|
|
78
77
|
locationview = LocationView()
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
from wtforms import validators
|
|
2
2
|
from flask_exts.admin.sqla import ModelView
|
|
3
3
|
from flask_exts.admin.sqla.filters import FilterLike
|
|
4
|
-
from ..models import db
|
|
5
4
|
from ..models.post import Post
|
|
6
5
|
from ..models.author import Author
|
|
7
6
|
|
|
8
7
|
|
|
9
8
|
# Customized Post model admin
|
|
10
9
|
class PostView(ModelView):
|
|
10
|
+
can_view_details = True
|
|
11
11
|
column_display_pk = True
|
|
12
12
|
column_list = [
|
|
13
13
|
"id",
|
|
@@ -24,6 +24,8 @@ class PostView(ModelView):
|
|
|
24
24
|
column_default_sort = ("date", True)
|
|
25
25
|
create_modal = True
|
|
26
26
|
# edit_modal = True
|
|
27
|
+
# details_modal = True
|
|
28
|
+
|
|
27
29
|
column_sortable_list = [
|
|
28
30
|
"id",
|
|
29
31
|
"title",
|
|
@@ -80,8 +82,12 @@ class PostView(ModelView):
|
|
|
80
82
|
# },
|
|
81
83
|
}
|
|
82
84
|
|
|
85
|
+
column_descriptions = dict(
|
|
86
|
+
color='favorite color'
|
|
87
|
+
)
|
|
88
|
+
|
|
83
89
|
|
|
84
90
|
# Add views
|
|
85
91
|
|
|
86
92
|
|
|
87
|
-
postview = PostView(Post
|
|
93
|
+
postview = PostView(Post)
|
|
@@ -1,20 +1,27 @@
|
|
|
1
1
|
from flask_exts.admin.sqla import ModelView
|
|
2
|
-
from ..models import db
|
|
3
2
|
from ..models.tree import Tree
|
|
4
3
|
|
|
4
|
+
|
|
5
5
|
class TreeView(ModelView):
|
|
6
|
-
list_template =
|
|
6
|
+
list_template = "tree_list.html"
|
|
7
7
|
column_auto_select_related = True
|
|
8
8
|
column_list = [
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
"id",
|
|
10
|
+
"name",
|
|
11
|
+
"parent",
|
|
12
|
+
]
|
|
13
|
+
form_excluded_columns = [
|
|
14
|
+
"children",
|
|
15
|
+
]
|
|
16
|
+
column_filters = [
|
|
17
|
+
"id",
|
|
18
|
+
"name",
|
|
19
|
+
"parent",
|
|
12
20
|
]
|
|
13
|
-
form_excluded_columns = ['children', ]
|
|
14
|
-
column_filters = ['id', 'name', 'parent', ]
|
|
15
21
|
|
|
16
22
|
# override the 'render' method to pass your own parameters to the template
|
|
17
23
|
def render(self, template, **kwargs):
|
|
18
24
|
return super().render(template, foo="bar", **kwargs)
|
|
19
25
|
|
|
20
|
-
|
|
26
|
+
|
|
27
|
+
treeview = TreeView(Tree)
|