django-ninja-aio-crud 2.15.0__py3-none-any.whl → 2.16.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-ninja-aio-crud
3
- Version: 2.15.0
3
+ Version: 2.16.0
4
4
  Summary: Django Ninja AIO CRUD - Rest Framework
5
5
  Author: Giuseppe Casillo
6
6
  Requires-Python: >=3.10, <3.15
@@ -1,6 +1,6 @@
1
- ninja_aio/__init__.py,sha256=1ZReAODrup4BI5sHOAuanMqhDqfl36W8gVvhBrf5IZ0,120
1
+ ninja_aio/__init__.py,sha256=r0RyWWYURc6f5zZT0E9Rqx4tbu1WzKhXpUusNtGwQ7s,120
2
2
  ninja_aio/api.py,sha256=tuC7vdvn7s1GkCnSFy9Kn1zv0glZfYptRQVvo8ZRtGQ,2429
3
- ninja_aio/auth.py,sha256=4sWdFPjKiQgUL1d_CSGDblVjnY5ptP6LQha6XXdluJA,9157
3
+ ninja_aio/auth.py,sha256=f4yk45fLi36Qctu0A0zgHTFedb9yk3ewq5rOMpoPYIE,9035
4
4
  ninja_aio/exceptions.py,sha256=_3xFqfFCOfrrMhSA0xbMqgXy8R0UQjhXaExrFvaDAjY,3891
5
5
  ninja_aio/parsers.py,sha256=e_4lGCPV7zs-HTqtdJTc8yQD2KPAn9njbL8nF_Mmgkc,153
6
6
  ninja_aio/renders.py,sha256=CW0xDa05Xna-UvL0MZqZeDEgueEaUassV_nG7Rh1-cw,1824
@@ -11,20 +11,20 @@ ninja_aio/decorators/views.py,sha256=0RVU4XaM1HvTQ-BOt_NwUtbhwfHau06lh-O8El1LqQk
11
11
  ninja_aio/factory/__init__.py,sha256=IdH2z1ZZpv_IqonaDfVo7IsMzkgop6lHqz42RphUYBU,72
12
12
  ninja_aio/factory/operations.py,sha256=OgWGqq4WJ4arSQrH9FGAby9kx-HTdS7MOITxHdYMk18,12051
13
13
  ninja_aio/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
- ninja_aio/helpers/api.py,sha256=O2nGvP3VSsG-AReQRn90yDH8vS3kMKh125j-ikwgGoQ,20987
14
+ ninja_aio/helpers/api.py,sha256=va_HvZVBFm1KxwQhH4u09U4F1JS5JrQuRpRmPTHJt7w,21326
15
15
  ninja_aio/helpers/query.py,sha256=Lqv4nrWYr543tC5K-SEcBottLID8cb83aDc26i2Wxj4,5053
16
16
  ninja_aio/models/__init__.py,sha256=L3UQnQAlKoI3F7jinadL-Nn55hkPvnSRPYW0JtnbWFo,114
17
- ninja_aio/models/serializers.py,sha256=tm2ACQO-n877NTYN0YR-6qVZrZQpWgPDh0EeOZo_TWY,42824
17
+ ninja_aio/models/serializers.py,sha256=fwuEQrBcybCNBHPo1i-EHXIX8F4Fd52iduZf_Cl9wE4,42823
18
18
  ninja_aio/models/utils.py,sha256=lAXtc3YY7_n4f0jIacX4DSXhUOzMy7y5MsBnInNxtfk,32874
19
19
  ninja_aio/schemas/__init__.py,sha256=dHILiYBKMb51lDcyQdiXRw_0nzqM7Lu81UX2hv7kEfo,837
20
20
  ninja_aio/schemas/api.py,sha256=dGUpJXR1iAf93QNR4kYj1uqIkTjiMfXultCotY6GtaQ,361
21
21
  ninja_aio/schemas/filters.py,sha256=VxzH2xSWok8cUSkyfeqtrGhRewtFVmNHQfHNvY8Aynw,2662
22
22
  ninja_aio/schemas/generics.py,sha256=frjJsKJMAdM_NdNKv-9ddZNGxYy5PNzjIRGtuycgr-w,112
