accrete 0.0.142__py3-none-any.whl → 0.0.143__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.
@@ -13,5 +13,6 @@ from . context import (
13
13
  from .utils import (
14
14
  modal_response,
15
15
  detail_response,
16
+ search_select_response,
16
17
  add_trigger
17
18
  )
@@ -5,7 +5,7 @@
5
5
  {{ form.non_field_errors }}
6
6
  {% if form.save_error %}
7
7
  <p>{{ form.save_error }}</p>
8
- <span>{% translate 'Error ID' %}: {{ form.save_error_id }}</span>
8
+ {% if form.save_error_id %}<span>{% translate 'Error ID' %}: {{ form.save_error_id }}</span>{% endif %}
9
9
  {% endif %}
10
10
  </div>
11
11
  {% endif %}
@@ -4,7 +4,7 @@
4
4
  {% for message in messages %}
5
5
  <div hx-swap-oob="{% if append %}beforeend:#message{% else %}innerHTML:#message{% endif %}">
6
6
  <div class="mb-2" style="min-width: 340px; max-width: 340px" x-data="{ show: false }" x-show="show" x-cloak="" x-init="show = true; {% if not persistent %}setTimeout(() => show = false, 4000){% endif %}" x-transition.duration.200ms>
7
- <div class="notification has-text-centered {{ message|message_class }}">
7
+ <div class="notification has-text-centered {{ message|message_class }}" style="box-shadow: 2px 2px 5px">
8
8
  {% if persistent %}<button class="delete" x-on:click="show = false;"></button>{% endif %}
9
9
  {{ message }}
10
10
  </div>
@@ -3,6 +3,7 @@ import json
3
3
 
4
4
  from django.http import HttpRequest, HttpResponse
5
5
  from django.shortcuts import render
6
+ from django.template.loader import render_to_string
6
7
 
7
8
  from . import OobContext
8
9
  from .context import BaseContext, ModalContext
@@ -30,26 +31,29 @@ def modal_response(
30
31
 
31
32
  def detail_response(
32
33
  request: HttpRequest,
33
- header_template: str,
34
- content_template: str,
35
- context: BaseContext | dict,
34
+ header_template: str = None,
35
+ content_template: str = None,
36
+ context: BaseContext | dict = None,
36
37
  extra_content: str | None = None
37
38
  ) -> HttpResponse:
38
39
  if isinstance(context, BaseContext):
39
40
  context = context.dict()
40
- content = render_templates([
41
- ('ui/message.html', context),
42
- ('ui/oob.html', OobContext(
41
+ templates = [
42
+ ('ui/message.html', context)
43
+ ]
44
+ if header_template:
45
+ templates.append(('ui/oob.html', OobContext(
43
46
  template=header_template,
44
47
  swap='innerHTML:#content-right-header',
45
48
  extra=context
46
- ).dict()),
47
- ('ui/oob.html', OobContext(
49
+ ).dict()))
50
+ if content_template:
51
+ templates.append(('ui/oob.html', OobContext(
48
52
  template=content_template,
49
53
  swap='innerHTML:#content-right',
50
54
  extra=context
51
- ).dict())
52
- ], request=request)
55
+ ).dict()))
56
+ content = render_templates(templates, request=request)
53
57
  if extra_content:
54
58
  content += extra_content
55
59
  res = HttpResponse(content=content)
@@ -57,8 +61,15 @@ def detail_response(
57
61
  return res
58
62
 
59
63
 
64
+ def search_select_response(queryset) -> HttpResponse:
65
+ return HttpResponse(render_to_string(
66
+ 'ui/widgets/model_search_select_options.html',
67
+ {'options': queryset}
68
+ ))
69
+
70
+
60
71
  def add_trigger(
61
- response: [HttpResponse],
72
+ response: HttpResponse,
62
73
  trigger: dict | str,
63
74
  header: str = 'HX-Trigger'
64
75
  ) -> HttpResponse:
accrete/utils/forms.py CHANGED
@@ -1,79 +1,91 @@
1
1
  import re
2
2
  import logging
3
3
  from uuid import uuid4
4
- from typing import Type
4
+ from typing import Type, Any
5
+ from dataclasses import dataclass, field
5
6
  from django.db import transaction
6
7
  from django.forms import BaseFormSet, Form, ModelForm
7
8
 
8
9
  _logger = logging.getLogger(__name__)
9
10
 
10
11
 
11
- def save_form(form: [Form|ModelForm], commit=True, reraise=False) -> [Form | ModelForm]:
12
+ @dataclass
13
+ class FormResult:
14
+
15
+ form: Form | ModelForm
16
+ is_saved: bool = False
17
+ save_error: str | None = None
18
+ save_error_id: str | None = None
19
+ res: Any = None # return value of form.save()
20
+ inline_formsets: list = field(default_factory=list)
21
+
22
+ def __getattr__(self, item):
23
+ return getattr(self.form, item)
24
+
25
+ def __getitem__(self, item):
26
+ return self.form.__getitem__(item)
27
+
28
+
29
+ def save_form(form: Form | ModelForm, commit=True, reraise=False) -> FormResult:
12
30
  if not hasattr(form, 'save'):
13
31
  raise AttributeError('Form must have method "save" implemented.')
14
- form.is_saved = False
15
- form.save_error = None
16
- form.save_error_id = None
17
- form.res = None
32
+ result = FormResult(form=form)
18
33
  try:
19
34
  if form.is_valid():
20
35
  with transaction.atomic():
21
- form.res = form.save(commit=commit)
22
- form.is_saved = True
36
+ result.res = form.save(commit=commit)
37
+ result.is_saved = True
23
38
  except Exception as e:
24
- form.save_error = repr(e)
39
+ result.save_error = repr(e)
25
40
  error_id = str(uuid4())[:8]
26
41
  _logger.exception(f'{error_id}: {e}')
27
- form.save_error_id = error_id
42
+ result.save_error_id = error_id
28
43
  if reraise:
29
44
  raise e
30
- return form
45
+ return result
31
46
 
32
47
 
33
- def save_forms(form, inline_formsets: list = None, commit=True, reraise: bool = False) -> [Form | ModelForm]:
48
+ def save_forms(form, inline_formsets: list = None, commit=True, reraise: bool = False) -> FormResult:
34
49
 
35
50
  def handle_error(error):
36
- form.save_error = repr(error)
51
+ result.save_error = repr(error)
37
52
  error_id = str(uuid4())[:8]
38
53
  _logger.exception(f'{error_id}: {error}')
39
- form.save_error_id = error_id
54
+ result.save_error_id = error_id
40
55
 
41
56
  if not hasattr(form, 'save'):
42
57
  raise AttributeError('Form must have method "save" implemented.')
43
58
 
44
- form.is_saved = False
45
- form.save_error = None
46
- form.save_error_id = None
47
- form.res = None
48
- form.inline_forms = inline_formsets
59
+ result = FormResult(form=form)
60
+ result.inline_forms = inline_formsets
49
61
 
50
62
  try:
51
63
  form.is_valid()
52
64
  inlines_valid = all([
53
- inline_formset.is_valid() for inline_formset in inline_formsets
65
+ inline_formset.is_valid() for inline_formset in result.inline_formsets
54
66
  ])
55
67
  except Exception as e:
56
68
  handle_error(e)
57
69
  if reraise:
58
70
  raise e
59
- return form
71
+ return result
60
72
 
61
73
  if not form.is_valid() or not inlines_valid:
62
- return form
74
+ return result
63
75
 
64
76
  try:
65
77
  with transaction.atomic():
66
- form.res = form.save(commit=commit)
67
- for inline_formset in inline_formsets:
78
+ result.res = form.save(commit=commit)
79
+ for inline_formset in result.inline_formsets:
68
80
  inline_formset.save(commit=commit)
69
81
  except Exception as e:
70
82
  handle_error(e)
71
83
  if reraise:
72
84
  raise e
73
- return form
85
+ return result
74
86
 
75
- form.is_saved = True
76
- return form
87
+ result.is_saved = True
88
+ return result
77
89
 
78
90
 
79
91
  def inline_vals_from_post(post: dict, prefix: str) -> list[dict]:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: accrete
3
- Version: 0.0.142
3
+ Version: 0.0.143
4
4
  Summary: Django Shared Schema Multi Tenant
5
5
  Author-email: Benedikt Jilek <benedikt.jilek@pm.me>
6
6
  License: Copyright (c) 2025 Benedikt Jilek
@@ -60,7 +60,7 @@ accrete/contrib/system_mail/tests.py,sha256=mrbGGRNg5jwbTJtWWa7zSKdDyeB4vmgZCRc2
60
60
  accrete/contrib/system_mail/views.py,sha256=xc1IQHrsij7j33TUbo-_oewy3vs03pw_etpBWaMYJl0,63
61
61
  accrete/contrib/system_mail/migrations/0001_initial.py,sha256=6cwkkRXGjXvwXoMjjgmWmcPyXSTlUbhW1vMiHObk9MQ,1074
62
62
  accrete/contrib/system_mail/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
63
- accrete/contrib/ui/__init__.py,sha256=ziSWIhoBk2EhnkG7gGhMKSLSlgLICPm-M2RxdWAjrn0,300
63
+ accrete/contrib/ui/__init__.py,sha256=7zRjbKxFZ_ox5XQmHmfxbKKJRcm_wxgmjXS759GdlEo,328
64
64
  accrete/contrib/ui/admin.py,sha256=suMo4x8I3JBxAFBVIdE-5qnqZ6JAZV0FESABHOSc-vg,63
65
65
  accrete/contrib/ui/apps.py,sha256=E0ao2ox6PQ3ldfeR17FXJUUJuGiWjm2DPCxHbPXGzls,152
66
66
  accrete/contrib/ui/context.py,sha256=7FBNcPG77dU7asMomiRACP1bypE3lbsHXdg90MXbjf4,2616
@@ -69,7 +69,7 @@ accrete/contrib/ui/middleware.py,sha256=QprWR8FXK9iMPIvLQAeYASaUJSW0uD9BHoYroMKr
69
69
  accrete/contrib/ui/models.py,sha256=Vjc0p2XbAPgE6HyTF6vll98A4eDhA5AvaQqsc4kQ9AQ,57
70
70
  accrete/contrib/ui/tests.py,sha256=mrbGGRNg5jwbTJtWWa7zSKdDyeB4vmgZCRc2nk6VY-g,60
71
71
  accrete/contrib/ui/urls.py,sha256=5XUfK85HYWYf7oopMoJEEYmQ6pNgHgZBErBEn97pBt4,337
72
- accrete/contrib/ui/utils.py,sha256=CyDqwIUAOhZQ-p0MCEjWzk-qEYI1jn_NBBL-D7Oi63w,2193
72
+ accrete/contrib/ui/utils.py,sha256=f660YNavcQQkO6TtpnEBsT2O3KoJk-M5wgBnhnWB1EI,2563
73
73
  accrete/contrib/ui/views.py,sha256=5VUbP0jgMcLMv9-3AKxkV315RA0qXuw5PmTRejPc0Yg,1136
74
74
  accrete/contrib/ui/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
75
75
  accrete/contrib/ui/static/bulma/LICENSE,sha256=--fY7Bi3Lt7RXXnKc9pe756OJY9fGv-D5OmT5pdSJ5w,1080
@@ -199,11 +199,11 @@ accrete/contrib/ui/templates/django/forms/widgets/text.html,sha256=MSmLlQc7PsPoD
199
199
  accrete/contrib/ui/templates/django/forms/widgets/textarea.html,sha256=c9BTedqb3IkXLyVYd0p9pR8DFnsXCNGoxVBWZTk_Fic,278
200
200
  accrete/contrib/ui/templates/ui/content_right.html,sha256=3DQqbjAafaLtWUTGcBTCzObQEII35DVLfWQ6i6KDh6Y,379
201
201
  accrete/contrib/ui/templates/ui/favicon.html,sha256=ZSK6qDGV4Cexgt0VA3KOHYN100yZHOFjfOiFZVudWg0,90
202
- accrete/contrib/ui/templates/ui/form_error.html,sha256=uPfIkK9OMpy5H147AxVxNAhG6dKBa9Wq64_f4tk5UU8,379
202
+ accrete/contrib/ui/templates/ui/form_error.html,sha256=WWqfFWyJ_LCzm5IkxXztn23GFak5wyM2HZcmiZ3Eq9s,417
203
203
  accrete/contrib/ui/templates/ui/layout.html,sha256=yDcZYMUdT3ZaqXPC1qg2Lme_dBnBUG2ZzGyrG0V6ces,13174
204
204
  accrete/contrib/ui/templates/ui/list.html,sha256=o0YGM2O4SUlFcP5jMwdEOXVTCuEfanvd77yH7OBRRws,2208
205
205
  accrete/contrib/ui/templates/ui/list_update.html,sha256=mLQTCgkKfVI5jrgei-Upc1u87iXL0Q63uLzXHPwMyeo,110
206
- accrete/contrib/ui/templates/ui/message.html,sha256=3LPe1D5tmEhan7Ldrwy3MsK6cL1uZSKt6aDYQNtNVHc,732
206
+ accrete/contrib/ui/templates/ui/message.html,sha256=jhqkPlWtOaPDoclTm4yKwowA7vR-bWbwfjo2b48uJt0,764
207
207
  accrete/contrib/ui/templates/ui/modal.html,sha256=2HwmqcUvGqWfKpuKO1EOfr5F1Lcwn7eChbu3XbrxvYg,2233
208
208
  accrete/contrib/ui/templates/ui/oob.html,sha256=lZHIBBYclefbGkKguS1A7vrtOhODJizbSRaGAAHDvG8,267
209
209
  accrete/contrib/ui/templates/ui/table.html,sha256=u6JJz1FykuljZiiC2hL83hy8RbMeXcSH8xuU1ji2SHc,3939
@@ -270,11 +270,11 @@ accrete/migrations/0007_accessgroup_description.py,sha256=T8BX0gSckC_fM_uD6a5-fd
270
270
  accrete/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
271
271
  accrete/utils/__init__.py,sha256=saw9zi2XItJOPbv4fjTXOpl7StNtC803jHhapFcGx08,312
272
272
  accrete/utils/dates.py,sha256=apM6kt6JhGrKgoT0jfav1W-8AUVTxNc9xt3fJQ2n0JI,1492
273
- accrete/utils/forms.py,sha256=JJ3EY1xcVP6L10i5cSVgh57G0uvFUjiVwUCpEqmBCos,3407
273
+ accrete/utils/forms.py,sha256=H8ojiMRrafdj6Jd-86w2SxkaqshKepNHP2_XOXsMmKQ,3758
274
274
  accrete/utils/log.py,sha256=BH0MBDweAjx30wGBO4F3sFhbgkSoEs7T1lLLjlYZNnA,407
275
275
  accrete/utils/models.py,sha256=2xTacvcpmDK_Bp4rAK7JdVLf8HU009LYNJ6eSpMgYZI,1014
276
276
  accrete/utils/views.py,sha256=PsKpUFjxCm6_l_nfVs-cNIY0lNTdkocm2uohR3o9eEo,5025
277
- accrete-0.0.142.dist-info/METADATA,sha256=dA1QJQ7xbXLO5cXqWqKdPuJWEbUfLZpjmKQcVjsbGdc,4953
278
- accrete-0.0.142.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
279
- accrete-0.0.142.dist-info/licenses/LICENSE,sha256=vHwb4Qnv8UfYKFiCWyTuRGsi49x19UQwHRCky3b2_NE,1057
280
- accrete-0.0.142.dist-info/RECORD,,
277
+ accrete-0.0.143.dist-info/METADATA,sha256=JfyR1afDladHASbgL-b4Kg1nA6ijfDlOmqEv2qV0qyc,4953
278
+ accrete-0.0.143.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
279
+ accrete-0.0.143.dist-info/licenses/LICENSE,sha256=vHwb4Qnv8UfYKFiCWyTuRGsi49x19UQwHRCky3b2_NE,1057
280
+ accrete-0.0.143.dist-info/RECORD,,