doccano后端开发:Django REST框架API扩展实战

doccano后端开发:Django REST框架API扩展实战

【免费下载链接】doccano 【免费下载链接】doccano 项目地址: https://gitcode.com/gh_mirrors/doc/doccano

项目架构概览

doccano后端基于Django REST框架构建,采用模块化设计理念,将不同功能划分为独立的Django应用。核心API架构遵循RESTful设计原则,通过ViewSet和APIView实现资源的CRUD操作。

Docker Compose架构

主要后端模块结构如下:

核心API实现模式

1. 基础视图实现

doccano后端主要使用两种视图模式:generics.ListCreateAPIView用于资源列表和创建,APIView用于自定义复杂逻辑。

示例代码examples/views/example.py

class ExampleList(generics.ListCreateAPIView):
    serializer_class = ExampleSerializer
    permission_classes = [IsAuthenticated & (IsProjectAdmin | IsProjectStaffAndReadOnly)]
    filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
    ordering_fields = ("created_at", "updated_at", "score")
    search_fields = ("text", "filename")
    model = Example
    filterset_class = ExampleFilter
    
    @property
    def project(self):
        return get_object_or_404(Project, pk=self.kwargs["project_id"])
    
    def get_queryset(self):
        member = get_object_or_404(Member, project=self.project, user=self.request.user)
        if member.is_admin():
            return self.model.objects.filter(project=self.project)
        # 普通成员只能访问分配给自己的示例
        queryset = self.model.objects.filter(project=self.project, assignments__assignee=self.request.user)
        if self.project.random_order:
            queryset = queryset.order_by("assignments__id")
        return queryset

2. URL路由配置

URL路由采用集中式管理,通过urls.py文件定义API端点与视图的映射关系。

示例代码backend/api/urls.py

from django.urls import path
from .views import TaskStatus

urlpatterns = [
    path(route="tasks/status/<task_id>", view=TaskStatus.as_view(), name="task_status"),
]

3. 权限控制机制

权限系统基于Django REST框架的权限类实现,结合项目角色管理细粒度访问控制。

权限类组合示例

permission_classes = [IsAuthenticated & (IsProjectAdmin | IsProjectStaffAndReadOnly)]

其中IsProjectAdminIsProjectStaffAndReadOnly定义在projects/permissions.py中,实现了基于项目角色的权限检查。

实战:扩展自定义API端点

步骤1:创建视图类

假设我们需要添加一个批量分配示例的API端点,可以创建如下视图:

# File: backend/examples/views/assignment.py
class BulkAssignment(APIView):
    serializer_class = AssignmentSerializer
    permission_classes = [IsAuthenticated & IsProjectAdmin]

    def post(self, *args, **kwargs):
        try:
            strategy_name = StrategyName[self.request.data["strategy_name"]]
        except KeyError:
            return Response(
                {"detail": "Invalid strategy name"},
                status=status.HTTP_400_BAD_REQUEST,
            )
        
        # 实现批量分配逻辑
        bulk_assign(
            project_id=self.kwargs["project_id"],
            strategy_name=strategy_name,
            member_ids=workload_allocation.member_ids,
            weights=workload_allocation.weights,
        )
        return Response(status=status.HTTP_201_CREATED)

步骤2:配置URL路由

在应用的urls.py中添加新端点:

# File: backend/examples/urls.py
from django.urls import path
from .views.assignment import BulkAssignment

urlpatterns = [
    # 其他URL配置...
    path('projects/<int:project_id>/assignments/bulk/', BulkAssignment.as_view(), name='bulk-assignment'),
]

步骤3:实现业务逻辑

将核心业务逻辑封装在专门的用例模块中,保持视图层简洁:

# File: backend/examples/assignment/usecase.py
def bulk_assign(project_id, strategy_name, member_ids, weights):
    """
    批量分配示例给项目成员
    """
    project = get_object_or_404(Project, pk=project_id)
    members = Member.objects.filter(id__in=member_ids, project=project)
    
    # 根据选择的策略分配示例
    strategy = get_strategy(strategy_name)
    assignments = strategy.assign(project.examples.all(), members, weights)
    
    Assignment.objects.bulk_create(assignments)
    return assignments

测试与调试

API端点测试

使用Django REST框架自带的测试工具进行API测试:

# File: backend/examples/tests/test_api.py
from rest_framework.test import APITestCase
from rest_framework import status
from django.urls import reverse

class ExampleAPITest(APITestCase):
    def setUp(self):
        # 创建测试用户、项目和示例数据
        self.user = User.objects.create_user(username='test', password='testpass')
        self.client.login(username='test', password='testpass')
        self.project = Project.objects.create(name='Test Project', owner=self.user)
        
    def test_list_examples(self):
        url = reverse('example-list', kwargs={'project_id': self.project.id})
        response = self.client.get(url)
        self.assertEqual(response.status_code, status.HTTP_200_OK)

权限测试

验证不同角色用户对API的访问权限:

def test_assignment_permissions(self):
    # 测试非管理员用户不能执行批量分配
    non_admin_user = User.objects.create_user(username='nonadmin', password='pass')
    Member.objects.create(user=non_admin_user, project=self.project, role='annotator')
    self.client.login(username='nonadmin', password='pass')
    
    url = reverse('bulk-assignment', kwargs={'project_id': self.project.id})
    response = self.client.post(url, {'strategy_name': 'ROUND_ROBIN', 'workloads': []})
    self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)

部署与扩展

配置生产环境

生产环境部署使用Docker Compose,配置文件位于docker/docker-compose.prod.yml,采用三层架构:

  • Nginx作为反向代理
  • Django应用服务器
  • Celery处理异步任务

性能优化建议

1.** 数据库优化 :为频繁查询的字段添加索引,如示例表的project_id和assignments字段 2. 缓存策略 :使用Redis缓存常用数据,如项目配置和标签定义 3. 异步处理 **:将耗时操作(如数据导入导出)通过Celery异步执行,实现代码位于backend/data_import/celery_tasks.pybackend/data_export/celery_tasks.py

总结与扩展阅读

通过本文介绍的方法,你可以基于Django REST框架扩展doccano的API功能。关键要点包括:

  • 遵循项目现有模块化结构
  • 使用Django REST框架的通用视图和权限类
  • 将业务逻辑与视图分离,保持代码清晰
  • 添加完善的测试用例确保API可靠性

深入学习可参考以下资源:

【免费下载链接】doccano 【免费下载链接】doccano 项目地址: https://gitcode.com/gh_mirrors/doc/doccano

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值