slthcore 0.4.8__tar.gz → 0.4.9__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.
Potentially problematic release.
This version of slthcore might be problematic. Click here for more details.
- {slthcore-0.4.8/slthcore.egg-info → slthcore-0.4.9}/PKG-INFO +1 -1
- {slthcore-0.4.8 → slthcore-0.4.9}/setup.py +1 -1
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/endpoints/__init__.py +45 -11
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/factory.py +5 -5
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/forms.py +24 -23
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/management/commands/api.py +26 -3
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/models.py +1 -1
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/serializer.py +7 -3
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/static/js/slth.min.js +8 -8
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/utils.py +8 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/views.py +1 -1
- {slthcore-0.4.8 → slthcore-0.4.9/slthcore.egg-info}/PKG-INFO +1 -1
- {slthcore-0.4.8 → slthcore-0.4.9}/MANIFEST.in +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/setup.cfg +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/__init__.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/application.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/apps.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/cmd/configure/__main__.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/cmd/init/__main__.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/cmd/init/__pycache__/__main__.cpython-312.pyc +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/cmd/init/boilerplate/.DS_Store +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/cmd/init/boilerplate/.gitignore +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/cmd/init/boilerplate/backend/api/__init__.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/cmd/init/boilerplate/backend/api/asgi.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/cmd/init/boilerplate/backend/api/endpoints/__init__.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/cmd/init/boilerplate/backend/api/models.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/cmd/init/boilerplate/backend/api/settings.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/cmd/init/boilerplate/backend/api/tests.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/cmd/init/boilerplate/backend/api/urls.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/cmd/init/boilerplate/backend/api/wsgi.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/cmd/init/boilerplate/backend/entrypoint.sh +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/cmd/init/boilerplate/backend/manage.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/cmd/init/boilerplate/backend/requirements.txt +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/cmd/init/boilerplate/base.env +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/cmd/init/boilerplate/docker-compose.yml +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/cmd/init/boilerplate/frontend/package.json +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/cmd/init/boilerplate/frontend/src/main.jsx +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/cmd/init/boilerplate/frontend/vite.config.js +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/cmd/init/boilerplate/local.env +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/cmd/init/boilerplate/run.sh +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/cmd/init/boilerplate/selenium/run.sh +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/cmd/init/boilerplate/test.sh +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/components.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/db/__init__.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/db/generic.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/db/models.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/endpoints/auth.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/endpoints/deletion.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/endpoints/dev.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/endpoints/email.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/endpoints/job.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/endpoints/log.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/endpoints/profile.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/endpoints/pushsubscription.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/endpoints/report.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/endpoints/role.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/endpoints/task.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/endpoints/timezone.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/endpoints/user.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/endpoints/whatsappnotification.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/exceptions.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/management/__init__.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/management/commands/__init__.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/management/commands/integration_test.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/management/commands/sync.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/management/commands/worker.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/middleware/__init__.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/middleware/timezone.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/migrations/0001_initial.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/migrations/0002_email_role_pushsubscription_error.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/migrations/0003_rename_photo_profile_alter_profile_options.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/migrations/0004_alter_profile_photo.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/migrations/0005_alter_profile_photo.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/migrations/0006_user.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/migrations/0007_deletion_log.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/migrations/0008_alter_deletion_datetime_alter_log_datetime.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/migrations/0009_remove_email_from_email_email_action_email_attempt_and_more.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/migrations/0010_email_key_alter_email_action_alter_email_attempt_and_more.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/migrations/0011_usertimezone.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/migrations/0012_timezone_remove_usertimezone_key_and_more.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/migrations/0013_whatsappnotification.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/migrations/__init__.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/notifications.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/oauth.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/pdf/__init__.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/pdf/tests.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/permissions.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/printer.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/queryset.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/roles.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/selenium/__init__.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/selenium/browser.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/static/.DS_Store +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/static/css/.DS_Store +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/static/css/slth.css +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/static/images/placeholder.png +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/static/js/index.min.js +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/static/js/react.min.js +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/statistics.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/tasks.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/templates/email.html +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/templates/index.html +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/templates/report.html +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/templates/service-worker.js +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/templates/signature.html +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/tests.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/threadlocal.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/tz.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slth/urls.py +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slthcore.egg-info/SOURCES.txt +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slthcore.egg-info/dependency_links.txt +0 -0
- {slthcore-0.4.8 → slthcore-0.4.9}/slthcore.egg-info/top_level.txt +0 -0
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import io
|
|
2
|
-
import json
|
|
3
2
|
import inspect
|
|
4
3
|
from ..models import Log
|
|
5
4
|
from django.apps import apps
|
|
@@ -26,10 +25,9 @@ from ..components import (
|
|
|
26
25
|
from slth.application import Application as ApplicationConfig
|
|
27
26
|
from ..exceptions import JsonResponseException, ReadyResponseException
|
|
28
27
|
from ..utils import build_url, append_url
|
|
29
|
-
from ..models import
|
|
28
|
+
from ..models import Log, Job
|
|
30
29
|
from slth.queryset import QuerySet
|
|
31
30
|
from slth import ENDPOINTS
|
|
32
|
-
from .. import oauth
|
|
33
31
|
from ..threadlocal import tl
|
|
34
32
|
from ..tasks import Task
|
|
35
33
|
|
|
@@ -65,6 +63,7 @@ class Endpoint(metaclass=EnpointMetaclass):
|
|
|
65
63
|
cache = cache
|
|
66
64
|
|
|
67
65
|
def __init__(self):
|
|
66
|
+
self.form: Form | ModelForm = None
|
|
68
67
|
self.base_url = None
|
|
69
68
|
self.request = None
|
|
70
69
|
self.source = None
|
|
@@ -150,15 +149,15 @@ class Endpoint(metaclass=EnpointMetaclass):
|
|
|
150
149
|
elif isinstance(data, Serializer):
|
|
151
150
|
data = data.contextualize(self.request).settitle(title)
|
|
152
151
|
elif isinstance(data, FormFactory):
|
|
153
|
-
form = self.getform(data.settitle(title).
|
|
154
|
-
if self.request.method == "POST" or (title and self.request.GET.get("form") == form._key):
|
|
152
|
+
self.form = self.getform(data.settitle(title).build(self))
|
|
153
|
+
if self.request.method == "POST" or (title and self.request.GET.get("form") == self.form._key):
|
|
155
154
|
try:
|
|
156
155
|
if isinstance(self, DeleteEndpoint):
|
|
157
156
|
return self.post()
|
|
158
157
|
else:
|
|
159
|
-
self.cleaned_data = form.submit()
|
|
160
|
-
if form._message or form._redirect or form._dispose:
|
|
161
|
-
return Response(form._message, form._redirect, dispose=form._dispose)
|
|
158
|
+
self.cleaned_data = self.form.submit()
|
|
159
|
+
if self.form._message or self.form._redirect or self.form._dispose:
|
|
160
|
+
return Response(self.form._message, self.form._redirect, dispose=self.form._dispose)
|
|
162
161
|
else:
|
|
163
162
|
return self.post()
|
|
164
163
|
except ValidationError as e:
|
|
@@ -166,7 +165,7 @@ class Endpoint(metaclass=EnpointMetaclass):
|
|
|
166
165
|
dict(type="error", text="\n".join(e.messages), errors={})
|
|
167
166
|
)
|
|
168
167
|
else:
|
|
169
|
-
data = form
|
|
168
|
+
data = self.form
|
|
170
169
|
elif isinstance(data, Form) or isinstance(data, ModelForm):
|
|
171
170
|
data = data.settitle(title)
|
|
172
171
|
elif self.request.method == "POST":# and not data:
|
|
@@ -337,7 +336,6 @@ class PublicEndpoint(Endpoint):
|
|
|
337
336
|
return True
|
|
338
337
|
|
|
339
338
|
|
|
340
|
-
|
|
341
339
|
class ModelEndpoint(Endpoint):
|
|
342
340
|
def __init__(self):
|
|
343
341
|
self.model = self.__orig_bases__[0].__args__[0]
|
|
@@ -503,6 +501,43 @@ class ChildInstanceEndpoint(ChildEndpoint):
|
|
|
503
501
|
return Serializer(self.get_instance()).contextualize(self.request)
|
|
504
502
|
|
|
505
503
|
|
|
504
|
+
class RelationEditEndpoint(Generic[T], ChildEndpoint):
|
|
505
|
+
|
|
506
|
+
def __init__(self, instance):
|
|
507
|
+
self.source = instance
|
|
508
|
+
|
|
509
|
+
def get(self) -> FormFactory:
|
|
510
|
+
return self.formfactory()
|
|
511
|
+
|
|
512
|
+
def formfactory(self) -> FormFactory:
|
|
513
|
+
return FormFactory(self.get_instance())
|
|
514
|
+
|
|
515
|
+
def get_instance(self):
|
|
516
|
+
return self.__orig_bases__[0].__args__[0].objects.get(pk=self.request.GET['id'])
|
|
517
|
+
|
|
518
|
+
|
|
519
|
+
class RelationDeleteEndpoint(Generic[T], ChildEndpoint):
|
|
520
|
+
|
|
521
|
+
def __init__(self, instance):
|
|
522
|
+
self.model = self.__orig_bases__[0].__args__[0]
|
|
523
|
+
self.source = instance
|
|
524
|
+
|
|
525
|
+
def get(self) -> FormFactory:
|
|
526
|
+
return FormFactory(self.get_instance()).fields()
|
|
527
|
+
|
|
528
|
+
def post(self):
|
|
529
|
+
self.get_instance().safe_delete(self.request.user.username)
|
|
530
|
+
return super().post()
|
|
531
|
+
|
|
532
|
+
def formfactory(self) -> FormFactory:
|
|
533
|
+
return FormFactory(self.get_instance())
|
|
534
|
+
|
|
535
|
+
def get_instance(self):
|
|
536
|
+
return self.model.objects.get(pk=self.request.GET['id'])
|
|
537
|
+
|
|
538
|
+
|
|
539
|
+
|
|
540
|
+
|
|
506
541
|
class Search(Endpoint):
|
|
507
542
|
def get(self):
|
|
508
543
|
key = "_options_"
|
|
@@ -529,7 +564,6 @@ class Search(Endpoint):
|
|
|
529
564
|
return result[0:10]
|
|
530
565
|
|
|
531
566
|
|
|
532
|
-
|
|
533
567
|
class Home(PublicEndpoint):
|
|
534
568
|
class Meta:
|
|
535
569
|
verbose_name = ""
|
|
@@ -3,7 +3,7 @@ from .serializer import Serializer
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
class FormFactory:
|
|
6
|
-
def __init__(self, instance,
|
|
6
|
+
def __init__(self, instance, method='POST'):
|
|
7
7
|
self._instance = instance
|
|
8
8
|
self._fieldsets = {}
|
|
9
9
|
self._values = {}
|
|
@@ -48,7 +48,7 @@ class FormFactory:
|
|
|
48
48
|
self._append_field(field_name)
|
|
49
49
|
for k in values:
|
|
50
50
|
self._append_field(k)
|
|
51
|
-
self.
|
|
51
|
+
self.values(**values)
|
|
52
52
|
self._empty = not self._fieldlist
|
|
53
53
|
return self
|
|
54
54
|
|
|
@@ -84,7 +84,7 @@ class FormFactory:
|
|
|
84
84
|
self._actions.update(kwargs)
|
|
85
85
|
return self
|
|
86
86
|
|
|
87
|
-
def
|
|
87
|
+
def values(self, **kwargs) -> 'FormFactory':
|
|
88
88
|
self._values.update(kwargs)
|
|
89
89
|
return self
|
|
90
90
|
|
|
@@ -106,7 +106,7 @@ class FormFactory:
|
|
|
106
106
|
self._redirect = '.'
|
|
107
107
|
return self
|
|
108
108
|
|
|
109
|
-
def
|
|
109
|
+
def build(self, endpoint):
|
|
110
110
|
from .forms import ModelForm, Form
|
|
111
111
|
|
|
112
112
|
if isinstance(self._instance, Model):
|
|
@@ -135,7 +135,7 @@ class FormFactory:
|
|
|
135
135
|
for name, queryset in self._choices.items():
|
|
136
136
|
form.fields[name].queryset = queryset
|
|
137
137
|
form.fieldsets = self._fieldsets
|
|
138
|
-
form.
|
|
138
|
+
form.values(**self._values)
|
|
139
139
|
if self._display:
|
|
140
140
|
serializer = Serializer(self._instance, request=endpoint.request)
|
|
141
141
|
for title, fields in self._display.items():
|
|
@@ -6,7 +6,7 @@ from django.utils.translation import gettext_lazy as _
|
|
|
6
6
|
from django.forms.models import ModelChoiceIterator, ModelMultipleChoiceField
|
|
7
7
|
from django.forms import fields
|
|
8
8
|
from django.db.models import Model, QuerySet, Manager
|
|
9
|
-
from .
|
|
9
|
+
from django.utils.text import slugify
|
|
10
10
|
from django.db import transaction
|
|
11
11
|
from django.db.models import Manager
|
|
12
12
|
from .exceptions import JsonResponseException
|
|
@@ -35,7 +35,7 @@ MASKS = dict(
|
|
|
35
35
|
|
|
36
36
|
class FormController:
|
|
37
37
|
|
|
38
|
-
def __init__(self, form):
|
|
38
|
+
def __init__(self, form: Form | ModelForm):
|
|
39
39
|
super().__init__()
|
|
40
40
|
self.form = form
|
|
41
41
|
self.controls = dict(hide=[], show=[], reload=[], set={})
|
|
@@ -66,7 +66,10 @@ class FormController:
|
|
|
66
66
|
v = v.strftime("%Y-%m-%d")
|
|
67
67
|
self.controls["set"][k] = v
|
|
68
68
|
|
|
69
|
-
def get(self,
|
|
69
|
+
def get(self, field_name, default=None):
|
|
70
|
+
return self.field_value(field_name, self.form.request.GET.get(field_name, default))
|
|
71
|
+
|
|
72
|
+
def field_value(self, name, value, default=None):
|
|
70
73
|
if value is None:
|
|
71
74
|
return default
|
|
72
75
|
else:
|
|
@@ -83,28 +86,28 @@ class FormController:
|
|
|
83
86
|
self.controls["hide"].clear()
|
|
84
87
|
self.controls["set"].clear()
|
|
85
88
|
|
|
86
|
-
def
|
|
89
|
+
def on_field_change(self, field_name):
|
|
87
90
|
self.clear()
|
|
88
|
-
|
|
91
|
+
value = self.get(field_name)
|
|
92
|
+
getattr(self.form._endpoint, f"on_{field_name}_change")(value)
|
|
89
93
|
return self.controls
|
|
90
94
|
|
|
91
|
-
|
|
92
|
-
def get_field_queryset(self, fname, qs):
|
|
95
|
+
def get_field_queryset(self, field_name, queryset):
|
|
93
96
|
method_attr = None
|
|
94
|
-
method_name = f"get_{
|
|
97
|
+
method_name = f"get_{field_name}_queryset"
|
|
95
98
|
if hasattr(self.form._endpoint, method_name):
|
|
96
99
|
method_attr = getattr(self.form._endpoint, method_name)
|
|
97
100
|
elif hasattr(self.form, "instance") and hasattr(
|
|
98
101
|
self.form.instance, method_name
|
|
99
102
|
):
|
|
100
103
|
method_attr = getattr(self.form.instance, method_name)
|
|
101
|
-
queryset = method_attr(
|
|
104
|
+
queryset = method_attr(queryset) if method_attr else queryset
|
|
102
105
|
return queryset.apply_lookups(self.form.request.user)
|
|
103
106
|
|
|
104
107
|
def values(self):
|
|
105
108
|
data = dict(**self.controls["set"])
|
|
106
109
|
for name in self.form.fields:
|
|
107
|
-
value = self.get(name
|
|
110
|
+
value = self.get(name)
|
|
108
111
|
if value:
|
|
109
112
|
data[name] = value
|
|
110
113
|
return data
|
|
@@ -156,7 +159,7 @@ class FormMixin:
|
|
|
156
159
|
def to_dict(self, prefix=None):
|
|
157
160
|
field_name = self.request.GET.get("on_change")
|
|
158
161
|
if field_name:
|
|
159
|
-
raise JsonResponseException(self.controller.
|
|
162
|
+
raise JsonResponseException(self.controller.on_field_change(field_name))
|
|
160
163
|
data = dict(
|
|
161
164
|
type="form",
|
|
162
165
|
key=self._key,
|
|
@@ -176,7 +179,9 @@ class FormMixin:
|
|
|
176
179
|
)
|
|
177
180
|
if self._display:
|
|
178
181
|
if isinstance(self._display, Serializer):
|
|
179
|
-
|
|
182
|
+
self._display.request.GET._mutable = True
|
|
183
|
+
self._display.request.GET.pop('only', None)
|
|
184
|
+
self._display.request.GET._mutable = False
|
|
180
185
|
data.update(
|
|
181
186
|
display=self._display.serialize(forward_exception=True)["data"]
|
|
182
187
|
)
|
|
@@ -220,7 +225,7 @@ class FormMixin:
|
|
|
220
225
|
fieldsetlist.append(fields[0][0])
|
|
221
226
|
else:
|
|
222
227
|
fieldsetlist.append(
|
|
223
|
-
dict(type="fieldset", title=title, fields=fields)
|
|
228
|
+
dict(type="fieldset", title=title, name=slugify(title), fields=fields)
|
|
224
229
|
)
|
|
225
230
|
data.update(fieldsets=fieldsetlist)
|
|
226
231
|
else:
|
|
@@ -285,7 +290,7 @@ class FormMixin:
|
|
|
285
290
|
else:
|
|
286
291
|
value = None
|
|
287
292
|
if self.instance is None or self.instance.id is None:
|
|
288
|
-
value = field.initial
|
|
293
|
+
value = field.initial or self.initial.get(name)
|
|
289
294
|
else:
|
|
290
295
|
value = self.initial.get(name)
|
|
291
296
|
if callable(value):
|
|
@@ -307,7 +312,7 @@ class FormMixin:
|
|
|
307
312
|
isinstance(field, ModelChoiceField)
|
|
308
313
|
or isinstance(field, DjangoModelChoiceField)
|
|
309
314
|
):
|
|
310
|
-
obj = field.queryset.get(pk=value)
|
|
315
|
+
obj = field.queryset.get(pk=value) if isinstance(value, int) else value
|
|
311
316
|
value = dict(id=obj.id, label=str(obj).strip())
|
|
312
317
|
elif isinstance(field, DjangoImageField):
|
|
313
318
|
value = build_url(self.request, value.url) if value else None
|
|
@@ -397,11 +402,9 @@ class FormMixin:
|
|
|
397
402
|
cls = ENDPOINTS[self._actions[name]]
|
|
398
403
|
endpoint = cls.instantiate(self.request, self)
|
|
399
404
|
if endpoint.check_permission():
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
)
|
|
404
|
-
)
|
|
405
|
+
action=endpoint.get_api_metadata(self.request, absolute_url(self.request))
|
|
406
|
+
action['name'] = action['name'].replace(field.label, "").strip()
|
|
407
|
+
data.update(action=action)
|
|
405
408
|
return data
|
|
406
409
|
|
|
407
410
|
def submit(self):
|
|
@@ -525,7 +528,7 @@ class FormMixin:
|
|
|
525
528
|
self._title = title
|
|
526
529
|
return self
|
|
527
530
|
|
|
528
|
-
def
|
|
531
|
+
def values(self, **kwargs):
|
|
529
532
|
self._values.update(**kwargs)
|
|
530
533
|
return self
|
|
531
534
|
|
|
@@ -700,8 +703,6 @@ class CharField(CharField):
|
|
|
700
703
|
self.mask = kwargs.pop("mask", None)
|
|
701
704
|
super().__init__(*args, **kwargs)
|
|
702
705
|
|
|
703
|
-
|
|
704
|
-
|
|
705
706
|
|
|
706
707
|
class ChoiceField(ChoiceField):
|
|
707
708
|
|
|
@@ -14,22 +14,36 @@ class {plural}(endpoints.ListEndpoint[{model}]):
|
|
|
14
14
|
def get(self):
|
|
15
15
|
return (
|
|
16
16
|
super().get()
|
|
17
|
-
.actions('{lower}.cadastrar', '{lower}.editar', '{lower}.excluir')
|
|
17
|
+
.actions('{lower}.cadastrar', '{lower}.visualizar', '{lower}.editar', '{lower}.excluir')
|
|
18
18
|
)
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
class Cadastrar(endpoints.AddEndpoint[{model}]):
|
|
22
22
|
class Meta:
|
|
23
|
+
icon = 'plus'
|
|
23
24
|
verbose_name = 'Cadastrar {verbose_name}'
|
|
24
25
|
|
|
25
26
|
def get(self):
|
|
26
27
|
return (
|
|
27
28
|
super().get()
|
|
28
29
|
)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class Visualizar(endpoints.ViewEndpoint[{model}]):
|
|
33
|
+
class Meta:
|
|
34
|
+
modal = False
|
|
35
|
+
icon = 'eye'
|
|
36
|
+
verbose_name = 'Visualizar {verbose_name}'
|
|
37
|
+
|
|
38
|
+
def get(self):
|
|
39
|
+
return (
|
|
40
|
+
super().get()
|
|
41
|
+
)
|
|
29
42
|
|
|
30
43
|
|
|
31
44
|
class Editar(endpoints.EditEndpoint[{model}]):
|
|
32
45
|
class Meta:
|
|
46
|
+
icon = 'pen'
|
|
33
47
|
verbose_name = 'Editar {verbose_name}'
|
|
34
48
|
|
|
35
49
|
def get(self):
|
|
@@ -40,6 +54,7 @@ class Editar(endpoints.EditEndpoint[{model}]):
|
|
|
40
54
|
|
|
41
55
|
class Excluir(endpoints.DeleteEndpoint[{model}]):
|
|
42
56
|
class Meta:
|
|
57
|
+
icon = 'trash'
|
|
43
58
|
verbose_name = 'Excluir {verbose_name}'
|
|
44
59
|
|
|
45
60
|
def get(self):
|
|
@@ -50,10 +65,18 @@ class Excluir(endpoints.DeleteEndpoint[{model}]):
|
|
|
50
65
|
"""
|
|
51
66
|
|
|
52
67
|
class Command(Command):
|
|
68
|
+
|
|
69
|
+
def add_arguments(self, parser):
|
|
70
|
+
parser.add_argument("models", nargs="*", type=str)
|
|
53
71
|
|
|
54
72
|
def handle(self, *args, **options):
|
|
55
|
-
|
|
56
|
-
|
|
73
|
+
names = options.get('models')
|
|
74
|
+
if names:
|
|
75
|
+
models = [apps.get_model(name) for name in names]
|
|
76
|
+
else:
|
|
77
|
+
models = apps.get_models()
|
|
78
|
+
for model in models:
|
|
79
|
+
if names or model._meta.app_label == "api":
|
|
57
80
|
content = TEMPLATE.format(
|
|
58
81
|
plural = slugify(model._meta.verbose_name_plural).replace('-de-', '-').replace('-', '').title(),
|
|
59
82
|
model = model.__name__,
|
|
@@ -96,7 +96,7 @@ class RoleFilter(models.Filter):
|
|
|
96
96
|
|
|
97
97
|
def choices(self, queryset, term=None):
|
|
98
98
|
application = ApplicationConfig.get_instance()
|
|
99
|
-
return [(k, v) for k, v in application.items()]
|
|
99
|
+
return [(k, v) for k, v in application.groups.items()]
|
|
100
100
|
|
|
101
101
|
def filter(self, queryset, value):
|
|
102
102
|
if value:
|
|
@@ -143,10 +143,11 @@ class Serializer:
|
|
|
143
143
|
self.metadata['content'].append(('queryset', name, dict(title=title, condition=condition, roles=roles)))
|
|
144
144
|
return self
|
|
145
145
|
|
|
146
|
-
def endpoint(self, title, cls, wrap=
|
|
146
|
+
def endpoint(self, title, cls, wrap=False, condition=None, roles=()) -> 'Serializer':
|
|
147
|
+
key = to_snake_case(title) if title else cls.replace('.', '_')
|
|
147
148
|
if isinstance(cls, str):
|
|
148
149
|
cls = slth.ENDPOINTS[cls]
|
|
149
|
-
self.metadata['content'].append(('endpoint',
|
|
150
|
+
self.metadata['content'].append(('endpoint', key, dict(title=title, cls=cls, wrap=wrap, condition=condition, roles=roles)))
|
|
150
151
|
return self
|
|
151
152
|
|
|
152
153
|
def append(self, title, component, condition=None, roles=()) -> 'Serializer':
|
|
@@ -217,6 +218,9 @@ class Serializer:
|
|
|
217
218
|
if self.request and 'action' in self.request.GET:
|
|
218
219
|
cls = slth.ENDPOINTS[self.request.GET.get('action')]
|
|
219
220
|
if cls:### and cls.get_key_name() in self.metadata['allow']:
|
|
221
|
+
self.request.GET._mutable = True
|
|
222
|
+
self.request.GET.pop('action', None)
|
|
223
|
+
self.request.GET._mutable = False
|
|
220
224
|
endpoint = cls.instantiate(self.request, self.obj)
|
|
221
225
|
if endpoint.check_permission():
|
|
222
226
|
raise JsonResponseException(endpoint.serialize())
|
|
@@ -234,7 +238,7 @@ class Serializer:
|
|
|
234
238
|
if leaf:
|
|
235
239
|
raise JsonResponseException(actions)
|
|
236
240
|
|
|
237
|
-
if not self.metadata['content'] and self.obj:
|
|
241
|
+
if not self.metadata['content'] and self.obj and isinstance(self.obj, Model):
|
|
238
242
|
self.fields(*[field.name for field in type(self.obj)._meta.fields])
|
|
239
243
|
for m2m in type(self.obj)._meta.many_to_many:
|
|
240
244
|
self.queryset(m2m.verbose_name, m2m.name)
|