django-nativemojo 0.1.15__py3-none-any.whl → 0.1.17__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.
Files changed (221) hide show
  1. {django_nativemojo-0.1.15.dist-info → django_nativemojo-0.1.17.dist-info}/METADATA +3 -2
  2. django_nativemojo-0.1.17.dist-info/RECORD +302 -0
  3. mojo/__init__.py +1 -1
  4. mojo/apps/account/management/commands/serializer_admin.py +121 -1
  5. mojo/apps/account/migrations/0006_add_device_tracking_models.py +72 -0
  6. mojo/apps/account/migrations/0007_delete_userdevicelocation.py +16 -0
  7. mojo/apps/account/migrations/0008_userdevicelocation.py +33 -0
  8. mojo/apps/account/migrations/0009_geolocatedip_subnet.py +18 -0
  9. mojo/apps/account/migrations/0010_group_avatar.py +20 -0
  10. mojo/apps/account/migrations/0011_user_org_registereddevice_pushconfig_and_more.py +118 -0
  11. mojo/apps/account/migrations/0012_remove_pushconfig_apns_key_file_and_more.py +21 -0
  12. mojo/apps/account/migrations/0013_pushconfig_test_mode_alter_pushconfig_apns_enabled_and_more.py +28 -0
  13. mojo/apps/account/migrations/0014_notificationdelivery_data_payload_and_more.py +48 -0
  14. mojo/apps/account/models/__init__.py +2 -0
  15. mojo/apps/account/models/device.py +279 -0
  16. mojo/apps/account/models/group.py +294 -8
  17. mojo/apps/account/models/member.py +14 -1
  18. mojo/apps/account/models/push/__init__.py +4 -0
  19. mojo/apps/account/models/push/config.py +112 -0
  20. mojo/apps/account/models/push/delivery.py +93 -0
  21. mojo/apps/account/models/push/device.py +66 -0
  22. mojo/apps/account/models/push/template.py +99 -0
  23. mojo/apps/account/models/user.py +190 -17
  24. mojo/apps/account/rest/__init__.py +2 -0
  25. mojo/apps/account/rest/device.py +39 -0
  26. mojo/apps/account/rest/group.py +8 -0
  27. mojo/apps/account/rest/push.py +187 -0
  28. mojo/apps/account/rest/user.py +95 -5
  29. mojo/apps/account/services/__init__.py +1 -0
  30. mojo/apps/account/services/push.py +363 -0
  31. mojo/apps/aws/migrations/0001_initial.py +206 -0
  32. mojo/apps/aws/migrations/0002_emaildomain_can_recv_emaildomain_can_send_and_more.py +28 -0
  33. mojo/apps/aws/migrations/0003_mailbox_is_domain_default_mailbox_is_system_default_and_more.py +31 -0
  34. mojo/apps/aws/migrations/0004_s3bucket.py +39 -0
  35. mojo/apps/aws/migrations/0005_alter_emaildomain_region_delete_s3bucket.py +21 -0
  36. mojo/apps/aws/models/__init__.py +19 -0
  37. mojo/apps/aws/models/email_attachment.py +99 -0
  38. mojo/apps/aws/models/email_domain.py +218 -0
  39. mojo/apps/aws/models/email_template.py +132 -0
  40. mojo/apps/aws/models/incoming_email.py +197 -0
  41. mojo/apps/aws/models/mailbox.py +288 -0
  42. mojo/apps/aws/models/sent_message.py +175 -0
  43. mojo/apps/aws/rest/__init__.py +6 -0
  44. mojo/apps/aws/rest/email.py +33 -0
  45. mojo/apps/aws/rest/email_ops.py +183 -0
  46. mojo/apps/aws/rest/messages.py +32 -0
  47. mojo/apps/aws/rest/send.py +101 -0
  48. mojo/apps/aws/rest/sns.py +403 -0
  49. mojo/apps/aws/rest/templates.py +19 -0
  50. mojo/apps/aws/services/__init__.py +32 -0
  51. mojo/apps/aws/services/email.py +390 -0
  52. mojo/apps/aws/services/email_ops.py +548 -0
  53. mojo/apps/docit/__init__.py +6 -0
  54. mojo/apps/docit/markdown_plugins/syntax_highlight.py +25 -0
  55. mojo/apps/docit/markdown_plugins/toc.py +12 -0
  56. mojo/apps/docit/migrations/0001_initial.py +113 -0
  57. mojo/apps/docit/migrations/0002_alter_book_modified_by_alter_page_modified_by.py +26 -0
  58. mojo/apps/docit/migrations/0003_alter_book_group.py +20 -0
  59. mojo/apps/docit/models/__init__.py +17 -0
  60. mojo/apps/docit/models/asset.py +231 -0
  61. mojo/apps/docit/models/book.py +227 -0
  62. mojo/apps/docit/models/page.py +319 -0
  63. mojo/apps/docit/models/page_revision.py +203 -0
  64. mojo/apps/docit/rest/__init__.py +10 -0
  65. mojo/apps/docit/rest/asset.py +17 -0
  66. mojo/apps/docit/rest/book.py +22 -0
  67. mojo/apps/docit/rest/page.py +22 -0
  68. mojo/apps/docit/rest/page_revision.py +17 -0
  69. mojo/apps/docit/services/__init__.py +11 -0
  70. mojo/apps/docit/services/docit.py +315 -0
  71. mojo/apps/docit/services/markdown.py +44 -0
  72. mojo/apps/fileman/backends/s3.py +209 -0
  73. mojo/apps/fileman/models/file.py +45 -9
  74. mojo/apps/fileman/models/manager.py +269 -3
  75. mojo/apps/incident/migrations/0007_event_uid.py +18 -0
  76. mojo/apps/incident/migrations/0008_ticket_ticketnote.py +55 -0
  77. mojo/apps/incident/migrations/0009_incident_status.py +18 -0
  78. mojo/apps/incident/migrations/0010_event_country_code.py +18 -0
  79. mojo/apps/incident/migrations/0011_incident_country_code.py +18 -0
  80. mojo/apps/incident/migrations/0012_alter_incident_status.py +18 -0
  81. mojo/apps/incident/models/__init__.py +1 -0
  82. mojo/apps/incident/models/event.py +35 -0
  83. mojo/apps/incident/models/incident.py +2 -0
  84. mojo/apps/incident/models/ticket.py +62 -0
  85. mojo/apps/incident/reporter.py +21 -3
  86. mojo/apps/incident/rest/__init__.py +1 -0
  87. mojo/apps/incident/rest/ticket.py +43 -0
  88. mojo/apps/jobs/__init__.py +489 -0
  89. mojo/apps/jobs/adapters.py +24 -0
  90. mojo/apps/jobs/cli.py +616 -0
  91. mojo/apps/jobs/daemon.py +370 -0
  92. mojo/apps/jobs/examples/sample_jobs.py +376 -0
  93. mojo/apps/jobs/examples/webhook_examples.py +203 -0
  94. mojo/apps/jobs/handlers/__init__.py +5 -0
  95. mojo/apps/jobs/handlers/webhook.py +317 -0
  96. mojo/apps/jobs/job_engine.py +734 -0
  97. mojo/apps/jobs/keys.py +203 -0
  98. mojo/apps/jobs/local_queue.py +363 -0
  99. mojo/apps/jobs/management/__init__.py +3 -0
  100. mojo/apps/jobs/management/commands/__init__.py +3 -0
  101. mojo/apps/jobs/manager.py +1327 -0
  102. mojo/apps/jobs/migrations/0001_initial.py +97 -0
  103. mojo/apps/jobs/migrations/0002_alter_job_max_retries_joblog.py +39 -0
  104. mojo/apps/jobs/models/__init__.py +6 -0
  105. mojo/apps/jobs/models/job.py +441 -0
  106. mojo/apps/jobs/rest/__init__.py +2 -0
  107. mojo/apps/jobs/rest/control.py +466 -0
  108. mojo/apps/jobs/rest/jobs.py +421 -0
  109. mojo/apps/jobs/scheduler.py +571 -0
  110. mojo/apps/jobs/services/__init__.py +6 -0
  111. mojo/apps/jobs/services/job_actions.py +465 -0
  112. mojo/apps/jobs/settings.py +209 -0
  113. mojo/apps/logit/models/log.py +3 -0
  114. mojo/apps/metrics/__init__.py +8 -1
  115. mojo/apps/metrics/redis_metrics.py +198 -0
  116. mojo/apps/metrics/rest/__init__.py +3 -0
  117. mojo/apps/metrics/rest/categories.py +266 -0
  118. mojo/apps/metrics/rest/helpers.py +48 -0
  119. mojo/apps/metrics/rest/permissions.py +99 -0
  120. mojo/apps/metrics/rest/values.py +277 -0
  121. mojo/apps/metrics/utils.py +17 -0
  122. mojo/decorators/http.py +40 -1
  123. mojo/helpers/aws/__init__.py +11 -7
  124. mojo/helpers/aws/inbound_email.py +309 -0
  125. mojo/helpers/aws/kms.py +413 -0
  126. mojo/helpers/aws/ses_domain.py +959 -0
  127. mojo/helpers/crypto/__init__.py +1 -1
  128. mojo/helpers/crypto/utils.py +15 -0
  129. mojo/helpers/location/__init__.py +2 -0
  130. mojo/helpers/location/countries.py +262 -0
  131. mojo/helpers/location/geolocation.py +196 -0
  132. mojo/helpers/logit.py +37 -0
  133. mojo/helpers/redis/__init__.py +2 -0
  134. mojo/helpers/redis/adapter.py +606 -0
  135. mojo/helpers/redis/client.py +48 -0
  136. mojo/helpers/redis/pool.py +225 -0
  137. mojo/helpers/request.py +8 -0
  138. mojo/helpers/response.py +8 -0
  139. mojo/middleware/auth.py +1 -1
  140. mojo/middleware/cors.py +40 -0
  141. mojo/middleware/logging.py +131 -12
  142. mojo/middleware/mojo.py +5 -0
  143. mojo/models/rest.py +271 -57
  144. mojo/models/secrets.py +86 -0
  145. mojo/serializers/__init__.py +16 -10
  146. mojo/serializers/core/__init__.py +90 -0
  147. mojo/serializers/core/cache/__init__.py +121 -0
  148. mojo/serializers/core/cache/backends.py +518 -0
  149. mojo/serializers/core/cache/base.py +102 -0
  150. mojo/serializers/core/cache/disabled.py +181 -0
  151. mojo/serializers/core/cache/memory.py +287 -0
  152. mojo/serializers/core/cache/redis.py +533 -0
  153. mojo/serializers/core/cache/utils.py +454 -0
  154. mojo/serializers/{manager.py → core/manager.py} +53 -4
  155. mojo/serializers/core/serializer.py +475 -0
  156. mojo/serializers/{advanced/formats → formats}/csv.py +116 -139
  157. mojo/serializers/suggested_improvements.md +388 -0
  158. testit/client.py +1 -1
  159. testit/helpers.py +14 -0
  160. testit/runner.py +23 -6
  161. django_nativemojo-0.1.15.dist-info/RECORD +0 -234
  162. mojo/apps/notify/README.md +0 -91
  163. mojo/apps/notify/README_NOTIFICATIONS.md +0 -566
  164. mojo/apps/notify/admin.py +0 -52
  165. mojo/apps/notify/handlers/example_handlers.py +0 -516
  166. mojo/apps/notify/handlers/ses/__init__.py +0 -25
  167. mojo/apps/notify/handlers/ses/complaint.py +0 -25
  168. mojo/apps/notify/handlers/ses/message.py +0 -86
  169. mojo/apps/notify/management/commands/__init__.py +0 -1
  170. mojo/apps/notify/management/commands/process_notifications.py +0 -370
  171. mojo/apps/notify/mod +0 -0
  172. mojo/apps/notify/models/__init__.py +0 -12
  173. mojo/apps/notify/models/account.py +0 -128
  174. mojo/apps/notify/models/attachment.py +0 -24
  175. mojo/apps/notify/models/bounce.py +0 -68
  176. mojo/apps/notify/models/complaint.py +0 -40
  177. mojo/apps/notify/models/inbox.py +0 -113
  178. mojo/apps/notify/models/inbox_message.py +0 -173
  179. mojo/apps/notify/models/outbox.py +0 -129
  180. mojo/apps/notify/models/outbox_message.py +0 -288
  181. mojo/apps/notify/models/template.py +0 -30
  182. mojo/apps/notify/providers/aws.py +0 -73
  183. mojo/apps/notify/rest/ses.py +0 -0
  184. mojo/apps/notify/utils/__init__.py +0 -2
  185. mojo/apps/notify/utils/notifications.py +0 -404
  186. mojo/apps/notify/utils/parsing.py +0 -202
  187. mojo/apps/notify/utils/render.py +0 -144
  188. mojo/apps/tasks/README.md +0 -118
  189. mojo/apps/tasks/__init__.py +0 -44
  190. mojo/apps/tasks/manager.py +0 -644
  191. mojo/apps/tasks/rest/__init__.py +0 -2
  192. mojo/apps/tasks/rest/hooks.py +0 -0
  193. mojo/apps/tasks/rest/tasks.py +0 -76
  194. mojo/apps/tasks/runner.py +0 -439
  195. mojo/apps/tasks/task.py +0 -99
  196. mojo/apps/tasks/tq_handlers.py +0 -132
  197. mojo/helpers/crypto/__pycache__/hash.cpython-310.pyc +0 -0
  198. mojo/helpers/crypto/__pycache__/sign.cpython-310.pyc +0 -0
  199. mojo/helpers/crypto/__pycache__/utils.cpython-310.pyc +0 -0
  200. mojo/helpers/redis.py +0 -10
  201. mojo/models/meta.py +0 -262
  202. mojo/serializers/advanced/README.md +0 -363
  203. mojo/serializers/advanced/__init__.py +0 -247
  204. mojo/serializers/advanced/formats/__init__.py +0 -28
  205. mojo/serializers/advanced/formats/excel.py +0 -516
  206. mojo/serializers/advanced/formats/json.py +0 -239
  207. mojo/serializers/advanced/formats/response.py +0 -485
  208. mojo/serializers/advanced/serializer.py +0 -568
  209. mojo/serializers/optimized.py +0 -618
  210. {django_nativemojo-0.1.15.dist-info → django_nativemojo-0.1.17.dist-info}/LICENSE +0 -0
  211. {django_nativemojo-0.1.15.dist-info → django_nativemojo-0.1.17.dist-info}/NOTICE +0 -0
  212. {django_nativemojo-0.1.15.dist-info → django_nativemojo-0.1.17.dist-info}/WHEEL +0 -0
  213. /mojo/apps/{notify → aws/migrations}/__init__.py +0 -0
  214. /mojo/apps/{notify/handlers → docit/markdown_plugins}/__init__.py +0 -0
  215. /mojo/apps/{notify/management → docit/migrations}/__init__.py +0 -0
  216. /mojo/apps/{notify/providers → jobs/examples}/__init__.py +0 -0
  217. /mojo/apps/{notify/rest → jobs/migrations}/__init__.py +0 -0
  218. /mojo/{serializers → rest}/openapi.py +0 -0
  219. /mojo/serializers/{settings_example.py → examples/settings.py} +0 -0
  220. /mojo/{apps/notify/handlers/ses/bounce.py → serializers/formats/__init__.py} +0 -0
  221. /mojo/serializers/{advanced/formats → formats}/localizers.py +0 -0
