statezero 0.1.0b12__py3-none-any.whl → 0.1.0b14__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.
- statezero/adaptors/django/extensions/custom_field_serializers/money_field.py +8 -0
- statezero/adaptors/django/query_optimizer.py +40 -2
- statezero/adaptors/django/schemas.py +2 -2
- statezero/core/ast_parser.py +13 -2
- statezero/core/config.py +2 -0
- {statezero-0.1.0b12.dist-info → statezero-0.1.0b14.dist-info}/METADATA +1 -1
- {statezero-0.1.0b12.dist-info → statezero-0.1.0b14.dist-info}/RECORD +10 -10
- {statezero-0.1.0b12.dist-info → statezero-0.1.0b14.dist-info}/WHEEL +0 -0
- {statezero-0.1.0b12.dist-info → statezero-0.1.0b14.dist-info}/licenses/license.md +0 -0
- {statezero-0.1.0b12.dist-info → statezero-0.1.0b14.dist-info}/top_level.txt +0 -0
|
@@ -15,6 +15,14 @@ class MoneyFieldSerializer(serializers.Field):
|
|
|
15
15
|
self.decimal_places = kwargs.pop("decimal_places", 2)
|
|
16
16
|
super().__init__(**kwargs)
|
|
17
17
|
|
|
18
|
+
@classmethod
|
|
19
|
+
def get_prefetch_db_fields(cls, field_name: str):
|
|
20
|
+
"""
|
|
21
|
+
Return all database fields required for this field to serialize.
|
|
22
|
+
MoneyField creates two database columns: field_name and field_name_currency.
|
|
23
|
+
"""
|
|
24
|
+
return [field_name, f"{field_name}_currency"]
|
|
25
|
+
|
|
18
26
|
def to_representation(self, value):
|
|
19
27
|
djmoney_field = MoneyField(
|
|
20
28
|
max_digits=self.max_digits, decimal_places=self.decimal_places
|
|
@@ -477,7 +477,34 @@ def optimize_query(queryset, fields=None, fields_map=None, depth=0, use_only=Tru
|
|
|
477
477
|
related_fields_to_fetch = set()
|
|
478
478
|
|
|
479
479
|
if fields_map and related_model_name in fields_map:
|
|
480
|
-
|
|
480
|
+
# Process each field, checking for custom serializers
|
|
481
|
+
from statezero.adaptors.django.serializers import get_custom_serializer
|
|
482
|
+
related_meta = _get_model_meta(related_model)
|
|
483
|
+
for field_name in fields_map[related_model_name]:
|
|
484
|
+
try:
|
|
485
|
+
field_obj = related_meta.get_field(field_name)
|
|
486
|
+
if not field_obj.is_relation:
|
|
487
|
+
# Check if this field has a custom serializer with explicit DB field requirements
|
|
488
|
+
custom_serializer = get_custom_serializer(field_obj.__class__)
|
|
489
|
+
if custom_serializer and hasattr(custom_serializer, 'get_prefetch_db_fields'):
|
|
490
|
+
# Use the explicit list from the custom serializer
|
|
491
|
+
db_fields = custom_serializer.get_prefetch_db_fields(field_name)
|
|
492
|
+
for db_field in db_fields:
|
|
493
|
+
related_fields_to_fetch.add(db_field)
|
|
494
|
+
logger.debug(f"Using custom DB fields {db_fields} for field '{field_name}' in {related_model_name}")
|
|
495
|
+
else:
|
|
496
|
+
# No custom serializer, just add the field itself
|
|
497
|
+
related_fields_to_fetch.add(field_name)
|
|
498
|
+
else:
|
|
499
|
+
# Relation field, add as-is
|
|
500
|
+
related_fields_to_fetch.add(field_name)
|
|
501
|
+
except FieldDoesNotExist:
|
|
502
|
+
# Field doesn't exist, add it anyway (might be computed)
|
|
503
|
+
related_fields_to_fetch.add(field_name)
|
|
504
|
+
except Exception as e:
|
|
505
|
+
logger.error(f"Error checking custom serializer for field '{field_name}' in {related_model_name}: {e}")
|
|
506
|
+
# On error, add the field anyway to be safe
|
|
507
|
+
related_fields_to_fetch.add(field_name)
|
|
481
508
|
else:
|
|
482
509
|
# If no field restrictions are provided, get all fields
|
|
483
510
|
all_fields = [f.name for f in related_model._meta.get_fields() if f.concrete]
|
|
@@ -531,7 +558,18 @@ def optimize_query(queryset, fields=None, fields_map=None, depth=0, use_only=Tru
|
|
|
531
558
|
try:
|
|
532
559
|
field_obj = root_meta.get_field(field_name)
|
|
533
560
|
if not field_obj.is_relation:
|
|
534
|
-
|
|
561
|
+
# Check if this field has a custom serializer with explicit DB field requirements
|
|
562
|
+
from statezero.adaptors.django.serializers import get_custom_serializer
|
|
563
|
+
custom_serializer = get_custom_serializer(field_obj.__class__)
|
|
564
|
+
if custom_serializer and hasattr(custom_serializer, 'get_prefetch_db_fields'):
|
|
565
|
+
# Use the explicit list from the custom serializer
|
|
566
|
+
db_fields = custom_serializer.get_prefetch_db_fields(field_name)
|
|
567
|
+
for db_field in db_fields:
|
|
568
|
+
root_fields_to_fetch.add(db_field)
|
|
569
|
+
logger.debug(f"Using custom DB fields {db_fields} for field '{field_name}'")
|
|
570
|
+
else:
|
|
571
|
+
# No custom serializer, just add the field itself
|
|
572
|
+
root_fields_to_fetch.add(field_name)
|
|
535
573
|
elif isinstance(field_obj, (ForeignKey, OneToOneField)):
|
|
536
574
|
# If FK/O2O itself is requested directly, include its id field
|
|
537
575
|
root_fields_to_fetch.add(field_obj.attname)
|
|
@@ -41,9 +41,9 @@ class DjangoSchemaGenerator(AbstractSchemaGenerator):
|
|
|
41
41
|
all_field_names: Set[str] = set()
|
|
42
42
|
db_field_names: Set[str] = set()
|
|
43
43
|
|
|
44
|
-
if model_config.
|
|
44
|
+
if model_config.frontend_fields != "__all__":
|
|
45
45
|
all_fields = [
|
|
46
|
-
field for field in all_fields if field.name in model_config.
|
|
46
|
+
field for field in all_fields if field.name in model_config.frontend_fields
|
|
47
47
|
]
|
|
48
48
|
|
|
49
49
|
for field in all_fields:
|
statezero/core/ast_parser.py
CHANGED
|
@@ -386,8 +386,19 @@ class ASTParser:
|
|
|
386
386
|
|
|
387
387
|
# If any permission allows all fields
|
|
388
388
|
if fields == "__all__":
|
|
389
|
-
|
|
390
|
-
|
|
389
|
+
# NEW: For read operations, default "__all__" to frontend_fields
|
|
390
|
+
if operation_type == "read":
|
|
391
|
+
# If frontend_fields is also "__all__", then return all fields
|
|
392
|
+
if model_config.frontend_fields == "__all__":
|
|
393
|
+
return all_fields
|
|
394
|
+
# Otherwise, use frontend_fields as the default for "__all__"
|
|
395
|
+
else:
|
|
396
|
+
fields = model_config.frontend_fields
|
|
397
|
+
fields &= all_fields # Ensure fields actually exist
|
|
398
|
+
allowed_fields |= fields
|
|
399
|
+
else:
|
|
400
|
+
# For create/update operations, "__all__" means truly all fields
|
|
401
|
+
return all_fields
|
|
391
402
|
# Add allowed fields from this permission
|
|
392
403
|
else: # Ensure we're not operating on the string "__all__"
|
|
393
404
|
fields &= all_fields # Ensure fields actually exist
|
statezero/core/config.py
CHANGED
|
@@ -181,6 +181,7 @@ class ModelConfig:
|
|
|
181
181
|
searchable_fields: Optional[Union[Set[str], Literal["__all__"]]] = None,
|
|
182
182
|
ordering_fields: Optional[Union[Set[str], Literal["__all__"]]] = None,
|
|
183
183
|
fields: Optional[Union[Set[str], Literal["__all__"]]] = None,
|
|
184
|
+
frontend_fields: Optional[Union[Set[str], Literal["__all__"]]] = None,
|
|
184
185
|
display: Optional[Any] = None,
|
|
185
186
|
DEBUG: bool = False,
|
|
186
187
|
):
|
|
@@ -195,6 +196,7 @@ class ModelConfig:
|
|
|
195
196
|
self.searchable_fields = searchable_fields or set()
|
|
196
197
|
self.ordering_fields = ordering_fields or set()
|
|
197
198
|
self.fields = fields or "__all__"
|
|
199
|
+
self.frontend_fields = frontend_fields or self.fields
|
|
198
200
|
self.display = display
|
|
199
201
|
self.DEBUG = DEBUG or False
|
|
200
202
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: statezero
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.0b14
|
|
4
4
|
Summary: Connect your Python backend to a modern JavaScript SPA frontend with 90% less complexity.
|
|
5
5
|
Author-email: Robert <robert.herring@statezero.dev>
|
|
6
6
|
Project-URL: homepage, https://www.statezero.dev
|
|
@@ -12,15 +12,15 @@ statezero/adaptors/django/helpers.py,sha256=0Dyq5vboDuTUaH-KpS3oVDjastA9yv6xI6Xp
|
|
|
12
12
|
statezero/adaptors/django/middleware.py,sha256=YVr8fkqCk51xJQM-ovtrUiB9Kt9H81cLd9xv4cM9YlM,410
|
|
13
13
|
statezero/adaptors/django/orm.py,sha256=Z62XheCvuKIpKOoIIiLLOwrpJ5jPhv-BGxg-pqPgNaU,40757
|
|
14
14
|
statezero/adaptors/django/permissions.py,sha256=fU2c4bKK0zX2uuVB0UazZHTI-5OkiI5-BtPNcPEWmW0,9525
|
|
15
|
-
statezero/adaptors/django/query_optimizer.py,sha256=-
|
|
16
|
-
statezero/adaptors/django/schemas.py,sha256=
|
|
15
|
+
statezero/adaptors/django/query_optimizer.py,sha256=-iAh5kyE8WNZdjb_qBbNag_nxKzejroUYPBdwG_uVaQ,41462
|
|
16
|
+
statezero/adaptors/django/schemas.py,sha256=YYWvtg-SNcARBZPl51zb4tY2BStcXDYbprKSyS3mIbM,13467
|
|
17
17
|
statezero/adaptors/django/serializers.py,sha256=YFFDu6bzoWkSEOVH5Wmc4yJ8SaOkUA6HbXXYt6djlfc,23296
|
|
18
18
|
statezero/adaptors/django/urls.py,sha256=OrGQ60vj_wrbiREAKmYDZTwohpKmgjH9n0fdOw1qPaY,924
|
|
19
19
|
statezero/adaptors/django/views.py,sha256=2bJDbXuRGoG2_7zyapWzmRzpSVUHkCpcI58wsrXN1jc,19947
|
|
20
20
|
statezero/adaptors/django/extensions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
21
21
|
statezero/adaptors/django/extensions/custom_field_serializers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
22
|
statezero/adaptors/django/extensions/custom_field_serializers/file_fields.py,sha256=BaOaJPmyzCp-YFwpsTOvGHjHpk6s8UJuZ5JsF-PEGV4,4518
|
|
23
|
-
statezero/adaptors/django/extensions/custom_field_serializers/money_field.py,sha256=
|
|
23
|
+
statezero/adaptors/django/extensions/custom_field_serializers/money_field.py,sha256=Oms0_hOaxpeTDI7JhgwFud8kYIVxX-fEflO7C1QBi9I,3083
|
|
24
24
|
statezero/adaptors/django/migrations/0001_initial.py,sha256=F5kr819sPN5_xc82GpX6-e5CwVWDvywePWC0cv9zYKY,1318
|
|
25
25
|
statezero/adaptors/django/migrations/0002_delete_modelviewsubscription.py,sha256=7fJXl18gvMdEjKnQbO2h8mPAl4jNGVCAb60NRl5V6tI,317
|
|
26
26
|
statezero/adaptors/django/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -29,10 +29,10 @@ statezero/adaptors/django/search_providers/basic_search.py,sha256=5_GJ1r_B6JdIYX
|
|
|
29
29
|
statezero/adaptors/django/search_providers/postgres_search.py,sha256=IMoHxzfi-Y3hAxPND4Xc6GatrPs1eXAqpmcfwt5Zr14,2459
|
|
30
30
|
statezero/core/__init__.py,sha256=Z6RTutAAElLMEjBFphVVmpySPdJBA55j-Uo0BtR7c5E,1040
|
|
31
31
|
statezero/core/actions.py,sha256=eq4zuDhK1h-nZ24jUQhiWL6BcMqq-W4BhdVNdYegymw,2969
|
|
32
|
-
statezero/core/ast_parser.py,sha256=
|
|
32
|
+
statezero/core/ast_parser.py,sha256=QTFRDwanN2jJJOs4SeRdRPiVZWlK-tkmwZBlQNByew0,39321
|
|
33
33
|
statezero/core/ast_validator.py,sha256=YZAflPyba0kXWBNhd1Z_XeEk-_zUzM6MkY9zSlX1PMs,11582
|
|
34
34
|
statezero/core/classes.py,sha256=NLIiOPm6PwQAmJXFeN2iScdoGeHyimzdnXmyyfBM-NY,6977
|
|
35
|
-
statezero/core/config.py,sha256=
|
|
35
|
+
statezero/core/config.py,sha256=kOcQPzBA06d8EliP2bVY0daFlt8bm-8ZOsqb5x7-8JA,11822
|
|
36
36
|
statezero/core/context_storage.py,sha256=DVx525ZMRorj41kg5K0N6pPdGkQ5_XEJcBucpH5ChxQ,162
|
|
37
37
|
statezero/core/event_bus.py,sha256=2IFLBHSkLzpm1AX0MfSXSmF2X-lXK-gOoODZCtB2Jdw,6284
|
|
38
38
|
statezero/core/event_emitters.py,sha256=qjMbeUmdn4bG7WiVfqTmNdaflEea5amnTEpOn5X0J44,2046
|
|
@@ -41,8 +41,8 @@ statezero/core/hook_checks.py,sha256=uqtvwRx1qGsF7Vc49elAWdOjMzhuv3RADKY1wiLvhK4
|
|
|
41
41
|
statezero/core/interfaces.py,sha256=kVkNWyh52tUlzD02CRheLJof3DyQoVcPuvX33fL6sn8,20544
|
|
42
42
|
statezero/core/process_request.py,sha256=dwIeBEVOE8zA-oE1h65XNOGiVqFbbXA7SzTAguLNgZk,8060
|
|
43
43
|
statezero/core/types.py,sha256=mMtqK3fGhEM6LtzUgQrxlyP-V0VgVqc-1eVKgRjTzp0,913
|
|
44
|
-
statezero-0.1.
|
|
45
|
-
statezero-0.1.
|
|
46
|
-
statezero-0.1.
|
|
47
|
-
statezero-0.1.
|
|
48
|
-
statezero-0.1.
|
|
44
|
+
statezero-0.1.0b14.dist-info/licenses/license.md,sha256=0uKjybTt9K_YbEmYgf25JN292qjjJ-BPofvIZ3wdtX4,7411
|
|
45
|
+
statezero-0.1.0b14.dist-info/METADATA,sha256=uhyUyV7nb4_H58RrviWtMXDzZjQDTKxyvUSBxsl38Fo,6704
|
|
46
|
+
statezero-0.1.0b14.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
47
|
+
statezero-0.1.0b14.dist-info/top_level.txt,sha256=UAuZYPKczradU1kcMQxsGjUzEW0qdgsqzhXyscrcLpw,10
|
|
48
|
+
statezero-0.1.0b14.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|