accrete 0.0.99__py3-none-any.whl → 0.0.109__py3-none-any.whl

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 (254) hide show
  1. accrete/contrib/ui/__init__.py +6 -27
  2. accrete/contrib/ui/context.py +26 -294
  3. accrete/contrib/ui/filter.py +309 -280
  4. accrete/contrib/ui/middleware.py +44 -0
  5. accrete/contrib/ui/models.py +3 -0
  6. accrete/contrib/ui/static/bulma/README.md +4 -2
  7. accrete/contrib/ui/static/bulma/bulma.css +21551 -0
  8. accrete/contrib/ui/static/bulma/bulma.css.map +1 -0
  9. accrete/contrib/ui/static/bulma/bulma.scss +1 -1
  10. accrete/contrib/ui/static/bulma/css/bulma.css +1988 -2874
  11. accrete/contrib/ui/static/bulma/css/bulma.css.map +1 -1
  12. accrete/contrib/ui/static/bulma/css/bulma.min.css +2 -2
  13. accrete/contrib/ui/static/bulma/css/versions/bulma-no-dark-mode.css +19648 -0
  14. accrete/contrib/ui/static/bulma/css/versions/bulma-no-dark-mode.css.map +1 -0
  15. accrete/contrib/ui/static/bulma/css/versions/bulma-no-dark-mode.min.css +2 -2
  16. accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers-prefixed.css +11136 -0
  17. accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers-prefixed.css.map +1 -0
  18. accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers-prefixed.min.css +2 -2
  19. accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers.css +11136 -0
  20. accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers.css.map +1 -0
  21. accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers.min.css +2 -2
  22. accrete/contrib/ui/static/bulma/css/versions/bulma-prefixed.min.css +21550 -2
  23. accrete/contrib/ui/static/bulma/css/versions/bulma-prefixed.min.css.map +1 -1
  24. accrete/contrib/ui/static/bulma/css/versions/bulma-prefixed.min.min.css +3 -0
  25. accrete/contrib/ui/static/bulma/package.json +12 -11
  26. accrete/contrib/ui/static/bulma/sass/base/animations.css +15 -0
  27. accrete/contrib/ui/static/bulma/sass/base/animations.css.map +1 -0
  28. accrete/contrib/ui/static/bulma/sass/base/generic.css +196 -0
  29. accrete/contrib/ui/static/bulma/sass/base/generic.css.map +1 -0
  30. accrete/contrib/ui/static/bulma/sass/base/minireset.css +82 -0
  31. accrete/contrib/ui/static/bulma/sass/base/minireset.css.map +1 -0
  32. accrete/contrib/ui/static/bulma/sass/base/skeleton.css +113 -0
  33. accrete/contrib/ui/static/bulma/sass/base/skeleton.css.map +1 -0
  34. accrete/contrib/ui/static/bulma/sass/base/skeleton.scss +0 -12
  35. accrete/contrib/ui/static/bulma/sass/components/breadcrumb.css +108 -0
  36. accrete/contrib/ui/static/bulma/sass/components/breadcrumb.css.map +1 -0
  37. accrete/contrib/ui/static/bulma/sass/components/card.css +130 -0
  38. accrete/contrib/ui/static/bulma/sass/components/card.css.map +1 -0
  39. accrete/contrib/ui/static/bulma/sass/components/dropdown.css +119 -0
  40. accrete/contrib/ui/static/bulma/sass/components/dropdown.css.map +1 -0
  41. accrete/contrib/ui/static/bulma/sass/components/menu.css +119 -0
  42. accrete/contrib/ui/static/bulma/sass/components/menu.css.map +1 -0
  43. accrete/contrib/ui/static/bulma/sass/components/message.css +191 -0
  44. accrete/contrib/ui/static/bulma/sass/components/message.css.map +1 -0
  45. accrete/contrib/ui/static/bulma/sass/components/modal.css +194 -0
  46. accrete/contrib/ui/static/bulma/sass/components/modal.css.map +1 -0
  47. accrete/contrib/ui/static/bulma/sass/components/navbar.css +768 -0
  48. accrete/contrib/ui/static/bulma/sass/components/navbar.css.map +1 -0
  49. accrete/contrib/ui/static/bulma/sass/components/navbar.scss +41 -30
  50. accrete/contrib/ui/static/bulma/sass/components/pagination.css +302 -0
  51. accrete/contrib/ui/static/bulma/sass/components/pagination.css.map +1 -0
  52. accrete/contrib/ui/static/bulma/sass/components/panel.css +224 -0
  53. accrete/contrib/ui/static/bulma/sass/components/panel.css.map +1 -0
  54. accrete/contrib/ui/static/bulma/sass/components/panel.scss +2 -2
  55. accrete/contrib/ui/static/bulma/sass/components/tabs.css +192 -0
  56. accrete/contrib/ui/static/bulma/sass/components/tabs.css.map +1 -0
  57. accrete/contrib/ui/static/bulma/sass/elements/block.css +17 -0
  58. accrete/contrib/ui/static/bulma/sass/elements/block.css.map +1 -0
  59. accrete/contrib/ui/static/bulma/sass/elements/box.css +43 -0
  60. accrete/contrib/ui/static/bulma/sass/elements/box.css.map +1 -0
  61. accrete/contrib/ui/static/bulma/sass/elements/button.css +685 -0
  62. accrete/contrib/ui/static/bulma/sass/elements/button.css.map +1 -0
  63. accrete/contrib/ui/static/bulma/sass/elements/button.scss +9 -2
  64. accrete/contrib/ui/static/bulma/sass/elements/content.css +208 -0
  65. accrete/contrib/ui/static/bulma/sass/elements/content.css.map +1 -0
  66. accrete/contrib/ui/static/bulma/sass/elements/content.scss +8 -2
  67. accrete/contrib/ui/static/bulma/sass/elements/delete.css +60 -0
  68. accrete/contrib/ui/static/bulma/sass/elements/delete.css.map +1 -0
  69. accrete/contrib/ui/static/bulma/sass/elements/icon.css +51 -0
  70. accrete/contrib/ui/static/bulma/sass/elements/icon.css.map +1 -0
  71. accrete/contrib/ui/static/bulma/sass/elements/image.css +253 -0
  72. accrete/contrib/ui/static/bulma/sass/elements/image.css.map +1 -0
  73. accrete/contrib/ui/static/bulma/sass/elements/loader.css +14 -0
  74. accrete/contrib/ui/static/bulma/sass/elements/loader.css.map +1 -0
  75. accrete/contrib/ui/static/bulma/sass/elements/notification.css +213 -0
  76. accrete/contrib/ui/static/bulma/sass/elements/notification.css.map +1 -0
  77. accrete/contrib/ui/static/bulma/sass/elements/progress.css +119 -0
  78. accrete/contrib/ui/static/bulma/sass/elements/progress.css.map +1 -0
  79. accrete/contrib/ui/static/bulma/sass/elements/table.css +294 -0
  80. accrete/contrib/ui/static/bulma/sass/elements/table.css.map +1 -0
  81. accrete/contrib/ui/static/bulma/sass/elements/tag.css +252 -0
  82. accrete/contrib/ui/static/bulma/sass/elements/tag.css.map +1 -0
  83. accrete/contrib/ui/static/bulma/sass/elements/title.css +131 -0
  84. accrete/contrib/ui/static/bulma/sass/elements/title.css.map +1 -0
  85. accrete/contrib/ui/static/bulma/sass/form/checkbox-radio.css +72 -0
  86. accrete/contrib/ui/static/bulma/sass/form/checkbox-radio.css.map +1 -0
  87. accrete/contrib/ui/static/bulma/sass/form/checkbox-radio.scss +7 -3
  88. accrete/contrib/ui/static/bulma/sass/form/file.css +374 -0
  89. accrete/contrib/ui/static/bulma/sass/form/file.css.map +1 -0
  90. accrete/contrib/ui/static/bulma/sass/form/input-textarea.css +284 -0
  91. accrete/contrib/ui/static/bulma/sass/form/input-textarea.css.map +1 -0
  92. accrete/contrib/ui/static/bulma/sass/form/input-textarea.scss +0 -10
  93. accrete/contrib/ui/static/bulma/sass/form/select.css +347 -0
  94. accrete/contrib/ui/static/bulma/sass/form/select.css.map +1 -0
  95. accrete/contrib/ui/static/bulma/sass/form/select.scss +1 -0
  96. accrete/contrib/ui/static/bulma/sass/form/shared.css +48 -0
  97. accrete/contrib/ui/static/bulma/sass/form/shared.css.map +1 -0
  98. accrete/contrib/ui/static/bulma/sass/form/shared.scss +5 -1
  99. accrete/contrib/ui/static/bulma/sass/form/tools.css +356 -0
  100. accrete/contrib/ui/static/bulma/sass/form/tools.css.map +1 -0
  101. accrete/contrib/ui/static/bulma/sass/form/tools.scss +23 -12
  102. accrete/contrib/ui/static/bulma/sass/grid/columns-v2.css +1635 -0
  103. accrete/contrib/ui/static/bulma/sass/grid/columns-v2.css.map +1 -0
  104. accrete/contrib/ui/static/bulma/sass/grid/columns.css +1652 -0
  105. accrete/contrib/ui/static/bulma/sass/grid/columns.css.map +1 -0
  106. accrete/contrib/ui/static/bulma/sass/grid/columns.scss +109 -25
  107. accrete/contrib/ui/static/bulma/sass/grid/grid.css +3011 -0
  108. accrete/contrib/ui/static/bulma/sass/grid/grid.css.map +1 -0
  109. accrete/contrib/ui/static/bulma/sass/grid/grid.scss +3 -3
  110. accrete/contrib/ui/static/bulma/sass/helpers/aspect-ratio.css +61 -0
  111. accrete/contrib/ui/static/bulma/sass/helpers/aspect-ratio.css.map +1 -0
  112. accrete/contrib/ui/static/bulma/sass/helpers/border.css +17 -0
  113. accrete/contrib/ui/static/bulma/sass/helpers/border.css.map +1 -0
  114. accrete/contrib/ui/static/bulma/sass/helpers/color.css +5582 -0
  115. accrete/contrib/ui/static/bulma/sass/helpers/color.css.map +1 -0
  116. accrete/contrib/ui/static/bulma/sass/helpers/color.scss +166 -186
  117. accrete/contrib/ui/static/bulma/sass/helpers/flexbox.css +217 -0
  118. accrete/contrib/ui/static/bulma/sass/helpers/flexbox.css.map +1 -0
  119. accrete/contrib/ui/static/bulma/sass/helpers/float.css +37 -0
  120. accrete/contrib/ui/static/bulma/sass/helpers/float.css.map +1 -0
  121. accrete/contrib/ui/static/bulma/sass/helpers/gap.css +209 -0
  122. accrete/contrib/ui/static/bulma/sass/helpers/gap.css.map +1 -0
  123. accrete/contrib/ui/static/bulma/sass/helpers/other.css +34 -0
  124. accrete/contrib/ui/static/bulma/sass/helpers/other.css.map +1 -0
  125. accrete/contrib/ui/static/bulma/sass/helpers/overflow.css +65 -0
  126. accrete/contrib/ui/static/bulma/sass/helpers/overflow.css.map +1 -0
  127. accrete/contrib/ui/static/bulma/sass/helpers/position.css +45 -0
  128. accrete/contrib/ui/static/bulma/sass/helpers/position.css.map +1 -0
  129. accrete/contrib/ui/static/bulma/sass/helpers/spacing.css +489 -0
  130. accrete/contrib/ui/static/bulma/sass/helpers/spacing.css.map +1 -0
  131. accrete/contrib/ui/static/bulma/sass/helpers/typography.css +423 -0
  132. accrete/contrib/ui/static/bulma/sass/helpers/typography.css.map +1 -0
  133. accrete/contrib/ui/static/bulma/sass/helpers/visibility.css +485 -0
  134. accrete/contrib/ui/static/bulma/sass/helpers/visibility.css.map +1 -0
  135. accrete/contrib/ui/static/bulma/sass/layout/container.scss +16 -8
  136. accrete/contrib/ui/static/bulma/sass/layout/footer.css +9 -0
  137. accrete/contrib/ui/static/bulma/sass/layout/footer.css.map +1 -0
  138. accrete/contrib/ui/static/bulma/sass/layout/hero.css +534 -0
  139. accrete/contrib/ui/static/bulma/sass/layout/hero.css.map +1 -0
  140. accrete/contrib/ui/static/bulma/sass/layout/level.css +102 -0
  141. accrete/contrib/ui/static/bulma/sass/layout/level.css.map +1 -0
  142. accrete/contrib/ui/static/bulma/sass/layout/media.css +90 -0
  143. accrete/contrib/ui/static/bulma/sass/layout/media.css.map +1 -0
  144. accrete/contrib/ui/static/bulma/sass/layout/section.css +23 -0
  145. accrete/contrib/ui/static/bulma/sass/layout/section.css.map +1 -0
  146. accrete/contrib/ui/static/bulma/sass/layout/section.scss +4 -0
  147. accrete/contrib/ui/static/bulma/sass/themes/dark.css +3 -0
  148. accrete/contrib/ui/static/bulma/sass/themes/dark.css.map +1 -0
  149. accrete/contrib/ui/static/bulma/sass/themes/light.css +3 -0
  150. accrete/contrib/ui/static/bulma/sass/themes/light.css.map +1 -0
  151. accrete/contrib/ui/static/bulma/sass/themes/light.scss +1 -0
  152. accrete/contrib/ui/static/bulma/sass/themes/setup.css +3 -0
  153. accrete/contrib/ui/static/bulma/sass/themes/setup.css.map +1 -0
  154. accrete/contrib/ui/static/bulma/sass/utilities/controls.css +13 -0
  155. accrete/contrib/ui/static/bulma/sass/utilities/controls.css.map +1 -0
  156. accrete/contrib/ui/static/bulma/sass/utilities/css-variables.css +3 -0
  157. accrete/contrib/ui/static/bulma/sass/utilities/css-variables.css.map +1 -0
  158. accrete/contrib/ui/static/bulma/sass/utilities/css-variables.scss +3 -2
  159. accrete/contrib/ui/static/bulma/sass/utilities/derived-variables.css +3 -0
  160. accrete/contrib/ui/static/bulma/sass/utilities/derived-variables.css.map +1 -0
  161. accrete/contrib/ui/static/bulma/sass/utilities/extends.css +13 -0
  162. accrete/contrib/ui/static/bulma/sass/utilities/extends.css.map +1 -0
  163. accrete/contrib/ui/static/bulma/sass/utilities/functions.scss +2 -2
  164. accrete/contrib/ui/static/bulma/sass/utilities/initial-variables.css +3 -0
  165. accrete/contrib/ui/static/bulma/sass/utilities/initial-variables.css.map +1 -0
  166. accrete/contrib/ui/static/bulma/sass/utilities/initial-variables.scss +4 -4
  167. accrete/contrib/ui/static/bulma/sass/utilities/mixins.css +3 -0
  168. accrete/contrib/ui/static/bulma/sass/utilities/mixins.css.map +1 -0
  169. accrete/contrib/ui/static/bulma/sass/utilities/mixins.scss +1 -1
  170. accrete/contrib/ui/static/bulma/versions/bulma-no-dark-mode.css +19648 -0
  171. accrete/contrib/ui/static/bulma/versions/bulma-no-dark-mode.css.map +1 -0
  172. accrete/contrib/ui/static/bulma/versions/bulma-no-dark-mode.scss +2 -1
  173. accrete/contrib/ui/static/bulma/versions/bulma-no-helpers-prefixed.css +11136 -0
  174. accrete/contrib/ui/static/bulma/versions/bulma-no-helpers-prefixed.css.map +1 -0
  175. accrete/contrib/ui/static/bulma/versions/bulma-no-helpers-prefixed.scss +1 -1
  176. accrete/contrib/ui/static/bulma/versions/bulma-no-helpers.css +11136 -0
  177. accrete/contrib/ui/static/bulma/versions/bulma-no-helpers.css.map +1 -0
  178. accrete/contrib/ui/static/bulma/versions/bulma-no-helpers.scss +1 -1
  179. accrete/contrib/ui/static/bulma/versions/bulma-prefixed.css +21551 -0
  180. accrete/contrib/ui/static/bulma/versions/bulma-prefixed.css.map +1 -0
  181. accrete/contrib/ui/static/bulma/versions/bulma-prefixed.scss +1 -1
  182. accrete/contrib/ui/static/css/accrete.css +20757 -19996
  183. accrete/contrib/ui/static/css/accrete.css.map +1 -1
  184. accrete/contrib/ui/static/css/accrete.scss +185 -461
  185. accrete/contrib/ui/static/js/filter.js +98 -679
  186. accrete/contrib/ui/static/js/htmx.min.js +1 -1
  187. accrete/contrib/ui/templates/django/forms/widgets/date.html +5 -0
  188. accrete/contrib/ui/templates/django/forms/widgets/input.html +1 -1
  189. accrete/contrib/ui/templates/django/forms/widgets/select.html +7 -5
  190. accrete/contrib/ui/templates/ui/content_right.html +7 -0
  191. accrete/contrib/ui/templates/ui/filter/filter.html +27 -0
  192. accrete/contrib/ui/templates/ui/filter/query_input.html +31 -0
  193. accrete/contrib/ui/templates/ui/filter/query_operator.html +11 -0
  194. accrete/contrib/ui/templates/ui/filter/query_params.html +106 -0
  195. accrete/contrib/ui/templates/ui/filter/query_tags.html +26 -0
  196. accrete/contrib/ui/templates/ui/layout.html +175 -232
  197. accrete/contrib/ui/templates/ui/list.html +39 -28
  198. accrete/contrib/ui/templates/ui/list_update.html +3 -0
  199. accrete/contrib/ui/templates/ui/message.html +13 -0
  200. accrete/contrib/ui/templates/ui/{partials/modal.html → modal.html} +9 -5
  201. accrete/contrib/ui/templates/ui/oob.html +3 -0
  202. accrete/contrib/ui/templates/ui/table.html +67 -71
  203. accrete/contrib/ui/templates/ui/table_row_update.html +14 -0
  204. accrete/contrib/ui/templates/ui/widgets/model_search_select.html +42 -0
  205. accrete/contrib/ui/templates/ui/widgets/model_search_select_multi.html +78 -0
  206. accrete/contrib/ui/templates/ui/widgets/model_search_select_options.html +3 -0
  207. accrete/contrib/ui/templatetags/{accrete_ui.py → ui.py} +69 -57
  208. accrete/contrib/ui/urls.py +3 -1
  209. accrete/contrib/ui/views.py +33 -3
  210. accrete/contrib/ui/widgets/__init__.py +1 -0
  211. accrete/contrib/ui/widgets/search_select.py +106 -0
  212. accrete/contrib/user/forms.py +1 -1
  213. accrete/contrib/user/templates/user/change_email.html +22 -27
  214. accrete/contrib/user/templates/user/change_password.html +24 -36
  215. accrete/contrib/user/templates/user/login.html +72 -23
  216. accrete/contrib/user/templates/user/user_form.html +50 -52
  217. accrete/contrib/user/urls.py +2 -3
  218. accrete/contrib/user/views.py +39 -46
  219. accrete/forms.py +0 -2
  220. accrete/managers.py +4 -4
  221. accrete/middleware.py +43 -68
  222. accrete/models.py +7 -1
  223. accrete/storage.py +4 -1
  224. accrete/tenant.py +11 -5
  225. accrete/utils/__init__.py +2 -0
  226. accrete/utils/models.py +9 -1
  227. accrete/utils/views.py +36 -20
  228. accrete/views.py +9 -5
  229. {accrete-0.0.99.dist-info → accrete-0.0.109.dist-info}/METADATA +2 -2
  230. accrete-0.0.109.dist-info/RECORD +369 -0
  231. {accrete-0.0.99.dist-info → accrete-0.0.109.dist-info}/WHEEL +1 -1
  232. accrete/contrib/ui/elements.py +0 -93
  233. accrete/contrib/ui/static/bulma/css/versions/bulma-no-dark-mode.min.css.map +0 -1
  234. accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers-prefixed.min.css.map +0 -1
  235. accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers.min.css.map +0 -1
  236. accrete/contrib/ui/static/bulma/sass/grid/columns-v2.scss +0 -957
  237. accrete/contrib/ui/static/js/ui.js +0 -30
  238. accrete/contrib/ui/templates/ui/dashboard.html +0 -7
  239. accrete/contrib/ui/templates/ui/detail.html +0 -19
  240. accrete/contrib/ui/templates/ui/form.html +0 -21
  241. accrete/contrib/ui/templates/ui/partials/filter.html +0 -143
  242. accrete/contrib/ui/templates/ui/partials/form_errors.html +0 -34
  243. accrete/contrib/ui/templates/ui/partials/header.html +0 -123
  244. accrete/contrib/ui/templates/ui/partials/modal_form.html +0 -45
  245. accrete/contrib/ui/templates/ui/partials/onchange_form.html +0 -1
  246. accrete/contrib/ui/templates/ui/partials/pagination_detail.html +0 -23
  247. accrete/contrib/ui/templates/ui/partials/pagination_list.html +0 -28
  248. accrete/contrib/ui/templates/ui/partials/table_field.html +0 -16
  249. accrete/contrib/ui/templates/ui/partials/table_field_float.html +0 -1
  250. accrete/contrib/ui/templates/ui/partials/table_field_monetary.html +0 -4
  251. accrete/contrib/ui/templates/ui/partials/table_field_string.html +0 -1
  252. accrete/contrib/user/templates/user/user_detail.html +0 -43
  253. accrete-0.0.99.dist-info/RECORD +0 -231
  254. {accrete-0.0.99.dist-info → accrete-0.0.109.dist-info}/licenses/LICENSE +0 -0