@@ -1,363 +0,0 @@
1
- # Advanced Django Model Serializer
2
-
3
- A comprehensive serialization library for Django models and QuerySets with support for multiple output formats, performance optimizations, and advanced configuration through `RestMeta.GRAPHS`.
4
-
5
- ## Features
6
-
7
- - **RestMeta.GRAPHS Configuration**: Use declarative graph configurations for consistent serialization
8
- - **Multiple Output Formats**: JSON, CSV, Excel, HTML debug views
9
- - **Performance Optimizations**: Caching, select_related, streaming responses
10
- - **Nested Relationships**: Deep serialization of related models
11
- - **Custom Fields**: Support for methods, properties, and computed values
12
- - **Pagination & Sorting**: Built-in collection handling with pagination
13
- - **Localization**: Field-level formatting and localization
14
-
15
- ## Quick Start
16
-
17
- ### Basic Usage
18
-
19
- ```python
20
- from mojo.serializers.advanced import AdvancedGraphSerializer, CollectionSerializer
21
-
22
- # Serialize a single model instance
23
- user = User.objects.get(pk=1)
24
- serializer = AdvancedGraphSerializer(user, graph="detail")
25
- data = serializer.serialize()
26
-
27
- # Serialize a QuerySet
28
- users = User.objects.all()
29
- serializer = CollectionSerializer(users, graph="list", size=25)
30
- response_data = serializer.serialize()
31
-
32
- # Create HTTP response
33
- response = serializer.to_response(request)
34
- ```
35
-
36
- ### RestMeta.GRAPHS Configuration
37
-
38
- Define serialization graphs in your Django models:
39
-
40
- ```python
41
- class User(models.Model):
42
- name = models.CharField(max_length=100)
43
- email = models.EmailField()
44
- profile = models.OneToOneField('Profile', on_delete=models.CASCADE)
45
- posts = models.ForeignKey('Post', related_name='author')
46
- created = models.DateTimeField(auto_now_add=True)
47
-
48
- class RestMeta:
49
- GRAPHS = {
50
- "default": {
51
- "fields": ["id", "name", "email", "created"],
52
- },
53
- "list": {
54
- "fields": ["id", "name", "email"],
55
- "extra": [
56
- ("get_full_name", "full_name"), # Method with alias
57
- "post_count", # Property or method
58
- ]
59
- },
60
- "detail": {
61
- "fields": ["id", "name", "email", "created"],
62
- "extra": ["get_full_name", "is_active"],
63
- "graphs": {
64
- "profile": "summary", # Related object with sub-graph
65
- "posts": "list", # Related QuerySet
66
- }
67
- },
68
- "export": {
69
- "fields": ["id", "name", "email", "created"],
70
- "extra": [("profile.bio", "biography")], # Nested field access
71
- }
72
- }
73
-
74
- def get_full_name(self):
75
- return f"{self.first_name} {self.last_name}"
76
-
77
- @property
78
- def post_count(self):
79
- return self.posts.count()
80
-
81
- class Profile(models.Model):
82
- user = models.OneToOneField(User, on_delete=models.CASCADE)
83
- bio = models.TextField()
84
- avatar = models.ImageField()
85
-
86
- class RestMeta:
87
- GRAPHS = {
88
- "summary": {
89
- "fields": ["bio"],
90
- "extra": ["avatar_url"]
91
- }
92
- }
93
-
94
- def avatar_url(self):
95
- return self.avatar.url if self.avatar else None
96
- ```
97
-
98
- ## Advanced Usage
99
-
100
- ### Multiple Output Formats
101
-
102
- ```python
103
- from mojo.serializers.advanced import (
104
- serialize, to_response, to_csv_response, to_excel_response
105
- )
106
-
107
- # Auto-detect format from request
108
- def user_list_view(request):
109
- users = User.objects.all()
110
- return to_response(users, graph="list", request=request)
111
-
112
- # Force specific formats
113
- def user_csv_export(request):
114
- users = User.objects.all()
115
- return to_csv_response(
116
- users,
117
- fields=["name", "email", "created"],
118
- filename="users.csv",
119
- request=request
120
- )
121
-
122
- def user_excel_export(request):
123
- users = User.objects.all()
124
- return to_excel_response(
125
- users,
126
- graph="export",
127
- filename="users.xlsx",
128
- request=request
129
- )
130
- ```
131
-
132
- ### Performance Optimizations
133
-
134
- ```python
135
- # Automatic select_related for foreign keys
136
- users = User.objects.all() # Will auto-add select_related('profile')
137
- serializer = AdvancedGraphSerializer(users, graph="detail", many=True)
138
-
139
- # Caching for repeated serialization
140
- cache = {}
141
- for user in users:
142
- data = AdvancedGraphSerializer(user, graph="detail", cache=cache).serialize()
143
-
144
- # Streaming responses for large datasets
145
- def large_export(request):
146
- large_queryset = User.objects.all() # 100k+ records
147
- return to_csv_response(
148
- large_queryset,
149
- fields=["name", "email"],
150
- filename="all_users.csv",
151
- stream=True # Enables streaming
152
- )
153
- ```
154
-
155
- ### Collection Serialization with Pagination
156
-
157
- ```python
158
- from mojo.serializers.advanced import CollectionSerializer
159
-
160
- def paginated_users(request):
161
- users = User.objects.all()
162
-
163
- serializer = CollectionSerializer(
164
- users,
165
- graph="list",
166
- size=request.GET.get('size', 25),
167
- start=request.GET.get('start', 0),
168
- sort=request.GET.get('sort', 'name'),
169
- request=request
170
- )
171
-
172
- return serializer.to_response()
173
-
174
- # Response format:
175
- {
176
- "data": [...],
177
- "status": true,
178
- "count": 1500,
179
- "size": 25,
180
- "start": 0,
181
- "sort": ["name"],
182
- "graph": "list",
183
- "datetime": 1640995200
184
- }
185
- ```
186
-
187
- ### Custom Localization
188
-
189
- ```python
190
- from mojo.serializers.advanced.formats.localizers import register_localizer
191
-
192
- # Register custom localizer
193
- @register_localizer('currency_eur')
194
- def format_euro(value, extra=None):
195
- return f"€{value:.2f}"
196
-
197
- # Use in CSV/Excel export
198
- csv_response = to_csv_response(
199
- Product.objects.all(),
200
- fields=['name', 'price'],
201
- localize={'price': 'currency_eur'},
202
- filename='products.csv'
203
- )
204
- ```
205
-
206
- ### Response Helpers
207
-
208
- ```python
209
- from mojo.serializers.advanced import (
210
- rest_success, rest_error, rest_not_found, rest_permission_denied
211
- )
212
-
213
- def api_view(request):
214
- try:
215
- user = User.objects.get(pk=request.GET['id'])
216
- data = serialize(user, graph="detail")
217
- return rest_success(request, data)
218
- except User.DoesNotExist:
219
- return rest_not_found(request, "User not found")
220
- except PermissionError:
221
- return rest_permission_denied(request, "Access denied")
222
- except Exception as e:
223
- return rest_error(request, str(e))
224
- ```
225
-
226
- ## Configuration Options
227
-
228
- ### Serializer Options
229
-
230
- ```python
231
- serializer = AdvancedGraphSerializer(
232
- instance=user,
233
- graph="detail", # Graph configuration to use
234
- many=False, # Whether serializing multiple objects
235
- request=request, # Django request for context
236
- cache={}, # Shared cache for performance
237
- format="json" # Output format hint
238
- )
239
- ```
240
-
241
- ### Collection Options
242
-
243
- ```python
244
- serializer = CollectionSerializer(
245
- queryset=users,
246
- graph="list", # Graph configuration
247
- size=25, # Page size
248
- start=0, # Start offset
249
- sort="name,-created", # Sort fields (- for descending)
250
- format="json", # Output format
251
- request=request # Django request
252
- )
253
- ```
254
-
255
- ### Export Options
256
-
257
- ```python
258
- # CSV Export
259
- csv_response = to_csv_response(
260
- queryset,
261
- fields=['name', 'email'], # Fields to include
262
- filename='export.csv', # Download filename
263
- headers=['Name', 'Email'], # Custom column headers
264
- localize={'date': 'date|%Y-%m-%d'}, # Field localization
265
- stream=True # Enable streaming for large datasets
266
- )
267
-
268
- # Excel Export
269
- excel_response = to_excel_response(
270
- queryset,
271
- fields=['name', 'email', 'created'],
272
- filename='export.xlsx',
273
- sheet_name='Users',
274
- freeze_panes=True, # Freeze header row
275
- auto_width=True # Auto-adjust column widths
276
- )
277
- ```
278
-
279
- ## Graph Configuration Reference
280
-
281
- ### Field Types
282
-
283
- ```python
284
- class RestMeta:
285
- GRAPHS = {
286
- "example": {
287
- # Basic model fields
288
- "fields": ["id", "name", "email"],
289
-
290
- # Extra fields (methods, properties, computed values)
291
- "extra": [
292
- "method_name", # Simple method/property
293
- ("method_name", "alias"), # Method with alias
294
- ("nested.field", "flat_name"), # Nested field access
295
- ],
296
-
297
- # Related object graphs
298
- "graphs": {
299
- "foreign_key_field": "sub_graph_name",
300
- "many_to_many_field": "list_graph",
301
- "reverse_fk": "related_graph"
302
- }
303
- }
304
- }
305
- ```
306
-
307
- ### Nested Field Access
308
-
309
- ```python
310
- # Access nested fields with dot notation
311
- "extra": [
312
- ("user.profile.bio", "biography"),
313
- ("metadata.category.name", "category"),
314
- ("settings.preferences.theme", "theme")
315
- ]
316
- ```
317
-
318
- ## Performance Tips
319
-
320
- 1. **Use select_related**: The serializer automatically applies `select_related()` for foreign keys in your graph
321
- 2. **Enable caching**: Pass a shared cache dictionary when serializing multiple related objects
322
- 3. **Stream large exports**: Set `stream=True` for CSV exports with >1000 records
323
- 4. **Optimize graphs**: Keep graph configurations focused - avoid over-fetching data
324
- 5. **Use pagination**: Always paginate large QuerySets with CollectionSerializer
325
-
326
- ## API Reference
327
-
328
- ### Core Classes
329
-
330
- - `AdvancedGraphSerializer`: Main serializer for single instances or lists
331
- - `CollectionSerializer`: Specialized serializer for QuerySets with pagination
332
- - `ResponseFormatter`: HTTP response handler for multiple formats
333
-
334
- ### Format Handlers
335
-
336
- - `JsonFormatter`: Enhanced JSON serialization with ujson support
337
- - `CsvFormatter`: CSV export with streaming support
338
- - `ExcelFormatter`: Excel export with openpyxl
339
- - `ResponseFormatter`: Multi-format HTTP response handler
340
-
341
- ### Convenience Functions
342
-
343
- - `serialize()`: Universal serialization function
344
- - `to_response()`: Quick HTTP response generation
345
- - `to_csv_response()`: CSV export response
346
- - `to_excel_response()`: Excel export response
347
-
348
- ### Response Helpers
349
-
350
- - `rest_success()`, `rest_error()`: Status responses
351
- - `rest_not_found()`, `rest_permission_denied()`: Error responses
352
- - `get_cached_count()`: Cached QuerySet counting
353
-
354
- ## Requirements
355
-
356
- - Django 3.2+
357
- - Python 3.8+
358
- - ujson (optional, for better JSON performance)
359
- - openpyxl (optional, for Excel export)
360
-
361
- ## License
362
-
363
- This project is part of the Django Mojo framework.
@@ -1,247 +0,0 @@
1
- """
2
- Advanced Django Model and QuerySet Serializer
3
-
4
- This module provides comprehensive serialization capabilities for Django models and QuerySets
5
- with support for:
6
-
7
- - RestMeta.GRAPHS configuration
8
- - Multiple output formats (JSON, CSV, Excel, HTML)
9
- - Nested relationships and custom fields
10
- - Performance optimizations with caching and select_related
11
- - Pagination and sorting for collections
12
- - Streaming responses for large datasets
13
- - Localization and field formatting
14
-
15
- Main Classes:
16
- AdvancedGraphSerializer: Serialize single model instances or lists
17
- CollectionSerializer: Serialize QuerySets with pagination and sorting
18
- ResponseFormatter: Handle HTTP responses in multiple formats
19
-
20
- Usage Examples:
21
- # Serialize a single model instance
22
- serializer = AdvancedGraphSerializer(user, graph="detail")
23
- data = serializer.serialize()
24
-
25
- # Serialize a QuerySet
26
- serializer = CollectionSerializer(User.objects.all(), graph="list")
27
- response = serializer.to_response(request)
28
-
29
- # Export to CSV
30
- csv_response = rest_csv(request, User.objects.all(), fields=['name', 'email'])
31
- """
32
-
33
- from .serializer import (
34
- AdvancedGraphSerializer,
35
- CollectionSerializer,
36
- serialize_model,
37
- serialize_collection,
38
- serialize_to_response,
39
- timeit
40
- )
41
-
42
- from .formats import (
43
- JsonFormatter,
44
- CsvFormatter,
45
- ExcelFormatter,
46
- ResponseFormatter,
47
- get_formatter
48
- )
49
-
50
- from .formats.json import (
51
- to_json,
52
- to_pretty_json,
53
- to_compact_json,
54
- ExtendedJSONEncoder
55
- )
56
-
57
- from .formats.csv import (
58
- generate_csv,
59
- generate_csv_stream,
60
- serialize_to_csv
61
- )
62
-
63
- from .formats.excel import (
64
- generate_excel,
65
- serialize_to_excel,
66
- create_multi_sheet_excel,
67
- qsetToExcel # Legacy compatibility
68
- )
69
-
70
- from .formats.response import (
71
- rest_status,
72
- rest_success,
73
- rest_error,
74
- rest_permission_denied,
75
- rest_not_found,
76
- rest_json,
77
- rest_csv,
78
- rest_excel,
79
- rest_html,
80
- get_cached_count,
81
- get_request_elapsed,
82
- )
83
-
84
- from .formats.localizers import (
85
- register_localizer,
86
- get_localizer,
87
- list_localizers,
88
- apply_localizer,
89
- localizer # decorator
90
- )
91
-
92
- # Version info
93
- __version__ = "2.0.0"
94
- __author__ = "Django Mojo Team"
95
-
96
- # Public API
97
- __all__ = [
98
- # Main serializer classes
99
- 'AdvancedGraphSerializer',
100
- 'CollectionSerializer',
101
-
102
- # Format handlers
103
- 'JsonFormatter',
104
- 'CsvFormatter',
105
- 'ExcelFormatter',
106
- 'ResponseFormatter',
107
-
108
- # Convenience functions
109
- 'serialize_model',
110
- 'serialize_collection',
111
- 'serialize_to_response',
112
- 'serialize_to_csv',
113
- 'serialize_to_excel',
114
-
115
- # JSON utilities
116
- 'to_json',
117
- 'to_pretty_json',
118
- 'to_compact_json',
119
- 'ExtendedJSONEncoder',
120
-
121
- # Export functions
122
- 'generate_csv',
123
- 'generate_csv_stream',
124
- 'generate_excel',
125
- 'create_multi_sheet_excel',
126
-
127
- # Response helpers
128
- 'rest_status',
129
- 'rest_success',
130
- 'rest_error',
131
- 'rest_permission_denied',
132
- 'rest_not_found',
133
- 'rest_json',
134
- 'rest_csv',
135
- 'rest_excel',
136
- 'rest_html',
137
-
138
- # Utilities
139
- 'get_cached_count',
140
- 'get_request_elapsed',
141
- 'get_formatter',
142
- 'timeit',
143
-
144
- # Localizers
145
- 'register_localizer',
146
- 'get_localizer',
147
- 'list_localizers',
148
- 'apply_localizer',
149
- 'localizer',
150
- ]
151
-
152
-
153
- # Convenience shortcuts for common use cases
154
- def serialize(instance, graph="default", many=None, request=None, format="json", **kwargs):
155
- """
156
- Universal serialization function that automatically chooses the right serializer.
157
-
158
- :param instance: Model instance, QuerySet, or list of objects
159
- :param graph: RestMeta graph name to use
160
- :param many: Force many=True for lists (auto-detected for QuerySets)
161
- :param request: Django request object
162
- :param format: Output format ('json', 'csv', 'excel', 'response')
163
- :param kwargs: Additional options
164
- :return: Serialized data or HttpResponse (if format='response')
165
- """
166
- from django.db.models import QuerySet
167
-
168
- # Auto-detect if we're dealing with a collection
169
- if isinstance(instance, QuerySet):
170
- if format == "response":
171
- return CollectionSerializer(instance, graph=graph, request=request, **kwargs).to_response()
172
- elif format in ["csv", "excel"]:
173
- formatter = ResponseFormatter(request)
174
- return formatter.format_response(instance, format, **kwargs)
175
- else:
176
- return CollectionSerializer(instance, graph=graph, request=request, **kwargs).serialize()
177
-
178
- elif isinstance(instance, (list, tuple)) or many:
179
- if format == "response":
180
- return AdvancedGraphSerializer(instance, graph=graph, many=True, request=request, **kwargs).to_response()
181
- elif format in ["csv", "excel"]:
182
- formatter = ResponseFormatter(request)
183
- return formatter.format_response(instance, format, **kwargs)
184
- else:
185
- return AdvancedGraphSerializer(instance, graph=graph, many=True, request=request, **kwargs).serialize()
186
-
187
- else:
188
- # Single instance
189
- if format == "response":
190
- return AdvancedGraphSerializer(instance, graph=graph, request=request, **kwargs).to_response()
191
- elif format in ["csv", "excel"]:
192
- formatter = ResponseFormatter(request)
193
- return formatter.format_response([instance], format, **kwargs)
194
- else:
195
- return AdvancedGraphSerializer(instance, graph=graph, request=request, **kwargs).serialize()
196
-
197
-
198
- def to_response(instance, graph="default", request=None, **kwargs):
199
- """
200
- Shortcut to serialize and return HTTP response.
201
-
202
- :param instance: Model instance, QuerySet, or list
203
- :param graph: RestMeta graph name
204
- :param request: Django request object
205
- :param kwargs: Additional options
206
- :return: HttpResponse
207
- """
208
- return serialize(instance, graph=graph, request=request, format="response", **kwargs)
209
-
210
-
211
- def to_csv_response(instance, fields=None, filename="export.csv", request=None, **kwargs):
212
- """
213
- Shortcut to export data as CSV response.
214
-
215
- :param instance: QuerySet or list of objects
216
- :param fields: Fields to include in CSV
217
- :param filename: Download filename
218
- :param request: Django request object
219
- :param kwargs: Additional options
220
- :return: HttpResponse with CSV file
221
- """
222
- formatter = ResponseFormatter(request)
223
- return formatter.format_response(instance, "csv", fields=fields, filename=filename, **kwargs)
224
-
225
-
226
- def to_excel_response(instance, fields=None, filename="export.xlsx", request=None, **kwargs):
227
- """
228
- Shortcut to export data as Excel response.
229
-
230
- :param instance: QuerySet or list of objects
231
- :param fields: Fields to include in Excel
232
- :param filename: Download filename
233
- :param request: Django request object
234
- :param kwargs: Additional options
235
- :return: HttpResponse with Excel file
236
- """
237
- formatter = ResponseFormatter(request)
238
- return formatter.format_response(instance, "excel", fields=fields, filename=filename, **kwargs)
239
-
240
-
241
- # Add shortcuts to __all__
242
- __all__.extend([
243
- 'serialize',
244
- 'to_response',
245
- 'to_csv_response',
246
- 'to_excel_response'
247
- ])
@@ -1,28 +0,0 @@
1
- """
2
- Format handlers for advanced serialization.
3
- Supports JSON, CSV, Excel, and other output formats.
4
- """
5
-
6
- from .json import JsonFormatter
7
- from .csv import CsvFormatter
8
- from .excel import ExcelFormatter
9
- from .response import ResponseFormatter
10
-
11
- __all__ = [
12
- 'JsonFormatter',
13
- 'CsvFormatter',
14
- 'ExcelFormatter',
15
- 'ResponseFormatter'
16
- ]
17
-
18
- # Default formatters
19
- DEFAULT_FORMATTERS = {
20
- 'json': JsonFormatter,
21
- 'csv': CsvFormatter,
22
- 'excel': ExcelFormatter,
23
- 'xlsx': ExcelFormatter,
24
- }
25
-
26
- def get_formatter(format_type):
27
- """Get formatter class for the specified format type."""
28
- return DEFAULT_FORMATTERS.get(format_type.lower())