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.
Files changed (404) hide show
  1. {flask_exts-0.2.1 → flask_exts-0.2.3}/.gitignore +3 -0
  2. {flask_exts-0.2.1 → flask_exts-0.2.3}/CHANGES.rst +23 -0
  3. {flask_exts-0.2.1 → flask_exts-0.2.3}/PKG-INFO +7 -4
  4. {flask_exts-0.2.1 → flask_exts-0.2.3}/README.rst +3 -3
  5. {flask_exts-0.2.1 → flask_exts-0.2.3}/docs/configure.rst +3 -14
  6. {flask_exts-0.2.1 → flask_exts-0.2.3}/docs/index.rst +8 -1
  7. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap4/app.py +3 -5
  8. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap5/app.py +9 -8
  9. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap5/templates/pagination.html +1 -1
  10. flask_exts-0.2.3/examples/demo/admin_views.py +31 -0
  11. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/build_sample.py +24 -2
  12. flask_exts-0.2.3/examples/demo/file_op.py +13 -0
  13. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/make_app.py +21 -18
  14. flask_exts-0.2.3/examples/demo/models/__init__.py +12 -0
  15. 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
  16. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/models/tree.py +3 -2
  17. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/models/user.py +3 -3
  18. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/models/user_keyword.py +4 -4
  19. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/views/author_view.py +2 -4
  20. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/views/keyword_view.py +1 -2
  21. 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
  22. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/views/post_view.py +8 -2
  23. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/views/tag_view.py +1 -2
  24. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/views/tree_view.py +15 -8
  25. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/views/user_view.py +2 -3
  26. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/fileadmin/make_app.py +6 -6
  27. flask_exts-0.2.3/examples/instance/config.py +3 -0
  28. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/rediscli.py +2 -1
  29. flask_exts-0.2.3/examples/simple.py +27 -0
  30. {flask_exts-0.2.1 → flask_exts-0.2.3}/pyproject.toml +7 -0
  31. flask_exts-0.2.3/src/flask_exts/__about__.py +1 -0
  32. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/admin/__init__.py +0 -1
  33. flask_exts-0.2.3/src/flask_exts/admin/admin.py +15 -0
  34. flask_exts-0.2.3/src/flask_exts/admin/base_admin.py +125 -0
  35. flask_exts-0.2.3/src/flask_exts/admin/menu.py +280 -0
  36. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/admin/model/filters.py +27 -72
  37. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/admin/model/form.py +3 -3
  38. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/admin/model/typefmt.py +4 -5
  39. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/admin/model/view.py +13 -23
  40. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/admin/sqla/ajax.py +42 -20
  41. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/admin/sqla/form.py +22 -47
  42. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/admin/sqla/typefmt.py +0 -12
  43. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/admin/sqla/view.py +333 -272
  44. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/admin/view.py +26 -46
  45. flask_exts-0.2.3/src/flask_exts/commands.py +34 -0
  46. {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
  47. flask_exts-0.2.3/src/flask_exts/datastore/sqla/models/role.py +15 -0
  48. flask_exts-0.2.3/src/flask_exts/datastore/sqla/models/user.py +70 -0
  49. flask_exts-0.2.3/src/flask_exts/datastore/sqla/models/user_profile.py +29 -0
  50. flask_exts-0.2.3/src/flask_exts/datastore/sqla/models/webauthn.py +38 -0
  51. flask_exts-0.2.3/src/flask_exts/datastore/sqla/orm.py +12 -0
  52. flask_exts-0.2.3/src/flask_exts/email/base.py +43 -0
  53. flask_exts-0.2.3/src/flask_exts/email/sender.py +6 -0
  54. flask_exts-0.2.3/src/flask_exts/email/smtp.py +41 -0
  55. flask_exts-0.2.3/src/flask_exts/email/verify_email_sender.py +12 -0
  56. flask_exts-0.2.3/src/flask_exts/forms/login.py +13 -0
  57. {flask_exts-0.2.1/src/flask_exts/users → flask_exts-0.2.3/src/flask_exts}/forms/profile.py +1 -1
  58. 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
  59. flask_exts-0.2.3/src/flask_exts/manager.py +83 -0
  60. flask_exts-0.2.3/src/flask_exts/proxies.py +22 -0
  61. flask_exts-0.2.3/src/flask_exts/security/__init__.py +6 -0
  62. flask_exts-0.2.3/src/flask_exts/security/authorizer/base.py +21 -0
  63. flask_exts-0.2.3/src/flask_exts/security/authorizer/casbin_authorizer.py +111 -0
  64. flask_exts-0.2.3/src/flask_exts/security/authorizer/sqlalchemy_adapter.py +245 -0
  65. flask_exts-0.2.3/src/flask_exts/security/core.py +29 -0
  66. flask_exts-0.2.3/src/flask_exts/security/email_verification.py +83 -0
  67. flask_exts-0.2.3/src/flask_exts/security/hasher.py +22 -0
  68. flask_exts-0.2.3/src/flask_exts/security/principal/identity.py +37 -0
  69. flask_exts-0.2.3/src/flask_exts/security/principal/identity_context.py +52 -0
  70. flask_exts-0.2.3/src/flask_exts/security/principal/permission.py +297 -0
  71. flask_exts-0.2.3/src/flask_exts/security/principal/principal.py +197 -0
  72. flask_exts-0.2.3/src/flask_exts/security/serializer.py +50 -0
  73. flask_exts-0.2.3/src/flask_exts/signals.py +7 -0
  74. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/js/filters.js +18 -8
  75. flask_exts-0.2.3/src/flask_exts/static/js/form.js +680 -0
  76. flask_exts-0.2.3/src/flask_exts/static/js/helper.js +7 -0
  77. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/js/modal.js +4 -1
  78. flask_exts-0.2.3/src/flask_exts/static/js/security/base64.js +127 -0
  79. flask_exts-0.2.3/src/flask_exts/static/js/security/webauthn.js +193 -0
  80. {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
  81. flask_exts-0.2.3/src/flask_exts/static/vendor/vanilla-editor/js/bootstrap-editable.min.js +1 -0
  82. flask_exts-0.2.3/src/flask_exts/template/base.py +48 -0
  83. {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/fields/__init__.py +2 -1
  84. {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/fields/datetime.py +6 -2
  85. {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/fields/sqla.py +4 -4
  86. {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/form/base_form.py +1 -1
  87. flask_exts-0.2.3/src/flask_exts/template/form/csrf.py +65 -0
  88. flask_exts-0.2.3/src/flask_exts/template/form/form_opts.py +6 -0
  89. {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/form/meta.py +2 -25
  90. {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template/form}/utils.py +0 -9
  91. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/template/utils.py +0 -16
  92. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/admin/base.html +13 -6
  93. flask_exts-0.2.3/src/flask_exts/templates/admin/index.html +11 -0
  94. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/admin/model/list.html +3 -10
  95. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/admin/model/modals/create.html +0 -3
  96. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/admin/model/modals/details.html +0 -1
  97. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/admin/model/modals/edit.html +0 -5
  98. flask_exts-0.2.3/src/flask_exts/templates/index.html +22 -0
  99. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/macro/actions.html +1 -4
  100. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/macro/inline.html +2 -2
  101. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/macro/layout.html +1 -3
  102. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/macro/menu.html +12 -20
  103. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/macro/row_actions.html +5 -5
  104. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/macro/vendor.html +2 -2
  105. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/views/file/list.html +4 -9
  106. flask_exts-0.2.3/src/flask_exts/templates/views/user/verify_email.html +9 -0
  107. flask_exts-0.2.1/src/flask_exts/_types.py → flask_exts-0.2.3/src/flask_exts/types.py +1 -1
  108. flask_exts-0.2.3/src/flask_exts/usercenter/base_user.py +7 -0
  109. flask_exts-0.2.3/src/flask_exts/usercenter/base_usercenter.py +40 -0
  110. flask_exts-0.2.3/src/flask_exts/usercenter/sqla_usercenter.py +101 -0
  111. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/utils/__init__.py +1 -1
  112. flask_exts-0.2.3/src/flask_exts/utils/authorize.py +21 -0
  113. flask_exts-0.2.3/src/flask_exts/utils/decorators.py +47 -0
  114. flask_exts-0.2.3/src/flask_exts/utils/flask.py +16 -0
  115. flask_exts-0.2.3/src/flask_exts/utils/jwt.py +34 -0
  116. flask_exts-0.2.3/src/flask_exts/utils/request_user.py +64 -0
  117. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/utils/sqla.py +0 -5
  118. flask_exts-0.2.1/src/flask_exts/utils/flask.py → flask_exts-0.2.3/src/flask_exts/utils/url.py +0 -14
  119. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/views/file_view/base_file_view.py +4 -5
  120. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/views/index_view.py +6 -5
  121. flask_exts-0.2.3/src/flask_exts/views/rediscli_view.py +190 -0
  122. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/views/user_view.py +32 -29
  123. flask_exts-0.2.3/tests/__init__.py +1 -0
  124. flask_exts-0.2.3/tests/admin/__init__.py +0 -0
  125. flask_exts-0.2.3/tests/admin/customer/conftest.py +44 -0
  126. flask_exts-0.2.3/tests/admin/customer/test_admin.py +97 -0
  127. flask_exts-0.2.3/tests/admin/sqla/__init__.py +0 -0
  128. {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/admin/sqla/test_basic.py +589 -944
  129. flask_exts-0.2.3/tests/admin/sqla/test_form_rules.py +86 -0
  130. flask_exts-0.2.3/tests/admin/sqla/test_inlineform.py +196 -0
  131. flask_exts-0.2.3/tests/admin/sqla/test_multi_pk.py +132 -0
  132. {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/admin/sqla/test_translation.py +9 -9
  133. flask_exts-0.2.3/tests/admin/test_base.py +153 -0
  134. {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/admin/test_model.py +80 -79
  135. flask_exts-0.2.3/tests/conftest.py +46 -0
  136. flask_exts-0.2.3/tests/email/test_base.py +18 -0
  137. flask_exts-0.2.3/tests/email/test_smtp.py +24 -0
  138. flask_exts-0.2.3/tests/models/__init__.py +6 -0
  139. flask_exts-0.2.3/tests/models/message.py +15 -0
  140. flask_exts-0.2.3/tests/models/model1.py +175 -0
  141. flask_exts-0.2.3/tests/models/multpk.py +7 -0
  142. flask_exts-0.2.3/tests/models/polymorphic.py +35 -0
  143. flask_exts-0.2.3/tests/models/tree.py +7 -0
  144. flask_exts-0.2.3/tests/models/user.py +41 -0
  145. flask_exts-0.2.3/tests/security/authorizer/__init__.py +0 -0
  146. flask_exts-0.2.3/tests/security/authorizer/casbin_adapter/rbac_model.conf +14 -0
  147. flask_exts-0.2.3/tests/security/authorizer/casbin_adapter/rbac_policy.csv +6 -0
  148. flask_exts-0.2.3/tests/security/authorizer/casbin_adapter/test_sqlalchemy_adapter.py +392 -0
  149. flask_exts-0.2.3/tests/security/authorizer/casbin_files/authz_policy.csv +11 -0
  150. flask_exts-0.2.3/tests/security/authorizer/casbin_files/rbac_model.conf +14 -0
  151. flask_exts-0.2.3/tests/security/authorizer/casbin_files/rbac_policy.csv +8 -0
  152. flask_exts-0.2.3/tests/security/authorizer/test_casbin_auth.py +148 -0
  153. flask_exts-0.2.3/tests/security/test_core.py +41 -0
  154. flask_exts-0.2.3/tests/security/test_principal.py +705 -0
  155. flask_exts-0.2.3/tests/template/__init__.py +0 -0
  156. flask_exts-0.2.3/tests/template/bootstrap4/__init__.py +0 -0
  157. {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/template/bootstrap4/test_render_field.py +17 -21
  158. {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/template/bootstrap4/test_render_form.py +40 -48
  159. {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/template/bootstrap4/test_render_form_row.py +10 -14
  160. {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/template/bootstrap4/test_render_hidden_errors.py +3 -4
  161. {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/template/bootstrap4/test_render_icon_sprite.py +25 -30
  162. {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/template/bootstrap4/test_render_messages.py +15 -19
  163. flask_exts-0.2.3/tests/template/bootstrap4/test_render_pager.py +35 -0
  164. {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/template/bootstrap4/test_render_pagination.py +12 -18
  165. {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/template/bootstrap4/test_render_table.py +51 -115
  166. flask_exts-0.2.3/tests/template/bootstrap5/__init__.py +0 -0
  167. flask_exts-0.2.3/tests/template/bootstrap5/conftest.py +21 -0
  168. {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/template/bootstrap5/test_base.py +2 -2
  169. {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/template/bootstrap5/test_render_form.py +31 -37
  170. {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/template/bootstrap5/test_render_form_row.py +4 -5
  171. {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/template/bootstrap5/test_render_messages.py +2 -3
  172. {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/template/bootstrap5/test_render_pagination.py +8 -13
  173. {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/template/conftest.py +1 -1
  174. flask_exts-0.2.1/tests/forms/test_form.py → flask_exts-0.2.3/tests/template/forms/test_csrf.py +4 -3
  175. {flask_exts-0.2.1/tests → flask_exts-0.2.3/tests/template}/forms/test_fields.py +3 -3
  176. {flask_exts-0.2.1/tests → flask_exts-0.2.3/tests/template}/forms/test_filefield.py +1 -1
  177. {flask_exts-0.2.1/tests → flask_exts-0.2.3/tests/template}/forms/test_uploadfile.py +3 -3
  178. {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/template/macros/test_render_breadcrumb_item.py +4 -6
  179. {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/template/macros/test_render_nav_item.py +4 -6
  180. {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/template/test_base.py +2 -2
  181. flask_exts-0.2.3/tests/templates/mock.html +1 -0
  182. {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/test_babel.py +7 -6
  183. flask_exts-0.2.3/tests/test_base.py +27 -0
  184. flask_exts-0.2.3/tests/test_flask.py +34 -0
  185. flask_exts-0.2.3/tests/usercenter/test_sqla_usercenter.py +34 -0
  186. flask_exts-0.2.3/tests/utils/test_request_user.py +80 -0
  187. {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/utils/test_url.py +1 -1
  188. flask_exts-0.2.3/tests/views/files/dummy.txt +0 -0
  189. {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/views/test_file_view.py +26 -28
  190. flask_exts-0.2.3/tests/views/test_user_view.py +96 -0
  191. flask_exts-0.2.1/examples/demo/admin_views.py +0 -26
  192. flask_exts-0.2.1/examples/demo/models/__init__.py +0 -24
  193. flask_exts-0.2.1/examples/demo/templates/admin/index.html +0 -4
  194. flask_exts-0.2.1/examples/demo/user_center.py +0 -54
  195. flask_exts-0.2.1/examples/multiple_admins/app.py +0 -34
  196. flask_exts-0.2.1/examples/multiple_admins/templates/admin/index.html +0 -7
  197. flask_exts-0.2.1/examples/multiple_admins/templates/first.html +0 -4
  198. flask_exts-0.2.1/examples/multiple_admins/templates/second.html +0 -4
  199. flask_exts-0.2.1/examples/simple.py +0 -13
  200. flask_exts-0.2.1/examples/sqla-custom-inline-forms/__init__.py +0 -1
  201. flask_exts-0.2.1/examples/sqla-custom-inline-forms/data.py +0 -23
  202. flask_exts-0.2.1/examples/sqla-custom-inline-forms/make_app.py +0 -83
  203. flask_exts-0.2.1/examples/sqla-custom-inline-forms/templates/admin/admin.html +0 -5
  204. flask_exts-0.2.1/src/flask_exts/__about__.py +0 -1
  205. flask_exts-0.2.1/src/flask_exts/admin/admin.py +0 -263
  206. flask_exts-0.2.1/src/flask_exts/admin/menu.py +0 -168
  207. flask_exts-0.2.1/src/flask_exts/forms/__init__.py +0 -3
  208. flask_exts-0.2.1/src/flask_exts/forms/form/__init__.py +0 -2
  209. flask_exts-0.2.1/src/flask_exts/forms/form/csrf.py +0 -57
  210. flask_exts-0.2.1/src/flask_exts/manager.py +0 -39
  211. flask_exts-0.2.1/src/flask_exts/static/js/form.js +0 -665
  212. flask_exts-0.2.1/src/flask_exts/static/js/helpers.js +0 -12
  213. flask_exts-0.2.1/src/flask_exts/static/vendor/x-editable/js/bootstrap-editable.min.js +0 -2
  214. flask_exts-0.2.1/src/flask_exts/template/__init__.py +0 -37
  215. flask_exts-0.2.1/src/flask_exts/templates/admin/admin.html +0 -5
  216. flask_exts-0.2.1/src/flask_exts/templates/admin/index.html +0 -6
  217. flask_exts-0.2.1/src/flask_exts/users/__init__.py +0 -15
  218. flask_exts-0.2.1/src/flask_exts/users/default_usercenter.py +0 -51
  219. flask_exts-0.2.1/src/flask_exts/users/forms/__init__.py +0 -2
  220. flask_exts-0.2.1/src/flask_exts/users/forms/login.py +0 -6
  221. flask_exts-0.2.1/src/flask_exts/users/forms/register.py +0 -6
  222. flask_exts-0.2.1/src/flask_exts/users/usercenter.py +0 -19
  223. flask_exts-0.2.1/src/flask_exts/views/rediscli_view.py +0 -191
  224. flask_exts-0.2.1/tests/admin/sqla/conftest.py +0 -20
  225. flask_exts-0.2.1/tests/admin/sqla/test_form_rules.py +0 -96
  226. flask_exts-0.2.1/tests/admin/sqla/test_inlineform.py +0 -289
  227. flask_exts-0.2.1/tests/admin/sqla/test_multi_pk.py +0 -173
  228. flask_exts-0.2.1/tests/admin/test_base.py +0 -248
  229. flask_exts-0.2.1/tests/conftest.py +0 -33
  230. flask_exts-0.2.1/tests/template/bootstrap4/conftest.py +0 -17
  231. flask_exts-0.2.1/tests/template/bootstrap4/test_render_pager.py +0 -42
  232. flask_exts-0.2.1/tests/template/bootstrap5/conftest.py +0 -18
  233. flask_exts-0.2.1/tests/test_base.py +0 -18
  234. flask_exts-0.2.1/tests/views/test_user_view.py +0 -58
  235. {flask_exts-0.2.1 → flask_exts-0.2.3}/.github/workflows/release.yml +0 -0
  236. {flask_exts-0.2.1 → flask_exts-0.2.3}/.readthedocs.yaml +0 -0
  237. {flask_exts-0.2.1 → flask_exts-0.2.3}/LICENSE.rst +0 -0
  238. {flask_exts-0.2.1 → flask_exts-0.2.3}/babel/babel.cfg +0 -0
  239. {flask_exts-0.2.1 → flask_exts-0.2.3}/babel/babel.sh +0 -0
  240. {flask_exts-0.2.1 → flask_exts-0.2.3}/babel/messages.pot +0 -0
  241. {flask_exts-0.2.1 → flask_exts-0.2.3}/docs/Makefile +0 -0
  242. {flask_exts-0.2.1 → flask_exts-0.2.3}/docs/_static/logo.png +0 -0
  243. {flask_exts-0.2.1 → flask_exts-0.2.3}/docs/changes.rst +0 -0
  244. {flask_exts-0.2.1 → flask_exts-0.2.3}/docs/conf.py +0 -0
  245. {flask_exts-0.2.1 → flask_exts-0.2.3}/docs/develop.rst +0 -0
  246. {flask_exts-0.2.1 → flask_exts-0.2.3}/docs/examples.rst +0 -0
  247. {flask_exts-0.2.1 → flask_exts-0.2.3}/docs/make.bat +0 -0
  248. {flask_exts-0.2.1 → flask_exts-0.2.3}/docs/requirements.txt +0 -0
  249. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/README.rst +0 -0
  250. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap4/static/favicon.ico +0 -0
  251. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap4/templates/bootswatch.html +0 -0
  252. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap4/templates/flash.html +0 -0
  253. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap4/templates/form.html +0 -0
  254. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap4/templates/icon.html +0 -0
  255. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap4/templates/icons.html +0 -0
  256. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap4/templates/index.html +0 -0
  257. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap4/templates/mybase.html +0 -0
  258. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap4/templates/nav.html +0 -0
  259. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap4/templates/pagination.html +0 -0
  260. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap4/templates/table.html +0 -0
  261. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap5/static/favicon.ico +0 -0
  262. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap5/templates/bootswatch.html +0 -0
  263. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap5/templates/flash.html +0 -0
  264. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap5/templates/form.html +0 -0
  265. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap5/templates/icon.html +0 -0
  266. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap5/templates/icons.html +0 -0
  267. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap5/templates/index.html +0 -0
  268. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap5/templates/mybase.html +0 -0
  269. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap5/templates/nav.html +0 -0
  270. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/bootstrap5/templates/table.html +0 -0
  271. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/__init__.py +0 -0
  272. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/models/author.py +0 -0
  273. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/models/keyword.py +0 -0
  274. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/models/post.py +0 -0
  275. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/models/post_tag.py +0 -0
  276. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/models/tag.py +0 -0
  277. {flask_exts-0.2.1/examples/sqla-custom-inline-forms → flask_exts-0.2.3/examples/demo}/templates/field_list.html +0 -0
  278. {flask_exts-0.2.1/examples/sqla-custom-inline-forms → flask_exts-0.2.3/examples/demo}/templates/locations.html +0 -0
  279. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/templates/my/index.html +0 -0
  280. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/templates/tree_list.html +0 -0
  281. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/demo/views/my_view.py +0 -0
  282. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/fileadmin/__init__.py +0 -0
  283. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/fileadmin/file_view.py +0 -0
  284. {flask_exts-0.2.1 → flask_exts-0.2.3}/examples/fileadmin/tmp/bbb/a.txt +0 -0
  285. {flask_exts-0.2.1 → flask_exts-0.2.3}/requirements/build.in +0 -0
  286. {flask_exts-0.2.1 → flask_exts-0.2.3}/requirements/test.in +0 -0
  287. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/__init__.py +0 -0
  288. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/admin/actions.py +0 -0
  289. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/admin/model/__init__.py +0 -0
  290. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/admin/model/ajax.py +0 -0
  291. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/admin/row_action.py +0 -0
  292. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/admin/sqla/__init__.py +0 -0
  293. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/admin/sqla/filters.py +0 -0
  294. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/babel/__init__.py +0 -0
  295. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/babel/selector.py +0 -0
  296. {flask_exts-0.2.1/src/flask_exts/translations → flask_exts-0.2.3/src/flask_exts/datastore}/__init__.py +0 -0
  297. {flask_exts-0.2.1/tests/admin → flask_exts-0.2.3/src/flask_exts/datastore/sqla/models}/__init__.py +0 -0
  298. {flask_exts-0.2.1/tests/admin/sqla → flask_exts-0.2.3/src/flask_exts/email}/__init__.py +0 -0
  299. {flask_exts-0.2.1/tests/template → flask_exts-0.2.3/src/flask_exts/forms}/__init__.py +0 -0
  300. {flask_exts-0.2.1/tests/template/bootstrap4 → flask_exts-0.2.3/src/flask_exts/security/authorizer}/__init__.py +0 -0
  301. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/css/admin.css +0 -0
  302. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/css/rediscli.css +0 -0
  303. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/js/actions.js +0 -0
  304. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/js/details_filter.js +0 -0
  305. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/js/rediscli.js +0 -0
  306. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/logo.png +0 -0
  307. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/vendor/bootstrap-icons/bootstrap-icons.svg +0 -0
  308. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/vendor/bootstrap-icons/font/bootstrap-icons.css +0 -0
  309. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/vendor/bootstrap-icons/font/bootstrap-icons.json +0 -0
  310. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/vendor/bootstrap-icons/font/bootstrap-icons.min.css +0 -0
  311. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/vendor/bootstrap-icons/font/bootstrap-icons.scss +0 -0
  312. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/vendor/bootstrap-icons/font/fonts/bootstrap-icons.woff +0 -0
  313. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/vendor/bootstrap-icons/font/fonts/bootstrap-icons.woff2 +0 -0
  314. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/vendor/bootstrap4/bootstrap.bundle.min.js +0 -0
  315. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/vendor/bootstrap4/bootstrap.min.css +0 -0
  316. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/vendor/bootstrap5/bootstrap.bundle.min.js +0 -0
  317. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/vendor/bootstrap5/bootstrap.min.css +0 -0
  318. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/vendor/daterangepicker/daterangepicker.css +0 -0
  319. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/vendor/daterangepicker/daterangepicker.js +0 -0
  320. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/vendor/jquery/jquery.min.js +0 -0
  321. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/vendor/moment.min.js +0 -0
  322. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/vendor/select2/select2.min.css +0 -0
  323. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/static/vendor/select2/select2.min.js +0 -0
  324. {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
  325. {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
  326. {flask_exts-0.2.1/tests → flask_exts-0.2.3/src/flask_exts/template}/__init__.py +0 -0
  327. {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/fields/ajax_select.py +0 -0
  328. {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/fields/file.py +0 -0
  329. {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/fields/inline.py +0 -0
  330. {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/fields/json.py +0 -0
  331. {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/fields/recaptcha.py +0 -0
  332. {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/fields/select.py +0 -0
  333. {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/fields/switch.py +0 -0
  334. {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/fields/taglist.py +0 -0
  335. {flask_exts-0.2.1/tests/template/bootstrap5 → flask_exts-0.2.3/src/flask_exts/template/form}/__init__.py +0 -0
  336. {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/form/flask_form.py +0 -0
  337. {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/form/session_csrf.py +0 -0
  338. {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/rules.py +0 -0
  339. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/template/theme.py +0 -0
  340. {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/validators/__init__.py +0 -0
  341. {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/validators/field_list.py +0 -0
  342. {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/validators/file.py +0 -0
  343. {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/validators/recaptcha.py +0 -0
  344. {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/validators/sqla.py +0 -0
  345. {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/widgets/__init__.py +0 -0
  346. {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/widgets/checkbox.py +0 -0
  347. {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/widgets/datetime.py +0 -0
  348. {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/widgets/file.py +0 -0
  349. {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/widgets/inline.py +0 -0
  350. {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/widgets/recaptcha.py +0 -0
  351. {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/widgets/render_template.py +0 -0
  352. {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/widgets/select.py +0 -0
  353. {flask_exts-0.2.1/src/flask_exts/forms → flask_exts-0.2.3/src/flask_exts/template}/widgets/xeditable.py +0 -0
  354. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/admin/master.html +0 -0
  355. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/admin/model/create.html +0 -0
  356. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/admin/model/details.html +0 -0
  357. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/admin/model/edit.html +0 -0
  358. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/base.html +0 -0
  359. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/bootstrap4/form.html +0 -0
  360. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/bootstrap4/message.html +0 -0
  361. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/bootstrap4/pagination.html +0 -0
  362. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/bootstrap5/form.html +0 -0
  363. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/bootstrap5/message.html +0 -0
  364. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/layout.html +0 -0
  365. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/macro/form.html +0 -0
  366. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/macro/icon.html +0 -0
  367. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/macro/message.html +0 -0
  368. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/macro/nav.html +0 -0
  369. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/macro/pagination.html +0 -0
  370. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/macro/table.html +0 -0
  371. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/views/file/form.html +0 -0
  372. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/views/file/modals/form.html +0 -0
  373. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/views/rediscli/console.html +0 -0
  374. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/views/rediscli/response.html +0 -0
  375. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/views/user/index.html +0 -0
  376. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/views/user/list.html +0 -0
  377. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/views/user/login.html +0 -0
  378. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/views/user/register.html +0 -0
  379. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/widgets/inline_field_list.html +0 -0
  380. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/templates/widgets/inline_form.html +0 -0
  381. /flask_exts-0.2.1/src/flask_exts/utils/url.py → /flask_exts-0.2.3/src/flask_exts/translations/__init__.py +0 -0
  382. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/translations/en/LC_MESSAGES/messages.mo +0 -0
  383. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/translations/en/LC_MESSAGES/messages.po +0 -0
  384. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/translations/zh_CN/LC_MESSAGES/messages.mo +0 -0
  385. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/translations/zh_CN/LC_MESSAGES/messages.po +0 -0
  386. /flask_exts-0.2.1/tests/views/files/dummy.txt → /flask_exts-0.2.3/src/flask_exts/usercenter/__init__.py +0 -0
  387. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/utils/tools.py +0 -0
  388. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/views/file_view/__init__.py +0 -0
  389. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/views/file_view/local_file_storage.py +0 -0
  390. {flask_exts-0.2.1 → flask_exts-0.2.3}/src/flask_exts/views/file_view/local_file_view.py +0 -0
  391. {flask_exts-0.2.1/tests → flask_exts-0.2.3/tests/admin/customer}/templates/mock.html +0 -0
  392. {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/admin/sqla/templates/another_macro.html +0 -0
  393. {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/admin/sqla/templates/macro.html +0 -0
  394. {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/data/copyleft.gif +0 -0
  395. {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/data/copyleft.jpeg +0 -0
  396. {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/data/copyleft.jpg +0 -0
  397. {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/data/copyleft.png +0 -0
  398. {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/data/copyleft.tiff +0 -0
  399. /flask_exts-0.2.1/tests/funcs.py → /flask_exts-0.2.3/tests/helper.py +0 -0
  400. {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/templates/method.html +0 -0
  401. {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/translations/en/LC_MESSAGES/messages.mo +0 -0
  402. {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/translations/en/LC_MESSAGES/messages.po +0 -0
  403. {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/translations/zh_CN/LC_MESSAGES/messages.po +0 -0
  404. {flask_exts-0.2.1 → flask_exts-0.2.3}/tests/views/test_rediscli_view.py +0 -0
@@ -32,3 +32,6 @@ docs/_build/
32
32
 
33
33
  # sqlite db
34
34
  *.sqlite
35
+
36
+ # production config
37
+ **/config_prod.py
@@ -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.1
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
- - `WTForms <https://github.com/wtforms/wtforms/>`_
60
- - `Flask-Admin <https://github.com/flask-admin/flask-admin/>`_
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 part rewrited from above and well tested.
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
- - `WTForms <https://github.com/wtforms/wtforms/>`_
7
- - `Flask-Admin <https://github.com/flask-admin/flask-admin/>`_
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 part rewrited from above and well tested.
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
- ``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
- ``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 admin, SQLAlchemy, babel, forms, fields, widgets, and so on.
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 flask_sqlalchemy import SQLAlchemy
8
- from flask_exts.forms.form import FlaskForm
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.forms.form import FlaskForm
10
- from flask_exts.forms.fields import SwitchField
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):
@@ -1,5 +1,5 @@
1
1
  {% extends "mybase.html" %}
2
- {% from 'pagination4/pagination.html' import render_pager, render_pagination %}
2
+ {% from 'bootstrap4/pagination.html' import render_pager, render_pagination %}
3
3
 
4
4
  {% block content %}
5
5
  <h2>Messages</h2>
@@ -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 User
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 = User()
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
- from .user_center import UserCenter
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 init_db
38
-
39
- init_db(app)
35
+ from .models import init_models
40
36
 
41
- manager = Manager()
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)
@@ -0,0 +1,12 @@
1
+ from flask_exts.datastore.sqla import db
2
+
3
+
4
+ def init_models():
5
+ from . import user
6
+ from . import keyword
7
+ from . import user_keyword
8
+ from . import tag
9
+ from . import author
10
+ from . import post
11
+ from . import post_tag
12
+ from . import tree
@@ -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: Mapped[int] = mapped_column(ForeignKey("location.id"))
37
- location: Mapped["Location"] = relationship(backref='images')
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 User(db.Model, UserMixin):
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="user",
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
- user_id = mapped_column(ForeignKey("user.id"), primary_key=True)
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
- user: Mapped["User"] = relationship(back_populates="user_keyword_associations")
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, user=None, special_key=None):
24
- self.user = user
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 db
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, db.session)
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, db.session)
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.forms.widgets.render_template import RenderTemplateWidget
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.forms.fields.sqla import InlineModelFormList
11
- from ..models import db
12
- from ..models.model import ImageType, Location, LocationImage
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
- current_app.save_image(file_data, model.path)
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, db.session, name="Locations")
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, db.session)
93
+ postview = PostView(Post)
@@ -1,5 +1,4 @@
1
1
  from flask_exts.admin.sqla import ModelView
2
2
  from ..models.tag import Tag
3
- from ..models import db
4
3
 
5
- tagview = ModelView(Tag, db.session)
4
+ tagview = ModelView(Tag)
@@ -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 = 'tree_list.html'
6
+ list_template = "tree_list.html"
7
7
  column_auto_select_related = True
8
8
  column_list = [
9
- 'id',
10
- 'name',
11
- 'parent',
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
- treeview = TreeView(Tree, db.session, category="tree")
26
+
27
+ treeview = TreeView(Tree)