accrete/models.py CHANGED
@@ -14,6 +14,7 @@ class TenantModel(models.Model, AnnotationModelMixin):
14
14
  abstract = True
15
15
 
16
16
  tenant = models.ForeignKey(
17
+ verbose_name=_('Tenant'),
17
18
  to='accrete.Tenant',
18
19
  on_delete=models.CASCADE
19
20
  )
@@ -34,7 +35,8 @@ class TenantModel(models.Model, AnnotationModelMixin):
34
35
  if self.pk and not self.tenant and not tenant:
35
36
  raise ValueError(
36
37
  'Tenant not provided! '
37
- 'Use accrete.tenant.set_tenant() or set the tenant explicitly on the instance.'
38
+ 'Use accrete.tenant.set_tenant() '
39
+ 'or set the tenant explicitly on the instance.'
38
40
  )
39
41
  if tenant:
40
42
  self.tenant = tenant
@@ -45,6 +47,10 @@ class TenantModel(models.Model, AnnotationModelMixin):
45
47
  update_fields=update_fields
46
48
  )
47
49
 
50
+ @staticmethod
51
+ def exclude_from_filter():
52
+ return ['tenant']
53
+
48
54
 
49
55
  class Tenant(models.Model):
50
56
 
accrete/storage.py CHANGED
@@ -25,7 +25,10 @@ class TenantFileSystemStorage(FileSystemStorage):
25
25
  def base_url(self):
