django-nativemojo 0.1.10__py3-none-any.whl → 0.1.15__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.
- django_nativemojo-0.1.15.dist-info/METADATA +136 -0
- {django_nativemojo-0.1.10.dist-info → django_nativemojo-0.1.15.dist-info}/RECORD +105 -65
- mojo/__init__.py +1 -1
- mojo/apps/account/management/__init__.py +5 -0
- mojo/apps/account/management/commands/__init__.py +6 -0
- mojo/apps/account/management/commands/serializer_admin.py +531 -0
- mojo/apps/account/migrations/0004_user_avatar.py +20 -0
- mojo/apps/account/migrations/0005_group_last_activity.py +18 -0
- mojo/apps/account/models/group.py +25 -7
- mojo/apps/account/models/member.py +15 -4
- mojo/apps/account/models/user.py +197 -20
- mojo/apps/account/rest/group.py +1 -0
- mojo/apps/account/rest/user.py +6 -2
- mojo/apps/aws/rest/__init__.py +1 -0
- mojo/apps/aws/rest/s3.py +64 -0
- mojo/apps/fileman/README.md +8 -8
- mojo/apps/fileman/backends/base.py +76 -70
- mojo/apps/fileman/backends/filesystem.py +86 -86
- mojo/apps/fileman/backends/s3.py +200 -108
- mojo/apps/fileman/migrations/0001_initial.py +106 -0
- mojo/apps/fileman/migrations/0002_filemanager_parent_alter_filemanager_max_file_size.py +24 -0
- mojo/apps/fileman/migrations/0003_remove_file_fileman_fil_upload__c4bc35_idx_and_more.py +25 -0
- mojo/apps/fileman/migrations/0004_remove_file_original_filename_and_more.py +39 -0
- mojo/apps/fileman/migrations/0005_alter_file_upload_token.py +18 -0
- mojo/apps/fileman/migrations/0006_file_download_url_filemanager_forever_urls.py +23 -0
- mojo/apps/fileman/migrations/0007_remove_filemanager_forever_urls_and_more.py +22 -0
- mojo/apps/fileman/migrations/0008_file_category.py +18 -0
- mojo/apps/fileman/migrations/0009_rename_file_path_file_storage_file_path.py +18 -0
- mojo/apps/fileman/migrations/0010_filerendition.py +33 -0
- mojo/apps/fileman/migrations/0011_alter_filerendition_original_file.py +19 -0
- mojo/apps/fileman/models/__init__.py +1 -5
- mojo/apps/fileman/models/file.py +204 -58
- mojo/apps/fileman/models/manager.py +161 -31
- mojo/apps/fileman/models/rendition.py +118 -0
- mojo/apps/fileman/renderer/__init__.py +111 -0
- mojo/apps/fileman/renderer/audio.py +403 -0
- mojo/apps/fileman/renderer/base.py +205 -0
- mojo/apps/fileman/renderer/document.py +404 -0
- mojo/apps/fileman/renderer/image.py +222 -0
- mojo/apps/fileman/renderer/utils.py +297 -0
- mojo/apps/fileman/renderer/video.py +304 -0
- mojo/apps/fileman/rest/__init__.py +1 -18
- mojo/apps/fileman/rest/upload.py +22 -32
- mojo/apps/fileman/signals.py +58 -0
- mojo/apps/fileman/tasks.py +254 -0
- mojo/apps/fileman/utils/__init__.py +40 -16
- mojo/apps/incident/migrations/0005_incidenthistory.py +39 -0
- mojo/apps/incident/migrations/0006_alter_incident_state.py +18 -0
- mojo/apps/incident/models/__init__.py +1 -0
- mojo/apps/incident/models/history.py +36 -0
- mojo/apps/incident/models/incident.py +1 -1
- mojo/apps/incident/reporter.py +3 -1
- mojo/apps/incident/rest/event.py +7 -1
- mojo/apps/logit/migrations/0004_alter_log_level.py +18 -0
- mojo/apps/logit/models/log.py +4 -1
- mojo/apps/metrics/utils.py +2 -2
- mojo/apps/notify/handlers/ses/message.py +1 -1
- mojo/apps/notify/providers/aws.py +2 -2
- mojo/apps/tasks/__init__.py +34 -1
- mojo/apps/tasks/manager.py +200 -45
- mojo/apps/tasks/rest/tasks.py +24 -10
- mojo/apps/tasks/runner.py +283 -18
- mojo/apps/tasks/task.py +99 -0
- mojo/apps/tasks/tq_handlers.py +118 -0
- mojo/decorators/auth.py +6 -1
- mojo/decorators/http.py +7 -2
- mojo/helpers/aws/__init__.py +41 -0
- mojo/helpers/aws/ec2.py +804 -0
- mojo/helpers/aws/iam.py +748 -0
- mojo/helpers/aws/s3.py +451 -11
- mojo/helpers/aws/ses.py +483 -0
- mojo/helpers/aws/sns.py +461 -0
- mojo/helpers/crypto/__pycache__/hash.cpython-310.pyc +0 -0
- mojo/helpers/crypto/__pycache__/sign.cpython-310.pyc +0 -0
- mojo/helpers/crypto/__pycache__/utils.cpython-310.pyc +0 -0
- mojo/helpers/dates.py +18 -0
- mojo/helpers/response.py +6 -2
- mojo/helpers/settings/__init__.py +2 -0
- mojo/helpers/{settings.py → settings/helper.py} +1 -37
- mojo/helpers/settings/parser.py +132 -0
- mojo/middleware/logging.py +1 -1
- mojo/middleware/mojo.py +5 -0
- mojo/models/rest.py +261 -46
- mojo/models/secrets.py +13 -4
- mojo/serializers/__init__.py +100 -0
- mojo/serializers/advanced/README.md +363 -0
- mojo/serializers/advanced/__init__.py +247 -0
- mojo/serializers/advanced/formats/__init__.py +28 -0
- mojo/serializers/advanced/formats/csv.py +416 -0
- mojo/serializers/advanced/formats/excel.py +516 -0
- mojo/serializers/advanced/formats/json.py +239 -0
- mojo/serializers/advanced/formats/localizers.py +509 -0
- mojo/serializers/advanced/formats/response.py +485 -0
- mojo/serializers/advanced/serializer.py +568 -0
- mojo/serializers/manager.py +501 -0
- mojo/serializers/optimized.py +618 -0
- mojo/serializers/settings_example.py +322 -0
- mojo/serializers/{models.py → simple.py} +38 -15
- testit/helpers.py +21 -4
- django_nativemojo-0.1.10.dist-info/METADATA +0 -96
- mojo/apps/metrics/rest/db.py +0 -0
- mojo/helpers/aws/setup_email.py +0 -0
- mojo/ws4redis/README.md +0 -174
- mojo/ws4redis/__init__.py +0 -2
- mojo/ws4redis/client.py +0 -283
- mojo/ws4redis/connection.py +0 -327
- mojo/ws4redis/exceptions.py +0 -32
- mojo/ws4redis/redis.py +0 -183
- mojo/ws4redis/servers/base.py +0 -86
- mojo/ws4redis/servers/django.py +0 -171
- mojo/ws4redis/servers/uwsgi.py +0 -63
- mojo/ws4redis/settings.py +0 -45
- mojo/ws4redis/utf8validator.py +0 -128
- mojo/ws4redis/websocket.py +0 -403
- {django_nativemojo-0.1.10.dist-info → django_nativemojo-0.1.15.dist-info}/LICENSE +0 -0
- {django_nativemojo-0.1.10.dist-info → django_nativemojo-0.1.15.dist-info}/NOTICE +0 -0
- {django_nativemojo-0.1.10.dist-info → django_nativemojo-0.1.15.dist-info}/WHEEL +0 -0
- /mojo/{ws4redis/servers → apps/aws}/__init__.py +0 -0
- /mojo/apps/{fileman/models/render.py → aws/models/__init__.py} +0 -0
- /mojo/apps/fileman/{rest/__init__ → migrations/__init__.py} +0 -0
@@ -0,0 +1,322 @@
|
|
1
|
+
"""
|
2
|
+
Django-MOJO Serializer Settings Configuration Examples
|
3
|
+
|
4
|
+
This file demonstrates how to configure the MOJO serializer system through Django settings.
|
5
|
+
Add the desired configurations to your project's settings.py file.
|
6
|
+
|
7
|
+
The serializer system supports:
|
8
|
+
- Multiple serializer backends (simple, optimized, advanced, custom)
|
9
|
+
- Performance tuning and caching configuration
|
10
|
+
- Runtime serializer switching
|
11
|
+
- Custom serializer registration
|
12
|
+
- Monitoring and debugging options
|
13
|
+
"""
|
14
|
+
|
15
|
+
# =============================================================================
|
16
|
+
# BASIC SERIALIZER CONFIGURATION
|
17
|
+
# =============================================================================
|
18
|
+
|
19
|
+
# Default serializer to use throughout the application
|
20
|
+
# Options: 'simple', 'optimized', 'advanced', or any custom registered name
|
21
|
+
MOJO_DEFAULT_SERIALIZER = 'optimized'
|
22
|
+
|
23
|
+
# Enable/disable performance tracking for serializers
|
24
|
+
MOJO_SERIALIZER_PERFORMANCE_TRACKING = True
|
25
|
+
|
26
|
+
# Enable debug logging for serializer operations
|
27
|
+
MOJO_SERIALIZER_DEBUG = False
|
28
|
+
|
29
|
+
# =============================================================================
|
30
|
+
# CUSTOM SERIALIZER REGISTRATION
|
31
|
+
# =============================================================================
|
32
|
+
|
33
|
+
# Register custom serializers
|
34
|
+
# Format: {'name': 'import.path.to.SerializerClass'} or {'name': config_dict}
|
35
|
+
MOJO_CUSTOM_SERIALIZERS = {
|
36
|
+
# Simple string path registration
|
37
|
+
'my_custom': 'myapp.serializers.CustomGraphSerializer',
|
38
|
+
|
39
|
+
# Detailed configuration with metadata
|
40
|
+
'enterprise': {
|
41
|
+
'class': 'myapp.serializers.EnterpriseSerializer',
|
42
|
+
'description': 'Enterprise-grade serializer with audit logging',
|
43
|
+
'is_default': False
|
44
|
+
},
|
45
|
+
|
46
|
+
# Redis-backed caching serializer
|
47
|
+
'redis_cached': {
|
48
|
+
'class': 'myapp.serializers.RedisCachedSerializer',
|
49
|
+
'description': 'Serializer with Redis-based distributed caching',
|
50
|
+
'is_default': False
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
# =============================================================================
|
55
|
+
# PERFORMANCE AND CACHING CONFIGURATION
|
56
|
+
# =============================================================================
|
57
|
+
|
58
|
+
# Optimized serializer cache settings
|
59
|
+
MOJO_OPTIMIZED_SERIALIZER = {
|
60
|
+
# Instance cache settings (model+graph+pk -> serialized data)
|
61
|
+
'instance_cache_size': 5000, # Maximum cached instances
|
62
|
+
'instance_cache_ttl': 300, # Time-to-live in seconds (5 minutes)
|
63
|
+
|
64
|
+
# Graph configuration cache (model+graph -> compiled config)
|
65
|
+
'graph_cache_size': 500, # Maximum cached graph configs
|
66
|
+
'graph_cache_ttl': 600, # Time-to-live in seconds (10 minutes)
|
67
|
+
|
68
|
+
# Query optimization cache
|
69
|
+
'query_cache_size': 500, # Maximum cached query optimizations
|
70
|
+
'query_cache_ttl': 600, # Time-to-live in seconds (10 minutes)
|
71
|
+
|
72
|
+
# Performance monitoring
|
73
|
+
'enable_performance_stats': True, # Track performance metrics
|
74
|
+
'stats_history_size': 1000, # Number of operations to track
|
75
|
+
}
|
76
|
+
|
77
|
+
# Advanced serializer settings (if using advanced serializer)
|
78
|
+
MOJO_ADVANCED_SERIALIZER = {
|
79
|
+
# Multi-format support
|
80
|
+
'enable_csv_export': True,
|
81
|
+
'enable_excel_export': True,
|
82
|
+
'enable_html_debug': True,
|
83
|
+
|
84
|
+
# Excel export settings
|
85
|
+
'excel_max_rows': 100000, # Maximum rows for Excel export
|
86
|
+
'excel_auto_width': True, # Auto-adjust column widths
|
87
|
+
'excel_freeze_panes': True, # Freeze header row
|
88
|
+
|
89
|
+
# CSV export settings
|
90
|
+
'csv_streaming_threshold': 1000, # Use streaming for > N rows
|
91
|
+
'csv_delimiter': ',', # CSV field delimiter
|
92
|
+
'csv_encoding': 'utf-8', # CSV file encoding
|
93
|
+
|
94
|
+
# Performance settings
|
95
|
+
'enable_caching': True,
|
96
|
+
'cache_timeout': 300, # Cache timeout in seconds
|
97
|
+
}
|
98
|
+
|
99
|
+
# =============================================================================
|
100
|
+
# DEVELOPMENT AND DEBUGGING
|
101
|
+
# =============================================================================
|
102
|
+
|
103
|
+
# Development-specific settings
|
104
|
+
if DEBUG:
|
105
|
+
# Enable detailed logging in development
|
106
|
+
MOJO_SERIALIZER_DEBUG = True
|
107
|
+
|
108
|
+
# Use smaller cache sizes for development
|
109
|
+
MOJO_OPTIMIZED_SERIALIZER['instance_cache_size'] = 1000
|
110
|
+
MOJO_OPTIMIZED_SERIALIZER['graph_cache_size'] = 100
|
111
|
+
|
112
|
+
# Enable performance benchmarking
|
113
|
+
MOJO_ENABLE_SERIALIZER_BENCHMARKS = True
|
114
|
+
|
115
|
+
# Production optimizations
|
116
|
+
else:
|
117
|
+
# Disable debug logging in production
|
118
|
+
MOJO_SERIALIZER_DEBUG = False
|
119
|
+
|
120
|
+
# Increase cache sizes for production
|
121
|
+
MOJO_OPTIMIZED_SERIALIZER['instance_cache_size'] = 10000
|
122
|
+
MOJO_OPTIMIZED_SERIALIZER['graph_cache_size'] = 1000
|
123
|
+
|
124
|
+
# Disable benchmarking in production
|
125
|
+
MOJO_ENABLE_SERIALIZER_BENCHMARKS = False
|
126
|
+
|
127
|
+
# =============================================================================
|
128
|
+
# REDIS INTEGRATION (Optional)
|
129
|
+
# =============================================================================
|
130
|
+
|
131
|
+
# Redis-backed caching for distributed environments
|
132
|
+
MOJO_REDIS_SERIALIZER_CACHE = {
|
133
|
+
'enabled': False, # Enable Redis caching
|
134
|
+
'host': 'localhost',
|
135
|
+
'port': 6379,
|
136
|
+
'db': 2, # Use separate DB for serializer cache
|
137
|
+
'password': None,
|
138
|
+
'key_prefix': 'mojo:serializer:', # Cache key prefix
|
139
|
+
'default_timeout': 300, # Default cache timeout
|
140
|
+
'connection_pool_kwargs': {
|
141
|
+
'max_connections': 50
|
142
|
+
}
|
143
|
+
}
|
144
|
+
|
145
|
+
# =============================================================================
|
146
|
+
# MONITORING AND ALERTS
|
147
|
+
# =============================================================================
|
148
|
+
|
149
|
+
# Performance monitoring thresholds
|
150
|
+
MOJO_SERIALIZER_MONITORING = {
|
151
|
+
'slow_serialization_threshold': 1.0, # Log if serialization takes > 1 second
|
152
|
+
'memory_usage_threshold': 100 * 1024 * 1024, # Alert if using > 100MB memory
|
153
|
+
'cache_hit_rate_threshold': 0.80, # Alert if cache hit rate < 80%
|
154
|
+
'error_rate_threshold': 0.05, # Alert if error rate > 5%
|
155
|
+
}
|
156
|
+
|
157
|
+
# Integration with external monitoring systems
|
158
|
+
MOJO_EXTERNAL_MONITORING = {
|
159
|
+
# StatsD integration
|
160
|
+
'statsd': {
|
161
|
+
'enabled': False,
|
162
|
+
'host': 'localhost',
|
163
|
+
'port': 8125,
|
164
|
+
'prefix': 'mojo.serializer'
|
165
|
+
},
|
166
|
+
|
167
|
+
# Sentry integration for error tracking
|
168
|
+
'sentry': {
|
169
|
+
'enabled': False,
|
170
|
+
'track_performance': True,
|
171
|
+
'sample_rate': 0.1 # Sample 10% of operations
|
172
|
+
}
|
173
|
+
}
|
174
|
+
|
175
|
+
# =============================================================================
|
176
|
+
# FEATURE FLAGS
|
177
|
+
# =============================================================================
|
178
|
+
|
179
|
+
# Feature flags for gradual rollout of new serializer features
|
180
|
+
MOJO_SERIALIZER_FEATURES = {
|
181
|
+
'optimized_serializer_default': True, # Use optimized serializer by default
|
182
|
+
'automatic_query_optimization': True, # Enable automatic select_related/prefetch_related
|
183
|
+
'advanced_caching': True, # Enable advanced caching strategies
|
184
|
+
'performance_monitoring': True, # Enable detailed performance monitoring
|
185
|
+
'async_serialization': False, # Enable async serialization (experimental)
|
186
|
+
'distributed_caching': False, # Enable distributed caching (experimental)
|
187
|
+
}
|
188
|
+
|
189
|
+
# =============================================================================
|
190
|
+
# MODEL-SPECIFIC CONFIGURATIONS
|
191
|
+
# =============================================================================
|
192
|
+
|
193
|
+
# Override serializer settings for specific models
|
194
|
+
MOJO_MODEL_SERIALIZER_OVERRIDES = {
|
195
|
+
'auth.User': {
|
196
|
+
'default_serializer': 'simple', # Use simple serializer for User model
|
197
|
+
'cache_ttl': 60, # Shorter cache TTL for user data
|
198
|
+
'enable_caching': True
|
199
|
+
},
|
200
|
+
|
201
|
+
'myapp.LargeDataModel': {
|
202
|
+
'default_serializer': 'optimized', # Use optimized serializer for large models
|
203
|
+
'cache_ttl': 1800, # Longer cache TTL for stable data
|
204
|
+
'enable_query_optimization': True
|
205
|
+
},
|
206
|
+
|
207
|
+
'reports.AnalyticsData': {
|
208
|
+
'default_serializer': 'advanced', # Use advanced serializer for reports
|
209
|
+
'enable_csv_export': True,
|
210
|
+
'enable_excel_export': True
|
211
|
+
}
|
212
|
+
}
|
213
|
+
|
214
|
+
# =============================================================================
|
215
|
+
# LOGGING CONFIGURATION
|
216
|
+
# =============================================================================
|
217
|
+
|
218
|
+
# Add serializer-specific logging configuration to Django's LOGGING setting
|
219
|
+
SERIALIZER_LOGGING = {
|
220
|
+
'version': 1,
|
221
|
+
'disable_existing_loggers': False,
|
222
|
+
'formatters': {
|
223
|
+
'serializer': {
|
224
|
+
'format': '[{levelname}] {asctime} {name} - {message}',
|
225
|
+
'style': '{',
|
226
|
+
},
|
227
|
+
},
|
228
|
+
'handlers': {
|
229
|
+
'serializer_file': {
|
230
|
+
'level': 'INFO',
|
231
|
+
'class': 'logging.handlers.RotatingFileHandler',
|
232
|
+
'filename': 'logs/serializer.log',
|
233
|
+
'maxBytes': 10 * 1024 * 1024, # 10MB
|
234
|
+
'backupCount': 5,
|
235
|
+
'formatter': 'serializer',
|
236
|
+
},
|
237
|
+
'performance_file': {
|
238
|
+
'level': 'INFO',
|
239
|
+
'class': 'logging.handlers.RotatingFileHandler',
|
240
|
+
'filename': 'logs/serializer_performance.log',
|
241
|
+
'maxBytes': 10 * 1024 * 1024, # 10MB
|
242
|
+
'backupCount': 3,
|
243
|
+
'formatter': 'serializer',
|
244
|
+
},
|
245
|
+
},
|
246
|
+
'loggers': {
|
247
|
+
'optimized_serializer': {
|
248
|
+
'handlers': ['serializer_file'],
|
249
|
+
'level': 'INFO',
|
250
|
+
'propagate': True,
|
251
|
+
},
|
252
|
+
'serializer_manager': {
|
253
|
+
'handlers': ['serializer_file'],
|
254
|
+
'level': 'INFO',
|
255
|
+
'propagate': True,
|
256
|
+
},
|
257
|
+
'serializer_performance': {
|
258
|
+
'handlers': ['performance_file'],
|
259
|
+
'level': 'INFO',
|
260
|
+
'propagate': False,
|
261
|
+
},
|
262
|
+
},
|
263
|
+
}
|
264
|
+
|
265
|
+
# Merge serializer logging into main LOGGING configuration
|
266
|
+
# Note: In your actual settings.py, you would merge this into your existing LOGGING dict
|
267
|
+
|
268
|
+
# =============================================================================
|
269
|
+
# MIGRATION AND COMPATIBILITY
|
270
|
+
# =============================================================================
|
271
|
+
|
272
|
+
# Backwards compatibility settings
|
273
|
+
MOJO_SERIALIZER_COMPATIBILITY = {
|
274
|
+
# Support legacy GraphSerializer API
|
275
|
+
'legacy_graph_serializer_support': True,
|
276
|
+
|
277
|
+
# Automatically migrate from simple to optimized serializer
|
278
|
+
'auto_migrate_simple_to_optimized': True,
|
279
|
+
|
280
|
+
# Warn about deprecated serializer features
|
281
|
+
'deprecation_warnings': True,
|
282
|
+
|
283
|
+
# Fallback to simple serializer on errors
|
284
|
+
'fallback_on_errors': True
|
285
|
+
}
|
286
|
+
|
287
|
+
# =============================================================================
|
288
|
+
# EXAMPLE USAGE IN VIEWS/MODELS
|
289
|
+
# =============================================================================
|
290
|
+
|
291
|
+
"""
|
292
|
+
Example usage in your Django code:
|
293
|
+
|
294
|
+
# In views.py
|
295
|
+
from mojo.serializers import serialize, to_response
|
296
|
+
|
297
|
+
def my_api_view(request):
|
298
|
+
queryset = MyModel.objects.all()
|
299
|
+
|
300
|
+
# Use default configured serializer
|
301
|
+
return to_response(queryset, request, graph="list")
|
302
|
+
|
303
|
+
# Force specific serializer
|
304
|
+
return to_response(queryset, request, graph="list", serializer_type="optimized")
|
305
|
+
|
306
|
+
# In models.py
|
307
|
+
class MyModel(MojoModel):
|
308
|
+
name = models.CharField(max_length=100)
|
309
|
+
|
310
|
+
class RestMeta:
|
311
|
+
GRAPHS = {
|
312
|
+
"default": {"fields": ["id", "name"]},
|
313
|
+
"list": {"fields": ["id", "name"]},
|
314
|
+
"detail": {"fields": ["id", "name", "created", "modified"]}
|
315
|
+
}
|
316
|
+
|
317
|
+
# Management commands
|
318
|
+
# python manage.py serializer_admin list
|
319
|
+
# python manage.py serializer_admin benchmark --model MyModel --count 1000
|
320
|
+
# python manage.py serializer_admin stats
|
321
|
+
# python manage.py serializer_admin clear-cache
|
322
|
+
"""
|
@@ -1,9 +1,11 @@
|
|
1
1
|
import ujson
|
2
|
-
from django.db.models import ForeignKey, OneToOneField
|
2
|
+
from django.db.models import ForeignKey, OneToOneField, ManyToOneRel
|
3
3
|
from django.db.models.query import QuerySet
|
4
|
+
from django.core.exceptions import FieldDoesNotExist
|
4
5
|
from django.http import HttpResponse
|
5
6
|
import datetime
|
6
7
|
from mojo.helpers import logit
|
8
|
+
from distutils.log import info
|
7
9
|
|
8
10
|
logger = logit.get_logger("serializer", "serializer.log")
|
9
11
|
|
@@ -66,46 +68,64 @@ class GraphSerializer:
|
|
66
68
|
method_name, alias = field
|
67
69
|
else:
|
68
70
|
method_name, alias = field, field
|
71
|
+
logger.info(f"Processing extra field {method_name} for {obj.__class__.__name__}")
|
69
72
|
if hasattr(obj, method_name):
|
70
73
|
attr = getattr(obj, method_name)
|
71
74
|
data[alias] = attr() if callable(attr) else attr
|
75
|
+
logger.info(f"Extra field {method_name} processed successfully", data[alias])
|
76
|
+
else:
|
77
|
+
logger.warning(f"Extra field {method_name} not found for {obj.__class__.__name__}")
|
72
78
|
|
73
|
-
# Process related model graphs (ForeignKeys, OneToOneFields)
|
79
|
+
# Process related model graphs (ForeignKeys, OneToOneFields, ManyToManyFields)
|
74
80
|
related_graphs = graph_config.get("graphs", {})
|
75
81
|
for related_field, sub_graph in related_graphs.items():
|
76
82
|
related_obj = getattr(obj, related_field, None)
|
77
83
|
if related_obj is not None:
|
78
|
-
# Determine if the field is a ForeignKey or
|
84
|
+
# Determine if the field is a ForeignKey, OneToOneField, or ManyToManyField
|
79
85
|
field_obj = obj._meta.get_field(related_field)
|
80
86
|
if isinstance(field_obj, (ForeignKey, OneToOneField)):
|
81
87
|
# Serialize related model using its corresponding graph
|
82
88
|
logger.warning(f"graph '{sub_graph}' for {related_obj.__class__.__name__}")
|
83
89
|
data[related_field] = GraphSerializer(related_obj, graph=sub_graph).serialize()
|
84
|
-
|
90
|
+
elif isinstance(field_obj, ManyToOneRel):
|
91
|
+
# Serialize related models in ManyToManyField
|
92
|
+
logger.warning(f"graph '{sub_graph}' for many to many relation {related_obj.model.__name__}")
|
93
|
+
m2m_qset = related_obj.all()
|
94
|
+
data[related_field] = GraphSerializer(m2m_qset, graph=sub_graph).serialize()
|
95
|
+
else:
|
96
|
+
logger.warning(f"Unsupported field type for {related_field}: {type(field_obj)}")
|
85
97
|
return data
|
86
98
|
|
99
|
+
def get_model_field(self, model_class, field_name):
|
100
|
+
try:
|
101
|
+
return model_class._meta.get_field(field_name)
|
102
|
+
except FieldDoesNotExist:
|
103
|
+
return None
|
104
|
+
|
87
105
|
def _model_to_dict_custom(self, obj, fields=None):
|
88
106
|
"""
|
89
107
|
Custom serialization method for Django model instances.
|
90
108
|
"""
|
91
109
|
data = {}
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
field_value
|
110
|
+
if fields is None:
|
111
|
+
fields = [field.name for field in obj._meta.fields]
|
112
|
+
for name in fields:
|
113
|
+
field_value = getattr(obj, name)
|
114
|
+
field = self.get_model_field(obj, name)
|
115
|
+
# Check if the field_value is callable and call it to get the value
|
116
|
+
if callable(field_value):
|
117
|
+
field_value = field_value()
|
98
118
|
|
99
119
|
# Handle DateTimeField serialization to epoch
|
100
120
|
if isinstance(field_value, datetime.datetime):
|
101
|
-
data[
|
121
|
+
data[name] = int(field_value.timestamp())
|
102
122
|
# Handle date serialization to ISO format
|
103
123
|
elif isinstance(field_value, datetime.date):
|
104
|
-
data[
|
124
|
+
data[name] = field_value.isoformat()
|
105
125
|
elif field_value is not None and isinstance(field, (ForeignKey, OneToOneField)):
|
106
|
-
data[
|
126
|
+
data[name] = field_value.id
|
107
127
|
else:
|
108
|
-
data[
|
128
|
+
data[name] = field_value
|
109
129
|
# logger.info(data)
|
110
130
|
return data
|
111
131
|
|
@@ -118,7 +138,10 @@ class GraphSerializer:
|
|
118
138
|
else:
|
119
139
|
data = dict(data=data, status=True, graph=self.graph)
|
120
140
|
data.update(dict(kwargs))
|
121
|
-
|
141
|
+
try:
|
142
|
+
out = ujson.dumps(data)
|
143
|
+
except Exception as e:
|
144
|
+
logger.exception(data)
|
122
145
|
return out
|
123
146
|
|
124
147
|
def to_response(self, request, **kwargs):
|
testit/helpers.py
CHANGED
@@ -131,8 +131,7 @@ def unit_test(name=None):
|
|
131
131
|
return decorator
|
132
132
|
|
133
133
|
|
134
|
-
|
135
|
-
def django_unit_test(name=None):
|
134
|
+
def django_unit_test(arg=None):
|
136
135
|
"""
|
137
136
|
Decorator to track unit test execution.
|
138
137
|
|
@@ -148,9 +147,27 @@ def django_unit_test(name=None):
|
|
148
147
|
import django
|
149
148
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings')
|
150
149
|
django.setup()
|
151
|
-
|
150
|
+
|
151
|
+
test_name = getattr(wrapper, '_test_name', None)
|
152
|
+
if test_name is None:
|
153
|
+
# Strip 'test_' if it exists
|
154
|
+
test_name = func.__name__
|
155
|
+
if test_name.startswith('test_'):
|
156
|
+
test_name = test_name[5:]
|
157
|
+
|
158
|
+
_run_unit(func, test_name, *args, **kwargs)
|
159
|
+
|
160
|
+
# Store the custom test name if provided
|
161
|
+
if isinstance(arg, str):
|
162
|
+
wrapper._test_name = arg
|
152
163
|
return wrapper
|
153
|
-
|
164
|
+
|
165
|
+
if callable(arg):
|
166
|
+
# Used as @django_unit_test with no arguments
|
167
|
+
return decorator(arg)
|
168
|
+
else:
|
169
|
+
# Used as @django_unit_test("name") or @django_unit_test()
|
170
|
+
return decorator
|
154
171
|
|
155
172
|
|
156
173
|
def get_mock_request(user=None, ip="127.0.0.1", path='/', method='GET', META=None):
|
@@ -1,96 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.3
|
2
|
-
Name: django-nativemojo
|
3
|
-
Version: 0.1.10
|
4
|
-
Summary: A REST framework for DJANGO with some extra apps that make it easy to provide a secure robust graph like RESIT API.
|
5
|
-
License: MIT
|
6
|
-
Author: MOJO Dev Team
|
7
|
-
Author-email: gotmojo@nativemojo.com
|
8
|
-
Requires-Python: >=3.9,<4.0
|
9
|
-
Classifier: License :: OSI Approved :: MIT License
|
10
|
-
Classifier: Programming Language :: Python :: 3
|
11
|
-
Classifier: Programming Language :: Python :: 3.9
|
12
|
-
Classifier: Programming Language :: Python :: 3.10
|
13
|
-
Classifier: Programming Language :: Python :: 3.11
|
14
|
-
Classifier: Programming Language :: Python :: 3.12
|
15
|
-
Classifier: Programming Language :: Python :: 3.13
|
16
|
-
Requires-Dist: django (>=4.2.18,<6.0.0)
|
17
|
-
Requires-Dist: django-cors-headers (>=4.7.0,<5.0.0)
|
18
|
-
Requires-Dist: faker (>=35.2.0,<36.0.0)
|
19
|
-
Requires-Dist: gevent (>=25.5.1,<26.0.0)
|
20
|
-
Requires-Dist: pycryptodome (>=3.21.0,<4.0.0)
|
21
|
-
Requires-Dist: pyjwt (>=2.10.1,<3.0.0)
|
22
|
-
Requires-Dist: pyobjict (>=2.0.2,<4.0.0)
|
23
|
-
Requires-Dist: pytz (>=2025.1,<2026.0)
|
24
|
-
Requires-Dist: redis (>=3.5.3,<6.0.0)
|
25
|
-
Requires-Dist: requests (>=2.32.3,<3.0.0)
|
26
|
-
Requires-Dist: ua-parser (>=1.0.1,<2.0.0)
|
27
|
-
Requires-Dist: ujson (>=5.10.0,<6.0.0)
|
28
|
-
Description-Content-Type: text/markdown
|
29
|
-
|
30
|
-
# Django-MOJO Documentation
|
31
|
-
|
32
|
-
Django-MOJO is a streamlined set of Django applications and a lightweight REST framework designed to simplify user authentication, authorization, and efficient API testing. This documentation provides descriptions and examples to help you get started quickly.
|
33
|
-
|
34
|
-
## Why Django-MOJO?
|
35
|
-
|
36
|
-
We built Django-MOJO to address the complexity and overhead of existing REST frameworks. Many frameworks are feature-heavy, making them cumbersome for projects that require simplicity, speed, and robust security.
|
37
|
-
|
38
|
-
## Key Differentiators
|
39
|
-
|
40
|
-
- **Lightweight Framework:** Django-MOJO is minimalistic, providing an easy way to add REST APIs to your Django models without unnecessary complexity.
|
41
|
-
- **Built-in Security:** Security is integral to Django-MOJO. We offer an alternative to Django's built-in permissions system, automatically protecting your REST APIs and data.
|
42
|
-
- **Robust Object-Level Permission System:** Unlike Django's native model-level permissions, Django-MOJO provides a simple yet robust permission system at the object level. This allows fine-grained control, enabling permissions to be applied to individual objects and extended to both user and group levels.
|
43
|
-
- **Effortless Integration:** Adding REST endpoints to your models is straightforward, enabling rapid development without compromising security or performance.
|
44
|
-
|
45
|
-
With Django-MOJO, you get a simple, efficient framework with powerful security features designed for developers who value speed and control.
|
46
|
-
|
47
|
-
## Table of Contents
|
48
|
-
|
49
|
-
1. [Overview](#overview)
|
50
|
-
2. [Installation](#installation)
|
51
|
-
3. [MOJO.Auth - Authentication and Authorization](#mojo-auth)
|
52
|
-
- [JWT Authentication Middleware](#jwt-authentication)
|
53
|
-
- [Models](#models)
|
54
|
-
- [REST API](#mojo-auth-rest-api)
|
55
|
-
4. [MOJO - REST Framework](#mojo)
|
56
|
-
- [URL Decorators](#url-decorators)
|
57
|
-
- [GraphSerializer](#graphserializer)
|
58
|
-
5. [Testit - Testing Suite](#testit)
|
59
|
-
- [Writing Tests](#writing-tests)
|
60
|
-
- [Running Tests](#running-tests)
|
61
|
-
6. [Taskit - Task Runner](#taskit)
|
62
|
-
7. [Utilities](#utilities)
|
63
|
-
8. [Contributing](#contributing)
|
64
|
-
9. [License](#license)
|
65
|
-
|
66
|
-
## Overview
|
67
|
-
|
68
|
-
Django-MOJO is a collection of Django-based applications focused on authentication, task management, and testing. These tools are built to enhance development efficiency by providing utilities for common requirements such as user management, token-based authentication, and automated testing.
|
69
|
-
|
70
|
-
## Installation
|
71
|
-
|
72
|
-
```bash
|
73
|
-
pip install django-nativemojo
|
74
|
-
```
|
75
|
-
|
76
|
-
## Detailed Documentation
|
77
|
-
|
78
|
-
For detailed information about each module and its usage, refer to the documentation within the `docs` folder:
|
79
|
-
|
80
|
-
- [MOJO Auth Documentation](docs/auth.md): Authentication and authorization management with JWT support.
|
81
|
-
- [MOJO REST Documentation](docs/rest.md): Provides RESTful API capabilities for Django models.
|
82
|
-
- [MOJO Testing Documentation](docs/testit.md): Offers tools and utilities for testing Django applications.
|
83
|
-
- [MOJO Tasks Documentation](docs/tasks.md): Handles task management and processing with Redis.
|
84
|
-
- [MOJO Decorators Documentation](docs/decorators.md): Describes decorators to enhance Django views with HTTP routing, validation, etc.
|
85
|
-
- [Helpers Documentation](docs/helpers.md): Lists various helper utilities for common tasks.
|
86
|
-
- [MOJO Metrics Documentation](docs/metrics.md): Details on recording and retrieving metrics using Redis.
|
87
|
-
- [Cron Scheduler Documentation](docs/cron.md): Explains task scheduling using a cron syntax.
|
88
|
-
|
89
|
-
## Contributing
|
90
|
-
|
91
|
-
We welcome contributions! Please create an issue or submit a pull request on the GitHub repository.
|
92
|
-
|
93
|
-
## License
|
94
|
-
|
95
|
-
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
96
|
-
|
mojo/apps/metrics/rest/db.py
DELETED
File without changes
|
mojo/helpers/aws/setup_email.py
DELETED
File without changes
|