向所有序列化程序上的所有文本字段添加通用验证



我正在寻找一种方法(或多种方法,如果需要),将通用/共享验证函数添加到DRF API中的所有文本字段。我希望能够以最不具侵入性的方式做到这一点,因为API中已经有很多序列化程序了。

这是一件可怕的事情,也是错误的,但这是一项要求。说"不要那样做"或";你不应该这样做"没有帮助。我知道。这不取决于我。

给定这样的序列化程序:

class MySerializer(ModelSerializer):
description = CharField()
class Meta:
model = SomeModel
fields = ["name", "description"]

这两者都会以某种方式运行验证函数。例如,在基础CharField中,框架添加了两个验证器,本质上我想添加第三个验证器。

class CharField(Field):  # site-packages/rest_framework/fields.py
def __init__(self):
..
self.validators.append(ProhibitNullCharactersValidator())
self.validators.append(ProhibitSurrogateCharactersValidator())

有什么聪明的方法可以做到这一点吗?我不想对源代码进行黑客攻击,也不想在整个应用程序中替换CharField。


我最终采用的解决方案如下。它在django启动时加载在我的settings模块中,该模块有一个很好的z_patches.py,其他类似的东西(替换默认的过滤器类等)

def wrap_init(old_init):
@functools.wraps(old_init)
def __new_init__(self, **kwargs):
old_init(self, **kwargs)
self.validators.append(MyCustomValidator())
return __new_init__
CharField.__init__ = wrap_init(CharField.__init__)

如果你完全知道风险,那么你可以在你的apps.py:中做这样的事情

from django.apps import AppConfig
from rest_framework.fields import Field
from rest_framework.serializers import CharField

def _init(self, **kwargs):
...
Field.__init__(self, **kwargs)
...
self.validators.append(YourCustomValidator())

class MyAppConfig(AppConfig):
...
def ready(self):
CharField.__init__ = _init

最新更新