26
26
  if self._base_url is not None and not self._base_url.endswith("/"):
27
27
  self._base_url += "/"
28
- res = self._value_or_setting(self._base_url, f'{settings.MEDIA_URL.strip("/")}/{get_tenant().id}')
28
+ res = self._value_or_setting(
29
+ self._base_url,
30
+ f'{settings.MEDIA_URL.strip("/")}/{get_tenant().id}'
31
+ )
29
32
  return res
30
33
 
31
34
  def url(self, name):
accrete/tenant.py CHANGED
@@ -2,7 +2,7 @@ import contextvars
2
2
  import logging
3
3
  import time
4
4
  from django.apps import apps
5
- from django.db.models import Q
5
+ from django.db.models import Q, QuerySet
6
6
 
7
7
  _logger = logging.getLogger(__name__)
8
8
 
@@ -19,7 +19,12 @@ def get_tenant():
19
19
 
20
20
 
21
21
  def set_member(member):
22
- tenant = member.tenant if member is not None else None
22
+ if member is False:
23
+ tenant = False
24
+ elif member is None:
25
+ tenant = None
26
+ else:
27
+ tenant = member.tenant
23
28
  member_contextvar.set(member)
24
29
  tenant_contextvar.set(tenant)
25
30
 
@@ -36,9 +41,10 @@ class Unscoped:
36
41
  def __enter__(self):
