statezero 0.1.0b16__tar.gz → 0.1.0b18__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 statezero might be problematic. Click here for more details.
- {statezero-0.1.0b16 → statezero-0.1.0b18}/PKG-INFO +1 -1
- {statezero-0.1.0b16 → statezero-0.1.0b18}/pyproject.toml +1 -1
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/adaptors/django/orm.py +9 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/adaptors/django/schemas.py +3 -4
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/adaptors/django/serializers.py +33 -24
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/adaptors/django/urls.py +2 -1
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/adaptors/django/views.py +101 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/core/ast_parser.py +2 -13
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/core/config.py +0 -2
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/core/interfaces.py +10 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero.egg-info/PKG-INFO +1 -1
- {statezero-0.1.0b16 → statezero-0.1.0b18}/README.md +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/license.md +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/requirements.txt +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/setup.cfg +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/__init__.py +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/adaptors/__init__.py +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/adaptors/django/__init__.py +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/adaptors/django/actions.py +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/adaptors/django/apps.py +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/adaptors/django/config.py +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/adaptors/django/context_manager.py +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/adaptors/django/event_emitters.py +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/adaptors/django/exception_handler.py +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/adaptors/django/extensions/__init__.py +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/adaptors/django/extensions/custom_field_serializers/__init__.py +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/adaptors/django/extensions/custom_field_serializers/file_fields.py +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/adaptors/django/extensions/custom_field_serializers/money_field.py +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/adaptors/django/f_handler.py +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/adaptors/django/helpers.py +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/adaptors/django/middleware.py +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/adaptors/django/migrations/0001_initial.py +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/adaptors/django/migrations/0002_delete_modelviewsubscription.py +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/adaptors/django/migrations/__init__.py +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/adaptors/django/permissions.py +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/adaptors/django/query_optimizer.py +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/adaptors/django/search_providers/__init__.py +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/adaptors/django/search_providers/basic_search.py +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/adaptors/django/search_providers/postgres_search.py +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/core/__init__.py +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/core/actions.py +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/core/ast_validator.py +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/core/classes.py +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/core/context_storage.py +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/core/event_bus.py +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/core/event_emitters.py +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/core/exceptions.py +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/core/hook_checks.py +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/core/process_request.py +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/core/types.py +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero.egg-info/SOURCES.txt +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero.egg-info/dependency_links.txt +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero.egg-info/requires.txt +0 -0
- {statezero-0.1.0b16 → statezero-0.1.0b18}/statezero.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: statezero
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.0b18
|
|
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
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "statezero"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.0b18"
|
|
8
8
|
description = "Connect your Python backend to a modern JavaScript SPA frontend with 90% less complexity."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { file = "LICENSE" }
|
|
@@ -763,6 +763,7 @@ class DjangoORMAdapter(AbstractORMProvider):
|
|
|
763
763
|
def get_fields(self, model: models.Model) -> Set[str]:
|
|
764
764
|
"""
|
|
765
765
|
Return a set of the model fields.
|
|
766
|
+
Includes both database fields and additional_fields (computed fields).
|
|
766
767
|
"""
|
|
767
768
|
model_config = registry.get_config(model)
|
|
768
769
|
if model_config.fields and "__all__" != model_config.fields:
|
|
@@ -775,6 +776,14 @@ class DjangoORMAdapter(AbstractORMProvider):
|
|
|
775
776
|
resolved_fields = resolved_fields.union(additional_fields)
|
|
776
777
|
return resolved_fields
|
|
777
778
|
|
|
779
|
+
def get_db_fields(self, model: models.Model) -> Set[str]:
|
|
780
|
+
"""
|
|
781
|
+
Return only actual database fields for the model.
|
|
782
|
+
Excludes read-only additional_fields (computed fields).
|
|
783
|
+
Used for deserialization - hooks can write to any DB field.
|
|
784
|
+
"""
|
|
785
|
+
return set(field.name for field in model._meta.get_fields())
|
|
786
|
+
|
|
778
787
|
def build_model_graph(
|
|
779
788
|
self, model: Type[models.Model], model_graph: nx.DiGraph = None
|
|
780
789
|
) -> nx.DiGraph:
|
|
@@ -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.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.fields
|
|
47
47
|
]
|
|
48
48
|
|
|
49
49
|
for field in all_fields:
|
|
@@ -323,8 +323,7 @@ class DjangoSchemaGenerator(AbstractSchemaGenerator):
|
|
|
323
323
|
@staticmethod
|
|
324
324
|
def is_field_required(field: models.Field) -> bool:
|
|
325
325
|
return (
|
|
326
|
-
not field.
|
|
327
|
-
and not field.null
|
|
326
|
+
not field.null
|
|
328
327
|
and field.default == models.fields.NOT_PROVIDED
|
|
329
328
|
)
|
|
330
329
|
|
|
@@ -6,7 +6,7 @@ from rest_framework import serializers
|
|
|
6
6
|
import contextvars
|
|
7
7
|
from contextlib import contextmanager
|
|
8
8
|
import logging
|
|
9
|
-
from cytoolz import pluck
|
|
9
|
+
from cytoolz import pluck, keyfilter
|
|
10
10
|
from zen_queries import queries_disabled
|
|
11
11
|
|
|
12
12
|
from statezero.adaptors.django.config import config, registry
|
|
@@ -484,33 +484,42 @@ class DRFDynamicSerializer(AbstractDataSerializer):
|
|
|
484
484
|
# Serious security issue if fields_map is None
|
|
485
485
|
assert fields_map is not None, "fields_map is required and cannot be None"
|
|
486
486
|
|
|
487
|
-
#
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
serializer_class = DynamicModelSerializer.for_model(model)
|
|
491
|
-
available_fields = set(serializer_class().fields.keys())
|
|
487
|
+
# Get model name and allowed fields from fields_map
|
|
488
|
+
model_name = config.orm_provider.get_model_name(model)
|
|
489
|
+
allowed_fields = fields_map.get(model_name, set())
|
|
492
490
|
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
491
|
+
# Filter user input to only allowed fields (security boundary)
|
|
492
|
+
data = dict(keyfilter(lambda k: k in allowed_fields, data))
|
|
493
|
+
|
|
494
|
+
try:
|
|
495
|
+
model_config = registry.get_config(model)
|
|
496
|
+
except ValueError:
|
|
497
|
+
# No model config available
|
|
498
|
+
model_config = None
|
|
499
|
+
|
|
500
|
+
# Run pre-hooks on filtered data (hooks can add any DB fields)
|
|
501
|
+
if model_config and model_config.pre_hooks:
|
|
502
|
+
for hook in model_config.pre_hooks:
|
|
503
|
+
hook_result = hook(data, request=request)
|
|
504
|
+
if settings.DEBUG:
|
|
505
|
+
# Note: available_fields check removed since hooks can add any DB field
|
|
506
|
+
data = hook_result or data
|
|
507
|
+
else:
|
|
508
|
+
data = hook_result or data
|
|
509
|
+
|
|
510
|
+
# Expand fields_map to all DB fields for serializer validation
|
|
511
|
+
# This allows hooks to add fields that aren't in the original fields_map
|
|
512
|
+
all_db_fields = config.orm_provider.get_db_fields(model)
|
|
513
|
+
expanded_fields_map = {model_name: all_db_fields}
|
|
514
|
+
|
|
515
|
+
# Use the context manager with expanded fields map
|
|
516
|
+
with fields_map_context(expanded_fields_map):
|
|
517
|
+
# Create serializer class with all DB fields available
|
|
518
|
+
serializer_class = DynamicModelSerializer.for_model(model)
|
|
510
519
|
|
|
511
520
|
# Create serializer
|
|
512
521
|
serializer = serializer_class(
|
|
513
|
-
data=data,
|
|
522
|
+
data=data,
|
|
514
523
|
partial=partial,
|
|
515
524
|
request=request
|
|
516
525
|
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from django.urls import path
|
|
2
2
|
|
|
3
|
-
from .views import EventsAuthView, ModelListView, ModelView, SchemaView, FileUploadView, FastUploadView, ActionSchemaView, ActionView, ValidateView
|
|
3
|
+
from .views import EventsAuthView, ModelListView, ModelView, SchemaView, FileUploadView, FastUploadView, ActionSchemaView, ActionView, ValidateView, FieldPermissionsView
|
|
4
4
|
|
|
5
5
|
app_name = "statezero"
|
|
6
6
|
|
|
@@ -12,6 +12,7 @@ urlpatterns = [
|
|
|
12
12
|
path("actions/<str:action_name>/", ActionView.as_view(), name="action"),
|
|
13
13
|
path("actions-schema/", ActionSchemaView.as_view(), name="actions_schema"),
|
|
14
14
|
path("<str:model_name>/validate/", ValidateView.as_view(), name="validate"),
|
|
15
|
+
path("<str:model_name>/field-permissions/", FieldPermissionsView.as_view(), name="field_permissions"),
|
|
15
16
|
path("<str:model_name>/get-schema/", SchemaView.as_view(), name="schema_view"),
|
|
16
17
|
path("<str:model_name>/", ModelView.as_view(), name="model_view"),
|
|
17
18
|
]
|
|
@@ -485,3 +485,104 @@ class ValidateView(APIView):
|
|
|
485
485
|
except Exception as original_exception:
|
|
486
486
|
# Let StateZero's exception handler deal with ValidationError, PermissionDenied, etc.
|
|
487
487
|
return explicit_exception_handler(original_exception)
|
|
488
|
+
|
|
489
|
+
|
|
490
|
+
class FieldPermissionsView(APIView):
|
|
491
|
+
"""
|
|
492
|
+
Returns user-specific field permissions for a given model.
|
|
493
|
+
Used by frontend forms to determine which fields to show/enable at runtime.
|
|
494
|
+
"""
|
|
495
|
+
|
|
496
|
+
permission_classes = [permission_class]
|
|
497
|
+
|
|
498
|
+
def get(self, request, model_name):
|
|
499
|
+
"""Get field permissions for the current user."""
|
|
500
|
+
try:
|
|
501
|
+
# Create processor following the same pattern as other views
|
|
502
|
+
processor = RequestProcessor(config=config, registry=registry)
|
|
503
|
+
|
|
504
|
+
# Get model using the processor's ORM provider
|
|
505
|
+
try:
|
|
506
|
+
model = processor.orm_provider.get_model_by_name(model_name)
|
|
507
|
+
except (LookupError, ValueError):
|
|
508
|
+
return Response({"error": f"Model {model_name} not found"}, status=404)
|
|
509
|
+
|
|
510
|
+
if not model:
|
|
511
|
+
return Response({"error": f"Model {model_name} not found"}, status=404)
|
|
512
|
+
|
|
513
|
+
try:
|
|
514
|
+
model_config = processor.registry.get_config(model)
|
|
515
|
+
except ValueError:
|
|
516
|
+
return Response(
|
|
517
|
+
{"error": f"Model {model_name} not registered"}, status=404
|
|
518
|
+
)
|
|
519
|
+
|
|
520
|
+
# Compute field permissions using the same logic as ASTParser._get_operation_fields
|
|
521
|
+
all_fields = processor.orm_provider.get_fields(model)
|
|
522
|
+
|
|
523
|
+
visible_fields = self._compute_operation_fields(
|
|
524
|
+
model, model_config, all_fields, request, "read"
|
|
525
|
+
)
|
|
526
|
+
creatable_fields = self._compute_operation_fields(
|
|
527
|
+
model, model_config, all_fields, request, "create"
|
|
528
|
+
)
|
|
529
|
+
editable_fields = self._compute_operation_fields(
|
|
530
|
+
model, model_config, all_fields, request, "update"
|
|
531
|
+
)
|
|
532
|
+
|
|
533
|
+
return Response(
|
|
534
|
+
{
|
|
535
|
+
"visible_fields": list(visible_fields),
|
|
536
|
+
"creatable_fields": list(creatable_fields),
|
|
537
|
+
"editable_fields": list(editable_fields),
|
|
538
|
+
},
|
|
539
|
+
status=200,
|
|
540
|
+
)
|
|
541
|
+
|
|
542
|
+
except Exception as original_exception:
|
|
543
|
+
# Let StateZero's exception handler deal with errors
|
|
544
|
+
return explicit_exception_handler(original_exception)
|
|
545
|
+
|
|
546
|
+
def _compute_operation_fields(self, model, model_config, all_fields, request, operation_type):
|
|
547
|
+
"""
|
|
548
|
+
Compute allowed fields for a specific operation type.
|
|
549
|
+
Replicates the logic from ASTParser._get_operation_fields.
|
|
550
|
+
"""
|
|
551
|
+
from typing import Union, Set, Literal
|
|
552
|
+
|
|
553
|
+
allowed_fields = set()
|
|
554
|
+
|
|
555
|
+
for permission_cls in model_config.permissions:
|
|
556
|
+
permission = permission_cls()
|
|
557
|
+
|
|
558
|
+
# Get the appropriate field set based on operation
|
|
559
|
+
if operation_type == "read":
|
|
560
|
+
fields = permission.visible_fields(request, model)
|
|
561
|
+
elif operation_type == "create":
|
|
562
|
+
fields = permission.create_fields(request, model)
|
|
563
|
+
elif operation_type == "update":
|
|
564
|
+
fields = permission.editable_fields(request, model)
|
|
565
|
+
else:
|
|
566
|
+
fields = set()
|
|
567
|
+
|
|
568
|
+
# If any permission allows all fields
|
|
569
|
+
if fields == "__all__":
|
|
570
|
+
# For read operations, default "__all__" to frontend_fields
|
|
571
|
+
if operation_type == "read":
|
|
572
|
+
# If frontend_fields is also "__all__", then return all fields
|
|
573
|
+
if model_config.fields == "__all__":
|
|
574
|
+
return all_fields
|
|
575
|
+
# Otherwise, use frontend_fields as the default for "__all__"
|
|
576
|
+
else:
|
|
577
|
+
fields = model_config.fields
|
|
578
|
+
fields &= all_fields # Ensure fields actually exist
|
|
579
|
+
allowed_fields |= fields
|
|
580
|
+
else:
|
|
581
|
+
# For create/update operations, "__all__" means truly all fields
|
|
582
|
+
return all_fields
|
|
583
|
+
else:
|
|
584
|
+
# Add allowed fields from this permission
|
|
585
|
+
fields &= all_fields # Ensure fields actually exist
|
|
586
|
+
allowed_fields |= fields
|
|
587
|
+
|
|
588
|
+
return allowed_fields
|
|
@@ -386,19 +386,8 @@ class ASTParser:
|
|
|
386
386
|
|
|
387
387
|
# If any permission allows all fields
|
|
388
388
|
if fields == "__all__":
|
|
389
|
-
|
|
390
|
-
|
|
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
|
|
389
|
+
return all_fields
|
|
390
|
+
|
|
402
391
|
# Add allowed fields from this permission
|
|
403
392
|
else: # Ensure we're not operating on the string "__all__"
|
|
404
393
|
fields &= all_fields # Ensure fields actually exist
|
|
@@ -181,7 +181,6 @@ 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,
|
|
185
184
|
display: Optional[Any] = None,
|
|
186
185
|
DEBUG: bool = False,
|
|
187
186
|
):
|
|
@@ -196,7 +195,6 @@ class ModelConfig:
|
|
|
196
195
|
self.searchable_fields = searchable_fields or set()
|
|
197
196
|
self.ordering_fields = ordering_fields or set()
|
|
198
197
|
self.fields = fields or "__all__"
|
|
199
|
-
self.frontend_fields = frontend_fields or self.fields
|
|
200
198
|
self.display = display
|
|
201
199
|
self.DEBUG = DEBUG or False
|
|
202
200
|
|
|
@@ -70,6 +70,16 @@ class AbstractORMProvider(ABC):
|
|
|
70
70
|
def get_fields(self, model: ORMModel) -> Set[str]:
|
|
71
71
|
"""
|
|
72
72
|
Get all of the model fields - doesn't apply permissions check.
|
|
73
|
+
Includes both database fields and additional_fields (computed fields).
|
|
74
|
+
"""
|
|
75
|
+
pass
|
|
76
|
+
|
|
77
|
+
@abstractmethod
|
|
78
|
+
def get_db_fields(self, model: ORMModel) -> Set[str]:
|
|
79
|
+
"""
|
|
80
|
+
Get only the actual database fields for a model.
|
|
81
|
+
Excludes read-only additional_fields (computed fields).
|
|
82
|
+
Used for deserialization - hooks can write to any DB field.
|
|
73
83
|
"""
|
|
74
84
|
pass
|
|
75
85
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: statezero
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.0b18
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/adaptors/django/migrations/0001_initial.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/adaptors/django/search_providers/__init__.py
RENAMED
|
File without changes
|
{statezero-0.1.0b16 → statezero-0.1.0b18}/statezero/adaptors/django/search_providers/basic_search.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|