小能豆

Django Rest Framework 仅为执行创建 REST API

py

我正在开展一个 django 项目,其中我需要为一些执行构建一个 rest API,我不太担心模型,因为我只需要根据用户的输入/调用执行执行。

这是我的情况:

  1. 最重要的是部署(我项目中的一个应用程序)

  2. 在获取请求时,用户将获得其所有部署(对象)的列表。

  3. 用户将向/deployments发送一个 POST 请求以及完整的对象:

py { "deployment_name": "dep4", "credentials": "cre4", "project_name": "pro4", "project_id": "004", "cluster_name": "clus4", "zone_region": "zon4", "services": "Single", "configuration": "conf4", "routing": "route4" }

然后我需要使用这些数据,并根据这些数据进行验证和执行。例如,我将利用这些信息,使用第三方 API 在云平台上进行部署。

我对 DRF 的文档感到非常困惑,尤其是有关序列化器的文档。

更新:目前,我正在尝试如何进行 POST:从apiview.py

class DeploymentsList(APIView):
    queryset = DeploymentOnUserModel.objects.all()

    def post(self, request):
        print(request.data)
        DeploymentOnUserModel.objects.create(
            deployment_name=request.data['deployment_name'],
            credentials=request.data['credentials'],
            project_name=request.data['project_name'],
            project_id=request.data['project_id'],
            cluster_name=request.data['cluster_name'],
            zone_region=request.data['zone_region'],
            services=request.data['services'],
            configuration=request.data['configuration'],
            routing=request.data['routing'],
        )
        return Response(request.data)

那么,我如何验证传入的数据/请求?

这是我的部署模型:

class DeploymentOnUserModel(models.Model):
    deployment_name = models.CharField(max_length=256, )
    credentials = models.TextField(blank=False)
    project_name = models.CharField(max_length=150, blank=False)
    project_id = models.CharField(max_length=150, blank=True)
    cluster_name = models.CharField(max_length=256, blank=False)
    zone_region = models.CharField(max_length=150, blank=False)
    services = models.CharField(max_length=150, choices=services)
    configuration = models.TextField()
    routing = models.TextField()

    def save(self, **kwargs):
        if not self.id and self.services == 'Multiple' and not self.routing and not self.configuration:
            raise ValidationError("You must have to provide routing for multiple services deployment.")
        super().save(**kwargs)

来自urls.py:

app_name = 'deployments'

urlpatterns = [
    path('deployments/', apiview.DeploymentsList.as_view(), name='deployment_list'),
    path('deployments/<int:pk>', apiview.DeploymentDetail.as_view(), name='deployment_detail')

]

我应该使用 DRF 的哪种方法和内容来实现我的 API。


阅读 6

收藏
2025-01-14

共1个答案

小能豆

为了构建 REST API 并处理传入数据的验证和执行,Django REST Framework (DRF) 提供了一套强大且易用的工具。以下是优化的实现建议,包括使用 序列化器视图类 和 DRF 的功能。


完整实现步骤

1. 创建序列化器

DRF 的 serializers 提供了数据验证和序列化/反序列化的功能,允许您轻松验证输入数据。

from rest_framework import serializers
from .models import DeploymentOnUserModel

class DeploymentSerializer(serializers.ModelSerializer):
    class Meta:
        model = DeploymentOnUserModel
        fields = '__all__'

    def validate(self, data):
        # 自定义验证逻辑
        if data['services'] == 'Multiple' and not data.get('routing'):
            raise serializers.ValidationError("Routing is required for multiple services deployment.")
        return data

说明

  • 使用 serializers.ModelSerializer 自动生成字段。
  • 自定义 validate 方法以添加跨字段验证逻辑。

2. 使用通用视图类

DRF 提供了基于类的通用视图,例如 ListCreateAPIView,简化了列表和创建的实现。

from rest_framework.generics import ListCreateAPIView
from rest_framework.permissions import IsAuthenticated
from .models import DeploymentOnUserModel
from .serializers import DeploymentSerializer