37
42
  if self.tenant is None:
38
43
  _logger.warning(
39
- 'Entering unscoped context manager with tenant already set to None!'
44
+ 'Entering unscoped context manager with tenant already set to None!',
45
+ stack_info=True
40
46
  )
41
- set_tenant(None)
47
+ set_tenant(False)
42
48
 
43
49
  def __exit__(self, exc_type, exc_val, exc_tb):
44
50
  set_tenant(self.tenant)
@@ -51,7 +57,7 @@ def unscoped():
51
57
  def per_tenant(include: Q = None, exclude: Q = None):
52
58
  def decorator(f):
53
59
  def wrapper(*args, **kwargs):
54
- tenants = apps.get_model('accrete', 'Tenant').objects.all()
60
+ tenants: QuerySet = apps.get_model('accrete', 'Tenant').objects.all()
55
61
  if include is not None:
56
62
  tenants = tenants.filter(include)
57
63
  if exclude is not None:
accrete/utils/__init__.py CHANGED
@@ -6,6 +6,8 @@ from .forms import (
6
6
  extend_formset
7
7
  )
8
8
  from .views import (
9
+ page_from_querystring,
10
+ get_page,
9
11
  filter_from_querystring,
10
12
  cast_param,
11
13
  method_not_allowed,
accrete/utils/models.py CHANGED
@@ -1,4 +1,4 @@
1
- from django.db.models import Model
1
+ from django.db.models import Model, Field
2
2
 
3
3
 
4
4
  def get_related_model(model: type[Model], rel_path: str) -> tuple[Model, list[str]]:
@@ -16,4 +16,12 @@ def get_related_model(model: type[Model], rel_path: str) -> tuple[Model, list[st
16
16
  related_model = next_model
17
17
  except AttributeError:
18
18
  break
19
+ names.append(str(related_model._meta.verbose_name))
19
20
  return related_model, names
21
+
22
+
23
+ def get_related_field(model: type[Model], field_path: str) -> Field:
24
+ parts = field_path.split('__')
25
+ rel_path = '__'.join(parts[:-1])
26
+ rel_model, _ = get_related_model(model, rel_path)
27
+ return rel_model._meta.get_field(parts[-1])
accrete/utils/views.py CHANGED
@@ -2,11 +2,12 @@ import logging
2
2
  import json
3
3
  import operator
4
4
  from typing import Callable
5
+
6
+ from django.core import paginator
5
7
  from django.db.models import Model, Q, QuerySet
6
8
  from django.template.loader import render_to_string, TemplateDoesNotExist
7
9
  from django.http import HttpResponseNotAllowed
8
10
  from accrete.utils.models import get_related_model
9
- from accrete.annotation import Annotation
10
11
 
11
12
  _logger = logging.getLogger(__name__)
12
13
 
@@ -18,13 +19,40 @@ QUERYSTRING_KEY_MAP = {
18
19
  }
19
20
 
20
21
 
22
+ def page_from_querystring(
23
+ model: type[Model], query_dict: dict, key_map: dict = None,
24
+ select_related: list = None, prefetch_related: list = None
25
+ ) -> paginator.Page:
26
+
27
+ key_map = key_map or QUERYSTRING_KEY_MAP
28
+ queryset = filter_from_querystring(
29
+ model, query_dict, key_map
30
+ ).select_related(
31
+ *select_related or []
32
+ ).prefetch_related(
33
+ *prefetch_related or []
34
+ )
35
+ return get_page(
36
+ queryset,
37
+ cast_param(query_dict, key_map.get('paginate_by'), int, 40),
38
+ cast_param(query_dict, key_map.get('page'), int, 1)
39
+ )
40
+
41
+
42
+ def get_page(queryset: QuerySet, paginate_by: int, page_number: int) -> paginator.Page:
43
+ pages = paginator.Paginator(queryset, per_page=paginate_by)
44
+ return pages.page(
45
+ page_number <= pages.num_pages and page_number or pages.num_pages
46
+ )
47
+
48
+
21
49
  def filter_from_querystring(
22
- model: type[Model], get_params: dict, key_map: dict = None
50
+ model: type[Model], query_dict: dict, key_map: dict = None
23
51
  ) -> QuerySet:
24
52
 
25
53
  key_map = key_map or QUERYSTRING_KEY_MAP
26
- querystring = get_params.get(key_map['querystring'], '[]')
27
- order = get_params.get(key_map['order']) or model._meta.ordering
54
+ querystring = query_dict.get(key_map['querystring'], '[]')
55
+ order = query_dict.get(key_map['order']) or model._meta.ordering
28
56
 
29
57
  return model.objects.filter(
30
58
  parse_querystring(model, querystring)
@@ -34,7 +62,7 @@ def filter_from_querystring(
34
62
  def parse_querystring(model: type[Model], query_string: str) -> Q:
35
63
  """
36
64
  param: query_string: JSON serializable string
37
- [{term: value}, '&', [{term: value}, '|', {~term: value}]]
65
+ [{"term": value}, "&", [{t"erm": value}, "|", {"~term": value}]]
38
66
  Q(term=value) & (Q(term=value) | ~Q(term=value))
39
67
  """
40
68
 
@@ -51,19 +79,7 @@ def parse_querystring(model: type[Model], query_string: str) -> Q:
51
79
 
52
80
  rel_path = '__'.join(parts[:-2])
53
81
  related_model, x = get_related_model(model, rel_path)
54
- attr = getattr(related_model, parts[-2])
55
- if not isinstance(attr, Annotation):
56
- expression = Q(**{term: value})
57
- return ~expression if invert else expression
58
-
59
- objects = related_model.objects.filter(Q(**{
60
- '__'.join(parts[-2:]): value
61
- }))
62
- expression = Q(**{
63
- f'{rel_path}{"__" if rel_path else ""}id__in':
64
- objects.values_list('id', flat=True)
65
- })
66
-
82
+ expression = Q(**{term: value})
67
83
  return ~expression if invert else expression
68
84
 
69
85
  def parse_query_block(sub_item) -> Q:
@@ -85,7 +101,6 @@ def parse_querystring(model: type[Model], query_string: str) -> Q:
85
101
  f'Operator must be one of &, |, ^'
86
102
  )
87
103
  op = ops[item]
88
-
89
104
  else:
90
105
  raise ValueError(
91
106
  f'Unsupported item in querystring: {item}.'
@@ -120,6 +135,7 @@ def method_not_allowed(method: str, allowed: list[str]) -> HttpResponseNotAllowe
120
135
  def render_templates(
121
136
  templates: list[str | tuple[str, dict]],
122
137
  context: dict = None,
138
+ request=None,
123
139
  log_not_found: bool = False
124
140
  ) -> str:
125
141
  context = {} if context is None else context
@@ -131,7 +147,7 @@ def render_templates(
131
147
  template_name = template
132
148
  template_context = context
133
149
  try:
134
- content += render_to_string(template_name, template_context)
150
+ content += render_to_string(template_name, template_context, request)
135
151
  except TemplateDoesNotExist as e:
136
152
  if log_not_found:
137
153
  _logger.warning(repr(e))
accrete/views.py CHANGED
@@ -4,9 +4,9 @@ from django.http import HttpResponse, HttpResponseNotFound
4
4
  from django.contrib.auth.mixins import LoginRequiredMixin
5
5
  from django.contrib.auth.views import login_required
6
6
  from django.core.exceptions import ImproperlyConfigured
7
- from django.shortcuts import redirect
7
+ from django.shortcuts import redirect, get_object_or_404
8
8
  from django.conf import settings
9
- from accrete.tenant import get_tenant
9
+ from accrete.models import Tenant, Member
10
10
  from . import config
11
11
 
12
12
 
@@ -80,6 +80,8 @@ def tenant_required(
80
80
  tenant = request.tenant
81
81
  if not tenant:
82
82
  return redirect(config.ACCRETE_TENANT_NOT_SET_URL)
83
+ if kwargs.get('tenant'):
84
+ kwargs.pop('tenant')
83
85
  return f(request, *args, **kwargs)
84
86
  return _wrapped_view
85
87
  return decorator
@@ -87,9 +89,11 @@ def tenant_required(
87
89
 
88
90
  @tenant_required()
89
91
  def get_tenant_file(request, tenant_id, filepath):
90
- tenant = get_tenant()
91
- if tenant.id != tenant_id:
92
- return HttpResponseNotFound()
92
+ tenant = get_object_or_404(Tenant, pk=tenant_id)
93
+ if not request.user.is_staff:
94
+ member = Member.objects.filter(user=request.user, tenant=tenant)
95
+ if not member.exists():
96
+ return HttpResponseNotFound()
93
97
  filepath = f'{settings.MEDIA_ROOT}/{tenant_id}/{filepath}'
94
98
  if not os.path.exists(filepath):
95
99
  return HttpResponseNotFound()
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: accrete
3
- Version: 0.0.99
3
+ Version: 0.0.109
4
4
  Summary: Django Shared Schema Multi Tenant
5
5
  Author-email: Benedikt Jilek <benedikt.jilek@pm.me>
6
6
  License: Copyright (c) 2023 Benedikt Jilek