23
- ninja_aio/schemas/helpers.py,sha256=h4zQRf21NVLMQbIVH-psAE4FICUBc857EqngblEy7og,8636
23
+ ninja_aio/schemas/helpers.py,sha256=CpubwNXsZHtu8jddliyQybF1epwZ-GO60vHIuF5AR1Y,8967
24
24
  ninja_aio/views/__init__.py,sha256=DEzjWA6y3WF0V10nNF8eEurLNEodgxKzyFd09AqVp3s,148
25
25
  ninja_aio/views/api.py,sha256=AAqkj0xT8J3PmJvsbluZ33cfrmrXJHiV9ARe2BqnfQ8,22492
26
26
  ninja_aio/views/mixins.py,sha256=Zl6J8gbVagwT85bzDuKyJTk3iFxxFgX0YgYkjiUxZGg,17040
27
- django_ninja_aio_crud-2.15.0.dist-info/licenses/LICENSE,sha256=yrDAYcm0gRp_Qyzo3GQa4BjYjWRkAhGC8QRva__RYq0,1073
28
- django_ninja_aio_crud-2.15.0.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
29
- django_ninja_aio_crud-2.15.0.dist-info/METADATA,sha256=m89g4FLCQgQvwCkSoJLxzsUwCuf4ESwyqKJLX31qKAo,9964
30
- django_ninja_aio_crud-2.15.0.dist-info/RECORD,,
27
+ django_ninja_aio_crud-2.16.0.dist-info/licenses/LICENSE,sha256=yrDAYcm0gRp_Qyzo3GQa4BjYjWRkAhGC8QRva__RYq0,1073
28
+ django_ninja_aio_crud-2.16.0.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
29
+ django_ninja_aio_crud-2.16.0.dist-info/METADATA,sha256=Ub6OM-TaFA9SkIDd2b--wcc0xRAok3En5NvWjPsT07M,9964
30
+ django_ninja_aio_crud-2.16.0.dist-info/RECORD,,
ninja_aio/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
1
  """Django Ninja AIO CRUD - Rest Framework"""
2
2
 
3
- __version__ = "2.15.0"
3
+ __version__ = "2.16.0"
4
4
 
5
5
  from .api import NinjaAIO
6
6
 
ninja_aio/auth.py CHANGED
@@ -107,11 +107,6 @@ class AsyncJwtBearer(HttpBearer):
107
107
  """
108
108
  try:
109
109
  self.dcd = jwt.decode(token, self.jwt_public, algorithms=self.algorithms)
110
- except ValueError:
111
- # raise AuthError(", ".join(exc.args), 401)
112
- return False
113
-
114
- try:
115
110
  self.validate_claims(self.dcd.claims)
116
111
  except errors.JoseError:
117
112
  return False
ninja_aio/helpers/api.py CHANGED
@@ -359,6 +359,7 @@ class ManyToManyAPI:
359
359
  filters_schema,
360
360
  append_slash: bool,
361
361
  verbose_name_plural: str,
362
+ decorators: list,
362
363
  ):
363
364
  @self.router.get(
364
365
  self._get_api_path(rel_path, append_slash=append_slash),
@@ -373,6 +374,7 @@ class ManyToManyAPI:
373
374
  @decorate_view(
374
375
  unique_view(f"get_{self.related_model_util.model_name}_{rel_path}"),
375
376
  paginate(self.pagination_class),
377
+ *decorators,
376
378
  )
377
379
  async def get_related(
378
380
  request: HttpRequest,
@@ -407,6 +409,7 @@ class ManyToManyAPI:
407
409
  m2m_add: bool,
408
410
  m2m_remove: bool,
409
411
  verbose_name_plural: str,
412
+ decorators: list,
410
413
  ):
411
414
  action, schema_in = self._resolve_action_schema(m2m_add, m2m_remove)
412
415
  plural = verbose_name_plural
@@ -422,7 +425,10 @@ class ManyToManyAPI:
422
425
  summary=summary,
423
426
  description=summary,
424
427
  )
425
- @unique_view(f"manage_{self.related_model_util.model_name}_{rel_path}")
428
+ @decorate_view(
429
+ unique_view(f"manage_{self.related_model_util.model_name}_{rel_path}"),
430
+ *decorators,
431
+ )
426
432
  async def manage_related(
427
433
  request: HttpRequest,
428
434
  pk: Path[self.path_schema], # type: ignore
@@ -483,6 +489,8 @@ class ManyToManyAPI:
483
489
  relation.verbose_name_plural
484
490
  or rel_util.model._meta.verbose_name_plural.capitalize()
485
491
  )
492
+ get_decorators = relation.get_decorators or []
493
+ post_decorators = relation.post_decorators or []
486
494
 
487
495
  if m2m_get:
488
496
  self._register_get_relation_view(
@@ -494,6 +502,7 @@ class ManyToManyAPI:
494
502
  filters_schema=filters_schema,
495
503
  append_slash=append_slash,
496
504
  verbose_name_plural=verbose_name_plural,
505
+ decorators=get_decorators,
497
506
  )
498
507
 
499
508
  if m2m_add or m2m_remove:
@@ -505,6 +514,7 @@ class ManyToManyAPI:
505
514
  m2m_add=m2m_add,
506
515
  m2m_remove=m2m_remove,
507
516
  verbose_name_plural=verbose_name_plural,
517
+ decorators=post_decorators,
508
518
  )
509
519
 
510
520
  def _add_views(self):
@@ -305,9 +305,8 @@ class BaseSerializer:
305
305
  """
