从0开始,重新赋能造数平台!(2)编写项目模块后端

156 阅读4分钟

编写项目模块后端

今天主要是来编写项目模块的后端部分(curd)

创建app

因为我对于造数功能的理解是,针对某个项目造数据,所以会有一个关联的项目表(其实如果单纯从功能角度上想,也不是非要有“项目”这个维度),大家不需要的可以不添加这个模块

1.在 Django 中,可以使用以下命令来创建一个新的 app:

python manage.py startapp app_name(我的是apitest)

其中,app_name 为你要创建的 app 的名称。

执行上述命令后,Django 会自动生成一个 app 的基本目录结构,包括 models.pyviews.pyurls.py 等文件。

2.接下来,你需要在 settings.py 文件中将你的 app 加入到 INSTALLED_APPS 中:

INSTALLED_APPS = [
    # ...
    'apitest',
]

3.然后,在 urls.py 文件中,你需要为你的 app 添加一个 URL 路由:

from django.urls import path, include

urlpatterns = [
    # ...
    path('apitest/', include('apitest.urls')),
]

在 app_name 目录下,你可以按照需求创建 models.pyviews.pyurls.py 等文件,实现你的 app 的功能。在 models.py 文件中,你可以定义你的数据模型;在 views.py 文件中,你可以定义你的视图函数;在 urls.py 文件中,你可以定义你的 URL 路由。

注意:在 Django 中,每个 app 都应该是自包含的,即每个 app 应该有自己的 models.pyviews.pyurls.py 等文件。这样,可以使得每个 app 的代码更加清晰和易于维护。

model.py文件

from django.db import models#固定引入
from apitest.utils.Validate import validate_unique#自定义的校验方法,下文会提到

#在model中创建的模型类,都可以用命令在数据库生成对应表

class Project(models.Model):
#定义了两个字段 项目名称和项目介绍
    projectName = models.CharField(verbose_name='项目名称', max_length=255,validators=[validate_unique(Project,"projectName")])
    descripTion = models.TextField(verbose_name='项目介绍',blank=True)

    def __str__(self):# 获取项目名称的字符串表示
        return self.projectName

    class Meta:#在admin文件中会用到,可忽略
        verbose_name = '项目'
        verbose_name_plural = '项目'
      

serializer.py文件

from rest_framework import generics, serializers
from .models import Project,RequestsInfo,ScriptStep
#RequestsInfo,ScriptStep是另外定义的model,后续会提到




class ProjectSerializer(serializers.ModelSerializer):
    #脚本数 在项目列表中会显示
    scriptcase_count = serializers.SerializerMethodField()
    class Meta:
        model = Project
        fields = '__all__'

    def get_scriptcase_count(self, obj):#获取脚本数方法
        return obj.script_cases.count()

views.py文件

from rest_framework import generics
from rest_framework.pagination import PageNumberPagination
from rest_framework.views import APIView
from rest_framework.exceptions import ValidationError
from rest_framework.response import Response
from django.http import JsonResponse
from django.db.models import Count,Max
from .models import Project,RequestsInfo,ScriptStep
from .serializer import ProjectSerializer
import json



# 主要使用类视图
class MyPagination(PageNumberPagination):
    page_size = 10
    page_size_query_param = 'page_size'
    page_query_param = 'page'

首先是定义了一个分页器,设置传参是page_size默认是10和page

class ProjectListCreateView(generics.ListCreateAPIView):
    queryset = Project.objects.all()
    serializer_class = ProjectSerializer

    def create(self, request, *args, **kwargs):
        # 获取请求中的项目名称
        project_name = request.data.get('projectName')

        try:
            # 创建新的 Project 对象
            return super().create(request, *args, **kwargs)
        except ValidationError as e:
            # 返回错误响应
            return Response({"code": 400, "message": e.message})

接下来,我们定义了一个 ProjectListCreateView 类,继承自 generics.ListCreateAPIView。这个视图类用于获取 Project 模型的列表,以及创建新的 Project 对象。

在这个视图类中,我们首先指定了 queryset 和 serializer_class 属性。其中,queryset 属性用于指定要查询的 Project 对象集合,serializer_class 属性用于指定使用的序列化器类。

然后,我们重写了 create() 方法,用于在创建新的 Project 对象之前,对请求数据进行校验。具体来说,我们从请求数据中获取 projectName 字段的值,然后判断该名称是否已经存在。如果存在,则返回 400 错误响应,否则调用父类的 create() 方法,创建新的 Project 对象。

class ProjectRetrieveUpdateDestroyView(generics.RetrieveUpdateDestroyAPIView):
    queryset = Project.objects.all()
    serializer_class = ProjectSerializer

    def perform_update(self, serializer):
        # 获取要更新的项目对象

        instance = serializer.instance
       
        # 校验项目名称是否已经存在
        project_name = serializer.validated_data.get('projectName')
       
        if Project.objects.filter(projectName=project_name).exists():
            
            return Response({"code":400,'message': '项目名称已经存在'})

        # 保存更新后的 Project 对象
        instance.projectName = project_name
        serializer.save()
        return Response({"code": 200, 'message': '修改成功'})
    #删除方法
    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        self.perform_destroy(instance)
        return Response({"code":200,'message': '删除成功'})   

接着,我们定义了一个 ProjectRetrieveUpdateDestroyView 类,继承自 generics.RetrieveUpdateDestroyAPIView。这个视图类用于获取、更新和删除指定 ID 的 Project 对象。

在这个视图类中,我们同样指定了 queryset 和 serializer_class 属性。然后,我们重写了 perform_update() 方法,用于在更新 Project 对象之前,对请求数据进行校验。具体来说,我们从序列化器中获取要更新的 Project 对象,然后根据请求数据中的 projectName 字段的值,判断该名称是否已经存在。如果存在,则返回 400 错误响应,否则更新 Project 对象的 projectName 字段的值,并保存更新后的对象。

最后,我们还重写了 destroy() 方法,用于删除指定 ID 的 Project 对象。在这个方法中,我们首先获取要删除的对象,然后调用 perform_destroy() 方法,真正地删除对象。

urls.py文件

from django.urls import path
from .views import ProjectListCreateView, ProjectRetrieveUpdateDestroyView
from apitest import views
urlpatterns = [
#restful风格
    path('projects/', ProjectListCreateView.as_view(), name='project-list-create'),
    path('projects/<int:pk>/', ProjectRetrieveUpdateDestroyView.as_view(), name='project-retrieve-update-destroy'),
    
]

自定义方法 validate_unique

from django.core.exceptions import ValidationError
#唯一性校验
def validate_unique(model,field):
    def validator(value):
        if model.objects.filter(**{field: value}).exists():
            raise ValidationError(f'{field}已经存在')

    return validator

然后项目这块的后端就完成拉~

【觉得这篇文章有用就请给我点赞吧】