You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pydantic中限制URL验证仅针对特定主机或网站

在Pydantic中限制URL仅允许特定主机的最佳方案

针对你的需求,有两种实用方案可以实现URL主机的限制,以下是具体实现:

方案一:字段验证器(适合单个模型场景)

直接给url字段添加自定义验证逻辑,简单直接,适合仅在单个模型中使用的场景:

from pydantic import BaseModel, AnyUrl, field_validator
from pydantic_core import ValidationError

# 定义允许的主机列表
ALLOWED_HOSTS = {"x.com", "y.com"}

class Media(BaseModel):
    url: AnyUrl

    @field_validator("url")
    def validate_host(cls, v: AnyUrl) -> AnyUrl:
        # 利用AnyUrl已解析的host属性进行校验
        if v.host not in ALLOWED_HOSTS:
            raise ValueError(f"URL主机必须是{', '.join(ALLOWED_HOSTS)}中的一个")
        return v

# 验证测试
if __name__ == "__main__":
    # 合法URL测试
    try:
        valid_media = Media(url="https://x.com/photo.png")
        print("验证通过:", valid_media)
    except ValidationError as e:
        print("验证失败:", e)

    # 非法URL测试
    try:
        invalid_media = Media(url="https://z.com/file.mp4")
        print("验证通过:", invalid_media)
    except ValidationError as e:
        print("验证失败:", e)

方案二:自定义受限URL类型(适合多模型复用场景)

如果多个模型都需要相同的主机限制,自定义一个继承自AnyUrl的类型可以实现逻辑复用:

from pydantic import BaseModel, AnyUrl, GetCoreSchemaHandler
from pydantic_core import core_schema
from typing import Any
from pydantic_core import ValidationError

ALLOWED_HOSTS = {"x.com", "y.com"}

class RestrictedUrl(AnyUrl):
    @classmethod
    def __get_pydantic_core_schema__(cls, source_type: Any, handler: GetCoreSchemaHandler) -> core_schema.CoreSchema:
        # 继承AnyUrl的原有验证逻辑
        base_schema = handler(source_type)
        # 追加主机校验逻辑
        validated_schema = core_schema.no_info_after_validator_function(
            cls.validate_host,
            base_schema,
        )
        return validated_schema

    @classmethod
    def validate_host(cls, v: AnyUrl) -> AnyUrl:
        if v.host not in ALLOWED_HOSTS:
            raise ValueError(f"URL主机必须是{', '.join(ALLOWED_HOSTS)}中的一个")
        return v

class Media(BaseModel):
    url: RestrictedUrl

# 验证测试
if __name__ == "__main__":
    try:
        valid_media = Media(url="https://y.com/video.mp4")
        print("验证通过:", valid_media)
    except ValidationError as e:
        print("验证失败:", e)

兼容Pydantic v1的写法

如果你仍在使用Pydantic v1,只需将@field_validator替换为@validator即可:

from pydantic import BaseModel, AnyUrl, validator
from pydantic.error_wrappers import ValidationError

ALLOWED_HOSTS = {"x.com", "y.com"}

class Media(BaseModel):
    url: AnyUrl

    @validator("url")
    def validate_host(cls, v):
        if v.host not in ALLOWED_HOSTS:
            raise ValueError(f"URL主机必须是{', '.join(ALLOWED_HOSTS)}中的一个")
        return v

内容的提问来源于stack exchange,提问作者pyGenius

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 23:05:09