我正在开展一个 django 项目,其中我需要为一些执行构建一个 rest API,我不太担心模型,因为我只需要根据用户的输入/调用执行执行。
这是我的情况:
最重要的是部署(我项目中的一个应用程序)
在获取请求时,用户将获得其所有部署(对象)的列表。
用户将向/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。
为了构建 REST API 并处理传入数据的验证和执行,Django REST Framework (DRF) 提供了一套强大且易用的工具。以下是优化的实现建议,包括使用 序列化器、视图类 和 DRF 的功能。
DRF 的 serializers 提供了数据验证和序列化/反序列化的功能,允许您轻松验证输入数据。
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
DRF 提供了基于类的通用视图,例如 ListCreateAPIView,简化了列表和创建的实现。
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}")
GET
POST
perform_create
更新 urls.py 以将视图与 URL 关联。
urls.py
from django.urls import path from .views import DeploymentListView app_name = 'deployments' urlpatterns = [ path('deployments/', DeploymentListView.as_view(), name='deployment_list'), ]
以下是通过 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."] }
使用 DRF 的权限系统保护 API。例如: - IsAuthenticated:要求用户登录。 - IsAdminUser:仅管理员可以访问。
IsAuthenticated
IsAdminUser
在视图中配置权限:
permission_classes = [IsAuthenticated]
如果您需要根据用户输入动态处理外部调用,可以在 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
pytest
django.test.TestCase
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)
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
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,同时能够根据用户请求动态执行操作。