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

如何在drf-yasg生成的Django REST API文档中自动添加权限信息?

Django+drf_yasg自动添加API权限到Schema的解决方案提示

以下是几种无需手动编写,自动将权限信息注入生成的API文档的实现思路:

  • 扩展SchemaGenerator自动提取权限
    继承drf_yasg的OpenAPISchemaGenerator,重写get_operation方法,在生成每个接口的Schema操作对象时,自动提取视图的权限类、关联的Permission模型信息,将其追加到接口描述中。
    示例代码:

    from drf_yasg.generators import OpenAPISchemaGenerator
    from rest_framework.permissions import BasePermission
    from django.contrib.auth.models import Permission
    
    class PermissionAwareSchemaGenerator(OpenAPISchemaGenerator):
        def get_operation(self, path, method, view):
            operation = super().get_operation(path, method, view)
            permission_classes = getattr(view, 'permission_classes', [])
            permission_notes = []
    
            for perm_cls in permission_classes:
                if issubclass(perm_cls, BasePermission):
                    # 处理DjangoModelPermissions这类带权限映射的内置权限
                    if hasattr(perm_cls, 'perms_map'):
                        required_perms = perm_cls.perms_map.get(method.lower(), [])
                        for perm_codename in required_perms:
                            app_label, codename = perm_codename.split('.')
                            try:
                                perm_obj = Permission.objects.get(codename=codename, content_type__app_label=app_label)
                                permission_notes.append(f"{perm_obj.name} (权限编码: {perm_codename})")
                            except Permission.DoesNotExist:
                                permission_notes.append(f"未定义权限: {perm_codename}")
                    else:
                        # 处理自定义权限类,直接读取类名和文档字符串
                        perm_desc = perm_cls.__doc__.strip() if perm_cls.__doc__ else "无描述"
                        permission_notes.append(f"自定义权限[{perm_cls.__name__}]: {perm_desc}")
    
            if permission_notes:
                desc_prefix = operation.get('description', '')
                operation['description'] = f"{desc_prefix}\n\n**所需权限:**\n- {chr(10)}- ".join(permission_notes) if desc_prefix else f"**所需权限:**\n- {chr(10)}- ".join(permission_notes)
            
            return operation
    

    最后在项目settings中配置drf_yasg使用这个生成器:

    SWAGGER_SETTINGS = {
        'DEFAULT_GENERATOR_CLASS': 'your_project.path.to.PermissionAwareSchemaGenerator',
        # 其他配置...
    }
    
  • 自定义SwaggerAutoSchema实现视图级权限注入
    如果需要更细粒度的控制,可以自定义SwaggerAutoSchema,重写get_operation方法实现权限信息注入,然后在指定视图或全局配置使用该类。
    示例:

    from drf_yasg.inspectors import SwaggerAutoSchema
    
    class PermissionSwaggerSchema(SwaggerAutoSchema):
        def get_operation(self, operation_keys=None):
            operation = super().get_operation(operation_keys)
            view = self.view
            # 权限提取逻辑和上面一致,省略重复代码
            permission_classes = getattr(view, 'permission_classes', [])
            permission_notes = []
            for perm_cls in permission_classes:
                if issubclass(perm_cls, BasePermission):
                    if hasattr(perm_cls, 'perms_map'):
                        required_perms = perm_cls.perms_map.get(self.method.lower(), [])
                        for perm_codename in required_perms:
                            app_label, codename = perm_codename.split('.')
                            try:
                                perm_obj = Permission.objects.get(codename=codename, content_type__app_label=app_label)
                                permission_notes.append(f"{perm_obj.name} (权限编码: {perm_codename})")
                            except Permission.DoesNotExist:
                                permission_notes.append(f"未定义权限: {perm_codename}")
                    else:
                        perm_desc = perm_cls.__doc__.strip() if perm_cls.__doc__ else "无描述"
                        permission_notes.append(f"自定义权限[{perm_cls.__name__}]: {perm_desc}")
            
            if permission_notes:
                operation['description'] = (operation.get('description', '') + "\n\n**权限要求:**\n- " + "\n- ".join(permission_notes)).strip()
            return operation
    

    使用时可以在视图类中指定:

    class YourAPIView(APIView):
        swagger_schema_class = PermissionSwaggerSchema
        permission_classes = [IsAuthenticated, DjangoModelPermissions]
        # 视图逻辑...
    

    也可以全局配置默认的schema类。

  • 给权限类添加元数据简化提取
    针对自定义权限类,可以预先添加描述性元数据,避免在生成Schema时做复杂的数据库查询或逻辑解析:

    class ArticleEditPermission(BasePermission):
        permission_meta = {
            'name': '编辑文章权限',
            'codename': 'article.edit_article',
            'description': '允许用户修改已发布的文章'
        }
    
        def has_permission(self, request, view):
            return request.user.has_perm(self.permission_meta['codename'])
    

    之后在Schema生成逻辑中,直接读取perm_cls.permission_meta的内容即可,更高效且易维护。

  • 适配OpenAPI Security规范
    如果需要符合OpenAPI的安全认证标准,可以在Schema中定义securitySchemes(如JWT、Session认证),并给每个接口的operation添加security字段,关联对应的权限范围。比如在自定义Generator中添加:

    def get_schema(self, request=None, public=False):
        schema = super().get_schema(request, public)
        # 添加securitySchemes定义
        schema['components']['securitySchemes'] = {
            "BearerAuth": {
                "type": "http",
                "scheme": "bearer",
                "bearerFormat": "JWT"
            }
        }
        return schema
    

    然后在get_operation中给需要权限的接口添加:

    operation['security'] = [{"BearerAuth": []}]
    

    这样文档会清晰展示接口的认证方式和权限要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 11:25:30