|
1 | 1 | import typing |
2 | 2 |
|
| 3 | +from django.http.request import HttpRequest |
| 4 | +from django.utils.translation import gettext |
3 | 5 | from rest_framework import serializers |
| 6 | +from ulid import ULID |
4 | 7 |
|
5 | 8 | from apps.common.models import UserResource |
6 | 9 |
|
7 | | -ModelType = typing.TypeVar("ModelType", bound=UserResource) |
8 | 10 |
|
| 11 | +class DrfContextType(typing.TypedDict): |
| 12 | + request: HttpRequest |
9 | 13 |
|
10 | | -class UserResourceSerializer(serializers.ModelSerializer[ModelType]): |
| 14 | + |
| 15 | +# FIXME(tnagorra): Add support for DrfContextType in __init__ |
| 16 | +# Reference: https://github.com/locustio/locust/blob/master/locust/clients.py#L144 |
| 17 | +class UserResourceSerializer[ModelType: UserResource, ContextType: DrfContextType = DrfContextType]( |
| 18 | + serializers.ModelSerializer[ModelType], |
| 19 | +): |
11 | 20 | modified_at = serializers.DateTimeField(read_only=True) |
12 | 21 | modified_by = serializers.PrimaryKeyRelatedField(read_only=True) |
| 22 | + client_id = serializers.CharField() |
13 | 23 |
|
14 | 24 | instance: ModelType | None # type: ignore[override] |
15 | 25 |
|
| 26 | + def validate_client_id(self, new_client_id: str | None): |
| 27 | + if new_client_id is None: |
| 28 | + return None |
| 29 | + |
| 30 | + try: |
| 31 | + ULID.from_str(new_client_id) |
| 32 | + return new_client_id |
| 33 | + except (ValueError, TypeError) as err: |
| 34 | + raise serializers.ValidationError( |
| 35 | + gettext("Not a valid ULID value '%s'") % (new_client_id), |
| 36 | + ) from err |
| 37 | + |
| 38 | + @property |
| 39 | + def context(self) -> ContextType: # type: ignore[override] |
| 40 | + context = super().context |
| 41 | + assert context is not None, f"Always pass context when using {type(self)}" |
| 42 | + return typing.cast("ContextType", context) |
| 43 | + |
16 | 44 | @typing.override |
17 | 45 | def create(self, validated_data: dict[str, typing.Any]) -> ModelType: |
18 | 46 | if "created_by" in self.Meta.model._meta._forward_fields_map: # type: ignore[reportAttributeAccessIssue] |
|
0 commit comments