306
306
  # Auto-resolve ModelSerializer with readable fields
307
307
  if isinstance(rel_model, ModelSerializerMeta):
308
- if rel_model.get_fields("read") or rel_model.get_custom_fields("read"):
309
- return rel_model.generate_related_s()
310
- return None
308
+ has_readable_fields = rel_model.get_fields("read") or rel_model.get_custom_fields("read")
309
+ return rel_model.generate_related_s() if has_readable_fields else None
311
310
 
312
311
  # Resolve from explicit serializer mapping
313
312
  rel_serializers = cls._get_relations_serializers() or {}
@@ -478,11 +477,10 @@ class BaseSerializer:
478
477
  return (field_name, PkFromModel[pk_field_type] | None, None)
479
478
 
480
479
  # Special case: ModelSerializer with no readable fields should be skipped entirely
481
- if isinstance(rel_model, ModelSerializerMeta):
482
- if not (
483
- rel_model.get_fields("read") or rel_model.get_custom_fields("read")
484
- ):
485
- return None
480
+ if isinstance(rel_model, ModelSerializerMeta) and not (
481
+ rel_model.get_fields("read") or rel_model.get_custom_fields("read")
482
+ ):
483
+ return None
486
484
 
487
485
  schema = cls._resolve_relation_schema(field_name, rel_model)
488
486
  if not schema:
@@ -1,4 +1,4 @@
1
- from typing import List, Optional, Type
1
+ from typing import Callable, List, Optional, Type
2
2
 
3
3
  from ninja import Schema
4
4
  from ninja_aio.types import ModelSerializerMeta, SerializerMeta
@@ -46,7 +46,11 @@ class M2MRelationSchema(BaseModel):
46
46
  Whether to append a trailing slash to the generated GET endpoint path. Defaults to False for backward compatibility.
47
47
  verbose_name_plural (str | None):
48
48
  Optional human-readable plural name for the related model, used in documentation and responses.
49
-
49
+ get_decorators (List | None):
50
+ Optional list of decorators to apply to the GET endpoint.
51
+ post_decorators (List | None):
52
+ Optional list of decorators to apply to the POST (add/remove) endpoints.
53
+
50
54
  Validation:
51
55
  - If `model` is not a ModelSerializerMeta, `related_schema` is required.
52
56
  - When `model` is a ModelSerializerMeta and `related_schema` is not provided, it will be
@@ -72,6 +76,8 @@ class M2MRelationSchema(BaseModel):
72
76
  serializer_class: Optional[SerializerMeta] = None
73
77
  append_slash: bool = False
74
78
  verbose_name_plural: Optional[str] = None
79
+ get_decorators: Optional[List[Callable]] = []
80
+ post_decorators: Optional[List[Callable]] = []
75
81
 
76
82
  model_config = ConfigDict(arbitrary_types_allowed=True)
77
83