|
3 | 3 | from django.core.exceptions import ObjectDoesNotExist |
4 | 4 | from rest_framework import serializers |
5 | 5 | from rest_framework.exceptions import ValidationError |
| 6 | +from rest_framework.utils.model_meta import get_field_info |
6 | 7 |
|
| 8 | +from django_features.custom_fields.models import CustomField |
7 | 9 | from django_features.custom_fields.models import CustomValue |
| 10 | +from django_features.custom_fields.models.value import CustomValueQuerySet |
8 | 11 |
|
9 | 12 |
|
10 | 13 | class ChoiceIdField(serializers.Field): |
11 | | - def to_internal_value(self, data: Any) -> CustomValue: |
12 | | - if isinstance(data, int): |
| 14 | + def __init__( |
| 15 | + self, field: CustomField, unique_field: str | None = None, **kwargs: Any |
| 16 | + ) -> None: |
| 17 | + super().__init__(**kwargs) |
| 18 | + self.field = field |
| 19 | + self.unique_field = unique_field or "id" |
| 20 | + |
| 21 | + valid_fields = get_field_info(CustomValue).fields_and_pk |
| 22 | + if self.unique_field not in valid_fields: |
| 23 | + raise ValueError( |
| 24 | + f"The unique_field must be a valid field of {valid_fields}: invalid field {self.unique_field}" |
| 25 | + ) |
| 26 | + |
| 27 | + def get_queryset(self) -> CustomValueQuerySet: |
| 28 | + return CustomValue.objects.filter(field_id=self.field.id) |
| 29 | + |
| 30 | + def to_internal_value(self, data: Any) -> CustomValue | CustomValueQuerySet: |
| 31 | + qs = self.get_queryset() |
| 32 | + if isinstance(data, int) or isinstance(data, str): |
13 | 33 | try: |
14 | | - return CustomValue.objects.get(id=data) |
| 34 | + return qs.get(**{self.unique_field: data}) |
15 | 35 | except ObjectDoesNotExist: |
16 | 36 | raise ValidationError( |
17 | | - f"Custom value with the id {data} does not exist." |
| 37 | + f"Custom value with the {self.unique_field} {data} does not exist." |
18 | 38 | ) |
19 | 39 | elif isinstance(data, list): |
20 | | - values = CustomValue.objects.filter(id__in=data) |
| 40 | + values = qs.filter(**{f"{self.unique_field}__in": data}) |
21 | 41 | if values.count() != len(data): |
22 | | - missing = set(data) - set(values.values_list("id", flat=True)) |
23 | | - raise ValidationError(f"Some of the given ids do not match: {missing}") |
| 42 | + missing = set(data) - set( |
| 43 | + values.values_list(self.unique_field, flat=True) |
| 44 | + ) |
| 45 | + raise ValidationError( |
| 46 | + f"Some of the given {self.unique_field}s do not match: {missing}" |
| 47 | + ) |
24 | 48 | return values |
25 | 49 | raise ValidationError( |
26 | 50 | f"The given value {data} has not a valid type. Expected a list or int." |
|
0 commit comments