From 81bacce484ffdc404d6672422ef05fbdbed1d889 Mon Sep 17 00:00:00 2001 From: Steven Bal Date: Fri, 20 Sep 2024 16:15:15 +0200 Subject: [PATCH] :sparkles: [open-zaak/open-notificaties#156] Pass request as kwarg to Kanaal.get_kenmerken and add hook for `_get_field` to support nested attributes in Open Zaak --- notifications_api_common/kanalen.py | 29 +++++++++++++++++++++------- notifications_api_common/viewsets.py | 4 +++- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/notifications_api_common/kanalen.py b/notifications_api_common/kanalen.py index c89d9eb..0089352 100644 --- a/notifications_api_common/kanalen.py +++ b/notifications_api_common/kanalen.py @@ -1,18 +1,22 @@ """ Provide notifications kanaal/exchange classes. """ + from collections import defaultdict -from typing import Dict, Tuple +from typing import Dict, Union from django.core.exceptions import FieldDoesNotExist, ImproperlyConfigured -from django.db.models import Model -from django.db.models.base import ModelBase +from django.db.models import Field, Model + +from rest_framework.request import Request KANAAL_REGISTRY = set() class Kanaal: - def __init__(self, label: str, main_resource: ModelBase, kenmerken: Tuple = None): + def __init__( + self, label: str, main_resource: Model, kenmerken: Union[tuple, None] = None + ): self.label = label self.main_resource = main_resource @@ -22,7 +26,7 @@ def __init__(self, label: str, main_resource: ModelBase, kenmerken: Tuple = None self.kenmerken = kenmerken or () for kenmerk in self.kenmerken: try: - self.main_resource._meta.get_field(kenmerk) + self._get_field(self.main_resource, kenmerk) except FieldDoesNotExist as exc: raise ImproperlyConfigured( f"Kenmerk '{kenmerk}' does not exist on the model {main_resource}" @@ -38,7 +42,18 @@ def __repr__(self): self.main_resource, ) - def get_kenmerken(self, obj: Model, data: Dict = None) -> Dict: + def _get_field(self, model: Model, field: str) -> Field: + """ + Function to retrieve a field from a Model + """ + return model._meta.get_field(field) + + def get_kenmerken( + self, + obj: Model, + data: dict | None = None, + request: Request | None = None, # noqa + ) -> Dict: data = data or {} return { kenmerk: data.get(kenmerk, getattr(obj, kenmerk)) @@ -54,7 +69,7 @@ def description(self): kenmerken = [ kenmerk_template.format( kenmerk=kenmerk, - help_text=self.main_resource._meta.get_field(kenmerk).help_text, + help_text=self._get_field(self.main_resource, kenmerk).help_text, ) for kenmerk in self.kenmerken ] diff --git a/notifications_api_common/viewsets.py b/notifications_api_common/viewsets.py index d614c45..5e93a3f 100644 --- a/notifications_api_common/viewsets.py +++ b/notifications_api_common/viewsets.py @@ -136,7 +136,9 @@ def construct_message(self, data: dict, instance: models.Model = None) -> dict: "actie": self.action, "aanmaakdatum": timezone.now(), # each channel knows which kenmerken it has, so delegate this - "kenmerken": kanaal.get_kenmerken(main_object, main_object_data), + "kenmerken": kanaal.get_kenmerken( + main_object, main_object_data, request=self.request + ), } # let the serializer & render machinery shape the data the way it