djresttoolkit 0.9.0__py3-none-any.whl → 0.10.0__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.
README.md CHANGED
@@ -30,7 +30,7 @@ djresttoolkit is a collection of utilities and helpers for Django and Django RES
30
30
 
31
31
  ## 📚 All API Reference
32
32
 
33
- ### 1. DB Seed Utilities
33
+ ### 1. DB Seed Utilities — API Reference
34
34
 
35
35
  #### `Generator`
36
36
 
@@ -89,7 +89,7 @@ Here’s a **concise API reference** for your database flush management command
89
89
 
90
90
  ---
91
91
 
92
- ### 2. DB Flush Command
92
+ ### 2. DB Flush Command — API Reference
93
93
 
94
94
  ```python
95
95
  from djresttoolkit.management.commands import flush
@@ -145,7 +145,7 @@ or
145
145
  Flushed 120 records from all models and reset IDs.
146
146
  ```
147
147
 
148
- ### 3. EnvBaseSettings
148
+ ### 3. EnvBaseSettings — API Reference
149
149
 
150
150
  ```python
151
151
  from djresttoolkit.envconfig import EnvBaseSettings
@@ -200,7 +200,7 @@ Loads configuration from **YAML first**, then overrides with **environment varia
200
200
  ```python
201
201
  from djresttoolkit.envconfig import EnvBaseSettings
202
202
 
203
- class EnvSettings(EnvBaseSettings):
203
+ class EnvSettings(EnvBaseSettings["EnvSettings"]):
204
204
  debug: bool = False
205
205
  database_url: str
206
206
 
@@ -217,7 +217,7 @@ print(settings.database_url)
217
217
  - Supports nested keys: `DATABASE__HOST` → `settings.database.host`.
218
218
  - Designed to be subclassed for project-specific settings.
219
219
 
220
- ### 4. EmailSender
220
+ ### 4. EmailSender — API Reference
221
221
 
222
222
  ```python
223
223
  from djresttoolkit.mail import EmailSender, EmailContent, EmailTemplate
@@ -266,7 +266,7 @@ EmailSender(content).send(to=["user@example.com"])
266
266
 
267
267
  - `text`, `html` — template file paths
268
268
 
269
- ### 5. Custom DRF Exception Handler
269
+ ### 5. Custom DRF Exception Handler — API Reference
270
270
 
271
271
  ```python
272
272
  from djresttoolkit.views import exception_handler