class DeploymentListView(ListCreateAPIView):
    queryset = DeploymentOnUserModel.objects.all()
    serializer_class = DeploymentSerializer
    permission_classes = [IsAuthenticated]

    def perform_create(self, serializer):
        # 在保存对象之前执行额外操作(例如调用外部 API)
        deployment = serializer.save()
        # 调用第三方 API 或其他操作
        self.trigger_cloud_deployment(deployment)

    def trigger_cloud_deployment(self, deployment):
        # 示例:调用第三方 API 进行云部署
        print(f"Triggering deployment for: {deployment.deployment_name}")

说明

  • ListCreateAPIView 提供了 GETPOST 的支持。
  • perform_create 方法允许您在保存对象之前执行额外逻辑,例如调用第三方 API。

3. 配置 URL

更新 urls.py 以将视图与 URL 关联。

from django.urls import path
from .views import DeploymentListView

app_name = 'deployments'

urlpatterns = [
    path('deployments/', DeploymentListView.as_view(), name='deployment_list'),
]

4. 测试数据验证

以下是通过 POST 请求发送无效数据的示例测试:

curl -X POST http://127.0.0.1:8000/deployments/ \
-H "Content-Type: application/json" \
-d '{
  "deployment_name": "dep4",
  "credentials": "cre4",
  "project_name": "pro4",
  "project_id": "004",
  "cluster_name": "clus4",
  "zone_region": "zon4",
  "services": "Multiple",
  "configuration": "conf4"
}'

响应:

{
  "non_field_errors": ["Routing is required for multiple services deployment."]
}

5. 权限与身份验证

使用 DRF 的权限系统保护 API。例如:
- IsAuthenticated:要求用户登录。
- IsAdminUser:仅管理员可以访问。

在视图中配置权限:

permission_classes = [IsAuthenticated]

6. 视图改进(条件性 API 调用)

如果您需要根据用户输入动态处理外部调用,可以在 perform_create 中添加条件。

def perform_create(self, serializer):
    deployment = serializer.save()
    if deployment.services == 'Single':
        self.trigger_single_service(deployment)
    else:
        self.trigger_multiple_services(deployment)

def trigger_single_service(self, deployment):
    # 处理单服务逻辑
    pass

def trigger_multiple_services(self, deployment):
    # 处理多服务逻辑
    pass

7. 调试与改进

  • 使用 DRF 的内置 Web 浏览 API 测试您的端点。
  • 借助 pytestdjango.test.TestCase 测试验证逻辑。

完整代码总结

models.py

class DeploymentOnUserModel(models.Model):
    deployment_name = models.CharField(max_length=256)
    credentials = models.TextField(blank=False)
    project_name = models.CharField(max_length=150, blank=False)
    project_id = models.CharField(max_length=150, blank=True)
    cluster_name = models.CharField(max_length=256, blank=False)
    zone_region = models.CharField(max_length=150, blank=False)
    services = models.CharField(max_length=150, choices=services)
    configuration = models.TextField()
    routing = models.TextField()

    def save(self, **kwargs):
        if not self.id and self.services == 'Multiple' and not self.routing and not self.configuration:
            raise ValidationError("You must have to provide routing for multiple services deployment.")
        super().save(**kwargs)

serializers.py

class DeploymentSerializer(serializers.ModelSerializer):
    class Meta:
        model = DeploymentOnUserModel
        fields = '__all__'

    def validate(self, data):
        if data['services'] == 'Multiple' and not data.get('routing'):
            raise serializers.ValidationError("Routing is required for multiple services deployment.")
        return data

views.py

class DeploymentListView(ListCreateAPIView):
    queryset = DeploymentOnUserModel.objects.all()
    serializer_class = DeploymentSerializer
    permission_classes = [IsAuthenticated]

    def perform_create(self, serializer):
        deployment = serializer.save()
        self.trigger_cloud_deployment(deployment)

    def trigger_cloud_deployment(self, deployment):
        print(f"Triggering deployment for: {deployment.deployment_name}")

通过这种方式,您可以构建一个验证良好、易于扩展的 API,同时能够根据用户请求动态执行操作。

2025-01-14