commonground-api-common 2.5.5__py3-none-any.whl → 2.6.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.
- {commonground_api_common-2.5.5.dist-info → commonground_api_common-2.6.0.dist-info}/METADATA +1 -1
- {commonground_api_common-2.5.5.dist-info → commonground_api_common-2.6.0.dist-info}/RECORD +8 -8
- {commonground_api_common-2.5.5.dist-info → commonground_api_common-2.6.0.dist-info}/WHEEL +1 -1
- vng_api_common/__init__.py +1 -1
- vng_api_common/authorizations/utils.py +1 -0
- vng_api_common/serializers.py +117 -6
- {commonground_api_common-2.5.5.data → commonground_api_common-2.6.0.data}/scripts/generate_schema +0 -0
- {commonground_api_common-2.5.5.dist-info → commonground_api_common-2.6.0.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,5 @@
|
|
1
|
-
commonground_api_common-2.
|
2
|
-
vng_api_common/__init__.py,sha256=
|
1
|
+
commonground_api_common-2.6.0.data/scripts/generate_schema,sha256=OpKgzlFc_uzA3TVW_vHSYXAD_feLaCdTEnkWjIcxVzA,280
|
2
|
+
vng_api_common/__init__.py,sha256=OEib63e0yPEGlhEXyrWE1OwRnleR0cHI7KSX7oZEQLs,22
|
3
3
|
vng_api_common/admin.py,sha256=iFtUPGf-ha0I-bXgq8QIFrP23Kzk_H3FlgAjt0U-ip0,259
|
4
4
|
vng_api_common/apps.py,sha256=QQiJXRmjX9Q91oh0P9fvVnHe3NSYd1cEcUUBw0HLBCA,3690
|
5
5
|
vng_api_common/checks.py,sha256=tOyfV7MMLGh4anrd_W30LvJCxiyQ4sFs1mGd9mtrEc0,1175
|
@@ -28,7 +28,7 @@ vng_api_common/routers.py,sha256=hEnhBulkgMM-7W_lYaykKTgTBj3-avl7DGsR9P7BbTU,189
|
|
28
28
|
vng_api_common/schema.py,sha256=axs2Q8IXwpHNd5WscQg5xOErL6bWhP8WFItTt4xCFO4,16305
|
29
29
|
vng_api_common/scopes.py,sha256=PGs6CkXorAAdWXGFY1bSy-jmsPn122Njen9aFFOpFIQ,2351
|
30
30
|
vng_api_common/search.py,sha256=yehS6boCOk1JXLCqAMU-B62hWtbTBSf_WKIVGPgp0Mg,1045
|
31
|
-
vng_api_common/serializers.py,sha256=
|
31
|
+
vng_api_common/serializers.py,sha256=ErIoN1br71eszZ-hRgVUycjQkK6rJNkT5ygsagZoGNg,14084
|
32
32
|
vng_api_common/urls.py,sha256=9IWHYLlEIIHNaZ_Zq02qNQ2HJpETb7o-89r7yBM_tQs,270
|
33
33
|
vng_api_common/utils.py,sha256=EHqVjZhtqnbU7YrqgYIBss28Sd19jtnTLNaMWLfj3Zw,8203
|
34
34
|
vng_api_common/validators.py,sha256=ejaFZvFXFaBlqxjA2_07NSHKHlG5pejrfC_GHjwCj6E,12852
|
@@ -78,7 +78,7 @@ vng_api_common/authorizations/admin.py,sha256=Tk0yYKbb005E0XZaYYWbucMf_K5M8Hhz62
|
|
78
78
|
vng_api_common/authorizations/middleware.py,sha256=KJ3znCXPRMOVqSur62SmBjvC6RcKxtcWq1rzaHdYR98,8416
|
79
79
|
vng_api_common/authorizations/models.py,sha256=slIYxSktxCxSg03Nfb2mhsQse17b93KWE-rdPdMv8Ik,5199
|
80
80
|
vng_api_common/authorizations/serializers.py,sha256=3HeKWEqhI3UWwI8SttC4rEID-Epbk7SWsC-bEjolbaw,5151
|
81
|
-
vng_api_common/authorizations/utils.py,sha256=
|
81
|
+
vng_api_common/authorizations/utils.py,sha256=GmwTy5GhYk3e1VU4LpdfYdr8VD-R8p00hUY11QBbOhc,555
|
82
82
|
vng_api_common/authorizations/validators.py,sha256=u7fKm0QgGy8fiAeYmIEB9Gy-yIE9C-tC2ZpnNQBXPso,2816
|
83
83
|
vng_api_common/authorizations/migrations/0001_initial.py,sha256=ooAZtQeDtWgDxXzAP-KnSyyFYLRPM-PMrK5RgOnTPjQ,4360
|
84
84
|
vng_api_common/authorizations/migrations/0002_authorizationsconfig.py,sha256=m4taH6ClHI-YHYGGOKaq_qYXGx9lq1InXOGLQKg9MSw,1364
|
@@ -183,7 +183,7 @@ vng_api_common/tests/auth.py,sha256=IKDWTEFv4Bign4F70-ibsFcnJqRxEJaXvqaPQJWa1xY,
|
|
183
183
|
vng_api_common/tests/caching.py,sha256=zfIw5cRRvO9cekHZZKfRqZc8cx5IfJUYNmcH6cuIMg4,624
|
184
184
|
vng_api_common/tests/schema.py,sha256=WDvifDQQiKqIpQijpeQ7rYkFroJmuPuHe7zNhl1Bigk,2293
|
185
185
|
vng_api_common/tests/urls.py,sha256=PFrYzQbBC0TFPMEn3uPhcBG0IQs9JsEPqckicJT1UA4,2159
|
186
|
-
commonground_api_common-2.
|
187
|
-
commonground_api_common-2.
|
188
|
-
commonground_api_common-2.
|
189
|
-
commonground_api_common-2.
|
186
|
+
commonground_api_common-2.6.0.dist-info/METADATA,sha256=HsGhhHvzoGLHlqzsYvNxs_qrG76ym2BtbcCX3u7jqx8,6988
|
187
|
+
commonground_api_common-2.6.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
188
|
+
commonground_api_common-2.6.0.dist-info/top_level.txt,sha256=vPismc83zPzWXTmlNCCwfDlFV9iygJYxNJW5iDjKTgw,15
|
189
|
+
commonground_api_common-2.6.0.dist-info/RECORD,,
|
vng_api_common/__init__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = "2.
|
1
|
+
__version__ = "2.6.0"
|
vng_api_common/serializers.py
CHANGED
@@ -1,13 +1,17 @@
|
|
1
1
|
import datetime
|
2
2
|
import inspect
|
3
3
|
from collections import OrderedDict
|
4
|
+
from functools import reduce
|
4
5
|
from typing import List, Optional, Tuple, Union
|
5
6
|
|
6
7
|
from django.db import models, transaction
|
8
|
+
from django.db.models import Model
|
7
9
|
from django.utils.translation import gettext_lazy as _
|
8
10
|
|
9
11
|
import isodate
|
10
12
|
from rest_framework import fields, serializers
|
13
|
+
from rest_framework.request import Request
|
14
|
+
from rest_framework_nested.relations import NestedHyperlinkedRelatedField
|
11
15
|
|
12
16
|
from .choices import TextChoicesWithDescriptions
|
13
17
|
from .descriptors import GegevensGroepType
|
@@ -164,11 +168,11 @@ class GegevensGroepSerializer(
|
|
164
168
|
|
165
169
|
Usage::
|
166
170
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
171
|
+
>>> class VerlengingSerializer(GegevensGroepSerializer):
|
172
|
+
... class Meta:
|
173
|
+
... model = Zaak
|
174
|
+
... gegevensgroep = 'verlenging'
|
175
|
+
>>>
|
172
176
|
|
173
177
|
Where ``Zaak.verlenging`` is a :class:``GegevensGroepType``.
|
174
178
|
"""
|
@@ -275,7 +279,77 @@ class NestedGegevensGroepMixin:
|
|
275
279
|
return super().update(instance, validated_data)
|
276
280
|
|
277
281
|
|
278
|
-
|
282
|
+
def get_nested_fk_attribute(instance, relation_path):
|
283
|
+
"""
|
284
|
+
Retrieves an attribute from a nested foreign key relation.
|
285
|
+
|
286
|
+
Args:
|
287
|
+
- instance: The model instance (e.g., Book).
|
288
|
+
- relation_path: A string with the relation path, e.g., 'author__publisher__name'.
|
289
|
+
|
290
|
+
Returns:
|
291
|
+
- The value of the nested attribute or None if not found.
|
292
|
+
"""
|
293
|
+
relations = relation_path.split("__")
|
294
|
+
|
295
|
+
return reduce(
|
296
|
+
lambda obj, attr: getattr(obj, attr, None) if obj else None, relations, instance
|
297
|
+
)
|
298
|
+
|
299
|
+
|
300
|
+
class CacheMixin:
|
301
|
+
"""
|
302
|
+
Mixin for Hyperlinked DRF fields to cache the base URI per view, to avoid
|
303
|
+
having to recalculate this for each related object that has to be serialized
|
304
|
+
|
305
|
+
This cache is stored on the field instance itself, so it's reset between requests
|
306
|
+
"""
|
307
|
+
|
308
|
+
lookup_url_kwarg = "" # Should be defined on `HyperlinkedRelatedField`
|
309
|
+
identifier_placeholder = "id-placeholder"
|
310
|
+
|
311
|
+
def get_extra_reverse_kwargs(self) -> dict[str, str]:
|
312
|
+
"""
|
313
|
+
Hook to inject extra kwargs to be passed to `reverse()`
|
314
|
+
"""
|
315
|
+
return {}
|
316
|
+
|
317
|
+
def __init__(self, *args, **kwargs):
|
318
|
+
super().__init__(*args, **kwargs)
|
319
|
+
|
320
|
+
self._reverse_cache = {}
|
321
|
+
|
322
|
+
def get_url(
|
323
|
+
self, obj: Model, view_name: str, request: Request, format: str | None
|
324
|
+
) -> str | None:
|
325
|
+
# Unsaved objects will not yet have a valid URL.
|
326
|
+
if hasattr(obj, "pk") and obj.pk in (None, ""):
|
327
|
+
return None
|
328
|
+
|
329
|
+
base_url = self._reverse_cache.get(view_name)
|
330
|
+
|
331
|
+
if base_url is None:
|
332
|
+
# If not cached, compute and cache it for this request cycle
|
333
|
+
try:
|
334
|
+
# Insert placeholders for identifiers, these will be replaced by
|
335
|
+
# real identifiers later on
|
336
|
+
kwargs = {self.lookup_url_kwarg: self.identifier_placeholder}
|
337
|
+
kwargs.update(self.get_extra_reverse_kwargs())
|
338
|
+
|
339
|
+
base_url = self.reverse(
|
340
|
+
view_name, kwargs=kwargs, request=request, format=format
|
341
|
+
)
|
342
|
+
self._reverse_cache[view_name] = base_url
|
343
|
+
except Exception as e:
|
344
|
+
raise ValueError(f"Could not resolve reverse for {view_name}: {e}")
|
345
|
+
|
346
|
+
url = base_url.replace(
|
347
|
+
self.identifier_placeholder, str(getattr(obj, self.lookup_url_kwarg))
|
348
|
+
)
|
349
|
+
return url
|
350
|
+
|
351
|
+
|
352
|
+
class LengthHyperlinkedRelatedField(CacheMixin, serializers.HyperlinkedRelatedField):
|
279
353
|
default_error_messages = {
|
280
354
|
"max_length": _("Ensure this field has no more than {max_length} characters."),
|
281
355
|
"min_length": _("Ensure this field has at least {min_length} characters."),
|
@@ -296,3 +370,40 @@ class LengthHyperlinkedRelatedField(serializers.HyperlinkedRelatedField):
|
|
296
370
|
self.fail("min_length", max_length=self.min_length, length=len(data))
|
297
371
|
|
298
372
|
return super().to_internal_value(data)
|
373
|
+
|
374
|
+
|
375
|
+
class CachedHyperlinkedRelatedField(CacheMixin, serializers.HyperlinkedRelatedField):
|
376
|
+
"""
|
377
|
+
Subclass of ``serializers.HyperlinkedRelatedField`` that applies caching in
|
378
|
+
``.get_url()`` to ``reverse()`` calls to improve serialization performance
|
379
|
+
"""
|
380
|
+
|
381
|
+
|
382
|
+
class CachedHyperlinkedIdentityField(CacheMixin, serializers.HyperlinkedIdentityField):
|
383
|
+
"""
|
384
|
+
Subclass of ``serializers.HyperlinkedIdentityField`` that applies caching in
|
385
|
+
``.get_url()`` to ``reverse()`` calls to improve serialization performance
|
386
|
+
"""
|
387
|
+
|
388
|
+
|
389
|
+
class CachedNestedHyperlinkedRelatedField(CacheMixin, NestedHyperlinkedRelatedField):
|
390
|
+
"""
|
391
|
+
Subclass of ``serializers.HyperlinkedIdentityField`` that applies caching in
|
392
|
+
``.get_url()`` to ``reverse()`` calls to improve serialization performance
|
393
|
+
"""
|
394
|
+
|
395
|
+
def get_extra_reverse_kwargs(self) -> dict[str, str]:
|
396
|
+
return self.parent_lookup_kwargs
|
397
|
+
|
398
|
+
def get_url(
|
399
|
+
self, obj: Model, view_name: str, request: Request, format: str | None
|
400
|
+
) -> str | None:
|
401
|
+
url = super().get_url(obj, view_name, request, format)
|
402
|
+
|
403
|
+
if not url:
|
404
|
+
return None
|
405
|
+
|
406
|
+
# Replace the placeholder from the cached base URI with the actual identifier
|
407
|
+
for k, v in self.parent_lookup_kwargs.items():
|
408
|
+
url = url.replace(v, str(get_nested_fk_attribute(obj, v)))
|
409
|
+
return url
|
{commonground_api_common-2.5.5.data → commonground_api_common-2.6.0.data}/scripts/generate_schema
RENAMED
File without changes
|
{commonground_api_common-2.5.5.dist-info → commonground_api_common-2.6.0.dist-info}/top_level.txt
RENAMED
File without changes
|