Files
DjangoVue3Admin/backend/utils/validator.py
T
2025-03-16 14:25:27 +08:00

73 lines
2.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
Time: 2023/8/6 16:07
Author: 公众号【布鲁的Python之旅】,【github】https://github.com/taskPyroer, 【gitee】https://gitee.com/hu_yupeng123/projects
Version: V 0.1
File: validator
Describe: 自定义验证器
"""
from django.db import DataError
from rest_framework.exceptions import APIException
from rest_framework.validators import UniqueValidator
class CustomValidationError(APIException):
"""
继承并重写验证器返回的结果,避免暴露字段
"""
def __init__(self, detail):
self.detail = detail
def qs_exists(queryset):
try:
return queryset.exists()
except (TypeError, ValueError, DataError):
return False
def qs_filter(queryset, **kwargs):
try:
return queryset.filter(**kwargs)
except (TypeError, ValueError, DataError):
return queryset.none()
class CustomUniqueValidator(UniqueValidator):
"""
继承,重写必填字段的验证器结果,防止字段暴露
"""
def filter_queryset(self, value, queryset, field_name):
"""
Filter the queryset to all instances matching the given attribute.
"""
filter_kwargs = {'%s__%s' % (field_name, self.lookup): value}
return qs_filter(queryset, **filter_kwargs)
def exclude_current_instance(self, queryset, instance):
"""
If an instance is being updated, then do not include
that instance itself as a uniqueness conflict.
"""
if instance is not None:
return queryset.exclude(pk=instance.pk)
return queryset
def __call__(self, value, serializer_field):
# Determine the underlying model field name. This may not be the
# same as the serializer field name if `source=<>` is set.
field_name = serializer_field.source_attrs[-1]
# Determine the existing instance, if this is an update operation.
instance = getattr(serializer_field.parent, 'instance', None)
queryset = self.queryset
queryset = self.filter_queryset(value, queryset, field_name)
queryset = self.exclude_current_instance(queryset, instance)
if qs_exists(queryset):
raise CustomValidationError(self.message)
def __repr__(self):
return super().__repr__()