@@ -306,7 +306,7 @@ REST_FRAMEWORK = {
306
306
  - Tracks requests in cache and calculates `retry_after`.
307
307
  - Cleans expired timestamps automatically.
308
308
 
309
- ### 6. Response Time Middleware
309
+ ### 6. Response Time Middleware — API Reference
310
310
 
311
311
  ```python
312
312
  from djresttoolkit.middlewares import ResponseTimeMiddleware
@@ -353,7 +353,7 @@ X-Response-Time: 0.01234 seconds
353
353
  INFO: Request processed in 0.01234 seconds
354
354
  ```
355
355
 
356
- ### 7. Throttle Utilities
356
+ ### 7. Throttle Utilities — API Reference
357
357
 
358
358
  #### `ThrottleInfoJSONRenderer`
359
359
 
@@ -469,6 +469,84 @@ data = serializer.data
469
469
  - Relative file paths are automatically converted to absolute URLs.
470
470
  - Can manually specify fields via `file_fields` for non-model serializers.
471
471
 
472
+ ### 9. BulkCreateMixin — API Reference
473
+
474
+ ```python
475
+ from djresttoolkit.serializers.mixins import BulkCreateMixin
476
+ ```
477
+
478
+ #### `BulkCreateMixin`
479
+
480
+ A **DRF serializer mixin** that adds support for:
481
+
482
+ - **Single instance creation** with extra context fields
483
+ - **Bulk creation** from a list of validated data dictionaries
484
+ - **Updating serializer field error messages** with model-specific messages
485
+
486
+ #### Bulk Create Mixin Notes
487
+
488
+ - `bulk_create()` does **not trigger model signals** or call `.save()` on instances.
489
+ - `Meta.model` **must** be defined in the serializer.
490
+
491
+ #### Bulk Create Mixin Methods
492
+
493
+ #### `create(self, validated_data: dict[str, Any] | list[dict[str, Any]]) -> Model | list[Model]`
494
+
495
+ - Creates single or multiple model instances.
496
+ - **Parameters:**
497
+ - `validated_data`: dict for single instance or list of dicts for bulk creation.
498
+
499
+ - **Returns:**
500
+ - Single model instance or list of instances.
501
+
502
+ - **Raises:**
503
+ - `AttributeError` if `Meta.model` is not defined.
504
+ - `NotImplementedError` if used with a serializer that does not implement `create()`.
505
+
506
+ #### `get_fields(self) -> dict[str, SerializerField]`
507
+
508
+ - Extends DRF serializer `get_fields()` to update **error messages** using model field definitions.
509
+ - **Returns:**
510
+ - Dictionary of serializer fields.
511
+
512
+ - **Warning:**
513
+ - Logs a warning if a serializer field is not present on the model.
514
+
515
+ ### Bulk Create Mixin Example
516
+
517
+ ```python
518
+ from rest_framework import serializers
519
+ from djresttoolkit.serializers.mixins import BulkCreateMixin
520
+ from myapp.models import Product
521
+
522
+ class ProductSerializer(BulkCreateMixin, serializers.ModelSerializer):
523
+ class Meta:
524
+ model = Product
525
+ fields = ["id", "name", "price"]
526
+
527
+ # Single creation
528
+ serializer = ProductSerializer(data={"name": "Item1", "price": 10})
529
+ serializer.is_valid(raise_exception=True)
530
+ product = serializer.save()
531
+
532
+ # Bulk creation
533
+ serializer = ProductSerializer(
534
+ data=[
535
+ {"name": "Item2", "price": 20},
536
+ {"name": "Item3", "price": 30},
537
+ ],
538
+ many=True
539
+ )
540
+ serializer.is_valid(raise_exception=True)
541
+ products = serializer.save()
542
+ ```
543
+
544
+ #### Bulk Create Mixin Features
545
+
546
+ - Works seamlessly with DRF `ModelSerializer`.
547
+ - Automatically updates field error messages based on Django model definitions.
548
+ - Bulk creation is optimized using `model.objects.bulk_create()` for efficiency.
549
+
472
550
  ## 🛠️ Planned Features
473
551
 
474
552
  - Add more utils
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: djresttoolkit
3
- Version: 0.9.0
3
+ Version: 0.10.0
4
4
  Summary: A collection of Django and DRF utilities to simplify API development.
5
5
  Project-URL: Homepage, https://github.com/shaileshpandit141/djresttoolkit
6
6
  Project-URL: Documentation, https://shaileshpandit141.github.io/djresttoolkit
@@ -88,7 +88,7 @@ djresttoolkit is a collection of utilities and helpers for Django and Django RES
88
88
 
89
89
  ## 📚 All API Reference
90
90
 
91
- ### 1. DB Seed Utilities
91
+ ### 1. DB Seed Utilities — API Reference
92
92
 
93
93
  #### `Generator`
94
94
 
@@ -147,7 +147,7 @@ Here’s a **concise API reference** for your database flush management command
147
147
 
148
148
  ---
149
149
 
150
- ### 2. DB Flush Command
150
+ ### 2. DB Flush Command — API Reference
151
151
 
152
152
  ```python
153
153
  from djresttoolkit.management.commands import flush
@@ -203,7 +203,7 @@ or
203
203
  Flushed 120 records from all models and reset IDs.
204
204
  ```
205
205
 
206
- ### 3. EnvBaseSettings
206
+ ### 3. EnvBaseSettings — API Reference
207
207
 
208
208
  ```python
209
209
  from djresttoolkit.envconfig import EnvBaseSettings
@@ -258,7 +258,7 @@ Loads configuration from **YAML first**, then overrides with **environment varia
258
258
  ```python
259
259
  from djresttoolkit.envconfig import EnvBaseSettings
260
260
 
261
- class EnvSettings(EnvBaseSettings):
261
+ class EnvSettings(EnvBaseSettings["EnvSettings"]):
262
262
  debug: bool = False
263
263
  database_url: str
264
264
 
@@ -275,7 +275,7 @@ print(settings.database_url)
275
275
  - Supports nested keys: `DATABASE__HOST` → `settings.database.host`.
276
276
  - Designed to be subclassed for project-specific settings.
277
277
 
278
- ### 4. EmailSender
278
+ ### 4. EmailSender — API Reference
279
279
 
280
280
  ```python
281
281
  from djresttoolkit.mail import EmailSender, EmailContent, EmailTemplate
@@ -324,7 +324,7 @@ EmailSender(content).send(to=["user@example.com"])
324
324
 
325
325
  - `text`, `html` — template file paths
326
326
 
327
- ### 5. Custom DRF Exception Handler
327
+ ### 5. Custom DRF Exception Handler — API Reference
328
328
 
329
329
  ```python
330
330
  from djresttoolkit.views import exception_handler
@@ -364,7 +364,7 @@ REST_FRAMEWORK = {
364
364
  - Tracks requests in cache and calculates `retry_after`.
365
365
  - Cleans expired timestamps automatically.
366
366
 
367
- ### 6. Response Time Middleware
367
+ ### 6. Response Time Middleware — API Reference
368
368
 
369
369
  ```python
370
370
  from djresttoolkit.middlewares import ResponseTimeMiddleware
@@ -411,7 +411,7 @@ X-Response-Time: 0.01234 seconds
411
411
  INFO: Request processed in 0.01234 seconds
412
412
  ```
413
413
 
414
- ### 7. Throttle Utilities
414
+ ### 7. Throttle Utilities — API Reference
415
415
 
416
416
  #### `ThrottleInfoJSONRenderer`
417
417
 
@@ -527,6 +527,84 @@ data = serializer.data
527
527
  - Relative file paths are automatically converted to absolute URLs.
528
528
  - Can manually specify fields via `file_fields` for non-model serializers.
529
529
 
530
+ ### 9. BulkCreateMixin — API Reference
531
+
532
+ ```python
533
+ from djresttoolkit.serializers.mixins import BulkCreateMixin
534
+ ```
535
+
536
+ #### `BulkCreateMixin`
537
+
538
+ A **DRF serializer mixin** that adds support for:
539
+
540
+ - **Single instance creation** with extra context fields
541
+ - **Bulk creation** from a list of validated data dictionaries
542
+ - **Updating serializer field error messages** with model-specific messages
543
+
544
+ #### Bulk Create Mixin Notes
545
+
546
+ - `bulk_create()` does **not trigger model signals** or call `.save()` on instances.
547
+ - `Meta.model` **must** be defined in the serializer.
548
+
549
+ #### Bulk Create Mixin Methods
550
+
551
+ #### `create(self, validated_data: dict[str, Any] | list[dict[str, Any]]) -> Model | list[Model]`
552
+
553
+ - Creates single or multiple model instances.
554
+ - **Parameters:**
555
+ - `validated_data`: dict for single instance or list of dicts for bulk creation.
556
+
557
+ - **Returns:**
558
+ - Single model instance or list of instances.
559
+
560
+ - **Raises:**
561
+ - `AttributeError` if `Meta.model` is not defined.
562
+ - `NotImplementedError` if used with a serializer that does not implement `create()`.
563
+
564
+ #### `get_fields(self) -> dict[str, SerializerField]`
565
+
566
+ - Extends DRF serializer `get_fields()` to update **error messages** using model field definitions.
567
+ - **Returns:**
568
+ - Dictionary of serializer fields.
569
+
570
+ - **Warning:**
571
+ - Logs a warning if a serializer field is not present on the model.
572
+
573
+ ### Bulk Create Mixin Example
574
+
575
+ ```python
576
+ from rest_framework import serializers
577
+ from djresttoolkit.serializers.mixins import BulkCreateMixin
578
+ from myapp.models import Product
579
+
580
+ class ProductSerializer(BulkCreateMixin, serializers.ModelSerializer):
581
+ class Meta:
582
+ model = Product
583
+ fields = ["id", "name", "price"]
584
+
585
+ # Single creation
586
+ serializer = ProductSerializer(data={"name": "Item1", "price": 10})
587
+ serializer.is_valid(raise_exception=True)
588
+ product = serializer.save()
589
+
590
+ # Bulk creation
591
+ serializer = ProductSerializer(
592
+ data=[
593
+ {"name": "Item2", "price": 20},
594
+ {"name": "Item3", "price": 30},
595
+ ],
596
+ many=True
597
+ )
598
+ serializer.is_valid(raise_exception=True)
599
+ products = serializer.save()
600
+ ```
601
+
602
+ #### Bulk Create Mixin Features
603
+
604
+ - Works seamlessly with DRF `ModelSerializer`.
605
+ - Automatically updates field error messages based on Django model definitions.
606
+ - Bulk creation is optimized using `model.objects.bulk_create()` for efficiency.
607
+
530
608
  ## 🛠️ Planned Features
531
609
 
532
610
  - Add more utils
@@ -1,5 +1,5 @@
1
1
  LICENSE,sha256=8-oZM3yuuTRjySMbVKX9YXYA7Y4M_KhQNBYXPFjeWUo,1074
2
- README.md,sha256=OoZENrGn6D6SPnRlXO1CI_rdRaqZfSJunHlE9QOm-zI,12188
2
+ README.md,sha256=OzvflId2K79hvwsZr4VIf393Fvm1PhTExUHAAnBvpzo,14651
3
3
  demo/staticfiles/admin/img/LICENSE,sha256=0RT6_zSIwWwxmzI13EH5AjnT1j2YU3MwM9j3U19cAAQ,1081
4
4
  src/djresttoolkit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  src/djresttoolkit/admin.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -27,16 +27,16 @@ src/djresttoolkit/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
27
27
  src/djresttoolkit/renderers/__init__.py,sha256=kmFMPRiMfD8CuJTN1_-6Z_Hqil3x8GBM0IN1roZESm0,107
28
28
  src/djresttoolkit/renderers/_throttle_info_json_renderer.py,sha256=aP2cN4cB_Imcpy732zsPBQrMQqcKEs5R3dld5Y_4AMU,1089
29
29
  src/djresttoolkit/serializers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
- src/djresttoolkit/serializers/_serializer_create_mixin.py,sha256=KprWF_aeEgRygcWG--xtVfnWsOowKqjmdF0aHmrNlzE,3253
31
- src/djresttoolkit/serializers/mixins/__init__.py,sha256=fCDNLYLx7Y_19mp8Ya_0akCAViSU3a3LhqgS_sFDMsA,154
30
+ src/djresttoolkit/serializers/mixins/__init__.py,sha256=dRT0kXDckOkZo1RQHrT1gXbGFMIv5M8TBHGF2uF-81Q,225
32
31
  src/djresttoolkit/serializers/mixins/_absolute_url_file_mixin.py,sha256=5ewael0_RsJZ9b36IfXacxjb-Vx1eQ9Dk6dWuj5D_dc,3261
32
+ src/djresttoolkit/serializers/mixins/_bulk_create_mixin.py,sha256=9ZWm2MNaZOhmhKlWOu6VECtlDbUtaPeceGHmivDYwYQ,3248
33
33
  src/djresttoolkit/throttling/__init__.py,sha256=01sjMymjx8XjqnAw3bEBLc-JtfhCDrp5dGxSNXMvPpU,84
34
34
  src/djresttoolkit/throttling/_throttle_inspector.py,sha256=Kss6ZxKy-EXq9UGaGprGDhpSuJ5992bmEYZSWmUVBHo,6480
35
35
  src/djresttoolkit/views/__init__.py,sha256=XrxBrs6sH4HmUzp41omcmy_y94pSaXAVn01ttQ022-4,76
36
36
  src/djresttoolkit/views/_exceptions/__init__.py,sha256=DrCUxuPNyBR4WhzNutn5HDxLa--q51ykIxSG7_bFsOI,83
37
37
  src/djresttoolkit/views/_exceptions/_exception_handler.py,sha256=_o7If47bzWLl57LeSXSWsIDsJGo2RIpwYAwNQ-hsHVY,2839
38
- djresttoolkit-0.9.0.dist-info/METADATA,sha256=8Kb2jWYW9ZTev9M6ciwtPk5A0z0lFJVrDhXVZkoIis8,15197
39
- djresttoolkit-0.9.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
40
- djresttoolkit-0.9.0.dist-info/entry_points.txt,sha256=YMhfTF-7mYppO8QqqWnvR_hyMWvoYxD6XI94_ViFu3k,60
41
- djresttoolkit-0.9.0.dist-info/licenses/LICENSE,sha256=8-oZM3yuuTRjySMbVKX9YXYA7Y4M_KhQNBYXPFjeWUo,1074
42
- djresttoolkit-0.9.0.dist-info/RECORD,,
38
+ djresttoolkit-0.10.0.dist-info/METADATA,sha256=A91Vw-rZ7cni31PQzgw568wk5tGRLROJkBe9mLXYa14,17661
39
+ djresttoolkit-0.10.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
40
+ djresttoolkit-0.10.0.dist-info/entry_points.txt,sha256=YMhfTF-7mYppO8QqqWnvR_hyMWvoYxD6XI94_ViFu3k,60
41
+ djresttoolkit-0.10.0.dist-info/licenses/LICENSE,sha256=8-oZM3yuuTRjySMbVKX9YXYA7Y4M_KhQNBYXPFjeWUo,1074
42
+ djresttoolkit-0.10.0.dist-info/RECORD,,
@@ -1,6 +1,8 @@
1
1
  from ._absolute_url_file_mixin import AbsoluteUrlFileMixin, MissingRequestContext
2
+ from ._bulk_create_mixin import BulkCreateMixin
2
3
 
3
4
  __all__ = [
4
5
  "AbsoluteUrlFileMixin",
5
6
  "MissingRequestContext",
7
+ "BulkCreateMixin",
6
8
  ]
@@ -10,7 +10,7 @@ from django.db.models import Field as ModelField
10
10
  logger = logging.getLogger(__name__)
11
11
 
12
12
 
13
- class RecordsCreationMixin:
13
+ class BulkCreateMixin:
14
14
  """
15
15
  A mixin for DRF serializers that supports:
16
16
  - Single instance creation with extra context fields