Download apps/reminders/services/validators.py from jun2024/fc: direct link, hf CLI and curl.
- Browser
- Download file 4.05 kB
-
https://huggingface.co/spaces/jun2024/fc/resolve/main/apps/reminders/services/validators.py
- Command line
-
hf download hf://spaces/jun2024/fc/apps/reminders/services/validators.py
-
curl -L -o validators.py https://huggingface.co/spaces/jun2024/fc/resolve/main/apps/reminders/services/validators.py
4.05 kB
| """Validation helpers for reminder services.""" | |
| from __future__ import annotations | |
| import json | |
| from datetime import datetime | |
| from typing import TYPE_CHECKING, Any | |
| from django.utils import timezone | |
| from django.utils.translation import gettext_lazy as _ | |
| from apps.core.exceptions import ValidationException | |
| from ..models import ReminderType | |
| if TYPE_CHECKING: | |
| from django.utils.functional import Promise | |
| from ..ports import CaseLogTargetQueryPort, CaseTargetQueryPort, ContractTargetQueryPort | |
| def normalize_target_id(value: int | None, *, field_name: str | Promise) -> int | None: | |
| if value is None: | |
| return None | |
| if isinstance(value, bool) or not isinstance(value, int) or value <= 0: | |
| raise ValidationException(_("%(field_name)s 必须为正整数") % {"field_name": field_name}) | |
| return value | |
| def validate_positive_id(value: int, *, field_name: str | Promise) -> None: | |
| """校验 ID 为正整数(非 bool)。""" | |
| if isinstance(value, bool) or value <= 0: | |
| raise ValidationException(_("%(field_name)s 必须为正整数") % {"field_name": field_name}) | |
| def validate_binding_exclusive( | |
| *, | |
| contract_id: int | None, | |
| case_id: int | None, | |
| case_log_id: int | None, | |
| ) -> None: | |
| bound_count = sum(target_id is not None for target_id in (contract_id, case_id, case_log_id)) | |
| if bound_count > 1: | |
| raise ValidationException(_("合同、案件、案件日志最多只能绑定一个")) | |
| def validate_fk_exists( | |
| *, | |
| contract_id: int | None, | |
| case_id: int | None, | |
| case_log_id: int | None, | |
| contract_target_query: ContractTargetQueryPort | None = None, | |
| case_target_query: CaseTargetQueryPort | None = None, | |
| case_log_target_query: CaseLogTargetQueryPort | None = None, | |
| ) -> None: | |
| """校验外键引用的记录是否存在。""" | |
| if contract_id is not None: | |
| if contract_target_query is None: | |
| raise RuntimeError("ContractTargetQueryPort not provided") | |
| if not contract_target_query.exists(contract_id): | |
| raise ValidationException(_("合同 %(id)s 不存在") % {"id": contract_id}) | |
| if case_id is not None: | |
| if case_target_query is None: | |
| raise RuntimeError("CaseTargetQueryPort not provided") | |
| if not case_target_query.exists(case_id): | |
| raise ValidationException(_("案件 %(id)s 不存在") % {"id": case_id}) | |
| if case_log_id is not None: | |
| if case_log_target_query is None: | |
| raise RuntimeError("CaseLogTargetQueryPort not provided") | |
| if not case_log_target_query.exists(case_log_id): | |
| raise ValidationException(_("案件日志 %(id)s 不存在") % {"id": case_log_id}) | |
| def normalize_reminder_type(reminder_type: str) -> str: | |
| value = str(reminder_type).strip() | |
| if not value: | |
| raise ValidationException(_("提醒类型不能为空")) | |
| if value not in ReminderType.values: | |
| raise ValidationException(_("无效的提醒类型")) | |
| return value | |
| # 与 Reminder.content max_length=255 保持同步 | |
| _CONTENT_MAX_LENGTH = 255 | |
| def normalize_content(content: str) -> str: | |
| value = str(content).strip() | |
| if not value: | |
| raise ValidationException(_("提醒事项不能为空")) | |
| if len(value) > _CONTENT_MAX_LENGTH: | |
| raise ValidationException(_("提醒事项不能超过 %(max)d 个字符") % {"max": _CONTENT_MAX_LENGTH}) | |
| return value | |
| def normalize_due_at(due_at: datetime) -> datetime: | |
| if not isinstance(due_at, datetime): | |
| raise ValidationException(_("到期时间格式不正确")) | |
| if timezone.is_naive(due_at): | |
| return timezone.make_aware(due_at) | |
| return due_at | |
| def normalize_metadata(metadata: Any) -> dict[str, Any]: | |
| if metadata is None: | |
| return {} | |
| if not isinstance(metadata, dict): | |
| raise ValidationException(_("扩展数据必须为 JSON 对象")) | |
| try: | |
| json.dumps(metadata) | |
| except (TypeError, ValueError): | |
| raise ValidationException(_("扩展数据包含不可序列化的值")) | |
| return metadata | |