一步步完整搭建一個圖紙管理系統(Django+Vue3)

来源:https://www.cnblogs.com/lightwower/archive/2023/05/24/17428880.html
-Advertisement-
Play Games

# 圖紙管理系統 ## 一、初步構建後端項目 ### 1、打開已經創建好的虛擬環境:激活activate(推薦使用虛擬環境)並創建項目 ![](https://img2023.cnblogs.com/blog/2240937/202305/2240937-20230524164953360-1300 ...


圖紙管理系統

一、初步構建後端項目

1、打開已經創建好的虛擬環境:激活activate(推薦使用虛擬環境)並創建項目

2、導入vs code中,項目環境大致如下:

需要將終端改成虛擬環境的解釋器後,簡單試運行:

3、創建子app(圖紙管理系統模塊)

由於我們把子項目都放在apps裡面了(方便統一管理)所以註冊要加入一段配置

4、創建資料庫

一定要註意格式

5、設置Django連接資料庫

(1)安裝pymysql

pip install pymysql

(2)gveInformationSystem/settings中進行相關配置

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'StudentDB',
        'USER': 'root',
        'PASSWORD': '123456',
        'HOST': 'localhost',
        'PORT': '3306',
    }
}

(3)需要在init.py導入pymysql

6、創建資料庫表內容

(在:apps/DrawingManagementSystem/models.py)

from django.db import models


# Create your models here.
# === 圖紙管理系統 models
# 感測器分類--sensor, 項目--project, 資料-data, 圖紙信息-drawing

# 公有創建時間和修改時間
class TimestampMode(models.Model):
    """
    An abstract base class model that provides selfupdating ``created`` and ``modified`` fields.
    """
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)

    class Meta:
        abstract = True  # it's very important to add this line


# === 感測器類 --- Sensor:Id,name,created,modified
class Sensor(TimestampMode):
    sensor_name = models.CharField(verbose_name="感測器名稱", max_length=50, unique=True, null=False, blank=False)

    # create_time = models.DateTimeField(default=timezone.now().replace(microsecond=0))

    class Meta:
        db_table = "Draw_Sensor"
        managed = True
        app_label = "DrawingManagementSystem"

    def __str__(self):
        return "%s" % (self.sensor_name)


# === 項目類 --- project:Id,name,created,modified
class Project(TimestampMode):
    project_name = models.CharField(verbose_name="項目名稱", max_length=50, unique=True, null=False, blank=False)
    sensor = models.ForeignKey(verbose_name="所屬感測器", to=Sensor, on_delete=models.PROTECT)

    class Meta:
        db_table = "Draw_Project"
        managed = True
        app_label = "DrawingManagementSystem"

    def __str__(self):
        return "%s" % (self.project_name)


# === 資料類 --- data:ID,name,created,modified
class Data(TimestampMode):
    data_name = models.CharField(verbose_name="資料名稱", max_length=50, unique=True, null=False, blank=False)
    sensor = models.ForeignKey(verbose_name="所屬感測器", to=Sensor, on_delete=models.PROTECT)
    project = models.ForeignKey(verbose_name="所屬項目", to=Project, on_delete=models.PROTECT)

    class Meta:
        db_table = "Draw_Data"
        managed = True
        app_label = "DrawingManagementSystem"

    def __str__(self):
        return "%s" % (self.data_name)


# === 圖紙信息 --- drawing:ID(Material_code),drawing_name,created,modified,drawing_spec,drawing_page,drawing_client_id,drawing_remark,drawing_version
class Drawing(TimestampMode):
    material_code = models.CharField(verbose_name="物料編號", max_length=50, blank=False)
    sensor = models.ForeignKey(verbose_name="所屬感測器", to=Sensor, on_delete=models.PROTECT)
    project = models.ForeignKey(verbose_name="所屬項目", to=Project, on_delete=models.PROTECT)
    data = models.ForeignKey(verbose_name="所屬資料", to=Data, on_delete=models.PROTECT)
    drawing_name = models.CharField(verbose_name="材料名稱", max_length=50, blank=False)
    drawing_spec = models.CharField(verbose_name="規格/圖紙號", max_length=50, blank=False)
    drawing_page = models.CharField(verbose_name="圖紙頁數", max_length=50, blank=False)
    drawing_client_id = models.CharField(verbose_name="客戶編號", max_length=50)
    drawing_version = models.CharField(verbose_name="版本號", max_length=50, blank=False)
    drawing_remark = models.CharField(verbose_name="備註", max_length=100)
    drawing_url = models.CharField(verbose_name="地址", max_length=100)
    is_deleted = models.IntegerField(verbose_name="邏輯刪除0否1是", max_length=10, blank=False, default=0)

    class Meta:
        db_table = "Draw_Drawing"
        managed = True
        app_label = "DrawingManagementSystem"

    def __str__(self):
        return "%s" % (self.drawing_name)


(1)用指令生成資料庫

python manage.py makemigrations
python manage.py migrate

完成後代碼如下:

7、DRF介面(初步)

(1)DRF的安裝和快速實現

安裝DjangoRestFramework包

pip install djangorestframework==3.13.0

在settings中導入

序列化:負責對象和json格式的相互轉換

​ a獲取數據:對象-->Json返回給前端

​ b添加、修改:json-->對象 存儲在資料庫中

視圖:實現後臺功能的核心

​ 早期:視圖是基於函數--FBV

​ DRF:視圖基於類--CBV

路由:路由的匹配

(2)序列化

創建DrawingManagementSystem\serializer.py文件

from rest_framework import serializers
from DrawingManagementSystem.models import Sensor, Project, Data, Drawing


# ----Sensor序列化類----
class SensorSerialzer(serializers.ModelSerializer):
    class Meta:
        model = Sensor
        fields = "__all__"

# ____Project序列化類____
class ProjectSerialzer(serializers.ModelSerializer):
    class Meta:
        model = Project
        fields = "__all__"

# ____Data序列化類____
class DataSerialzer(serializers.ModelSerializer):
    class Meta:
        model = Data
        fields = "__all__"

# ____Drawing序列化類____
class DrawingSerialzer(serializers.ModelSerializer):
    class Meta:
        model = Drawing
        fields = "__all__"

(3)編寫view.py代碼(apps\DrawingManagementSystem\views.py)

# ====== 導入模塊 ======
from rest_framework.viewsets import ModelViewSet  # 封裝完成的ModelViewset視圖集
from DrawingManagementSystem.models import Sensor, Project, Data, Drawing  # 具體的類
from DrawingManagementSystem.serializer import SensorSerialzer, ProjectSerialzer, DataSerialzer, DrawingSerialzer # 序列化類

# ---Sensor視圖---
class SensorViewSet(ModelViewSet):
    queryset = Sensor.objects.all()
    serializer_class = SensorSerialzer

# ---Project---
class ProjectViewSet(ModelViewSet):
    queryset = Project.objects.all()
    serializer_class = ProjectSerialzer

# ---Data視圖---
class DataViewSet(ModelViewSet):
    queryset = Data.objects.all()
    serializer_class = DataSerialzer

# ---Sensor視圖---
class DrawingViewSet(ModelViewSet):
    queryset = Drawing.objects.all()
    serializer_class = DrawingSerialzer

(4)編寫urls.py代碼(apps\DrawingManagementSystem\urls.py)

# ======導入模塊======
from django.urls import path
from rest_framework.routers import DefaultRouter
from DrawingManagementSystem.views import SensorViewSet, ProjectViewSet, DataViewSet, DrawingViewSet

# ====1.實例化一個 DefaultRouter====
router = DefaultRouter()

# ====2.註冊相應的url====
# 註冊Sensor對象
router.register('Sensors', SensorViewSet, basename='Sensors') # http://127.0.0.1:8080/DrawingApi/v1/Sensors/
# 註冊Sensor對象
router.register('Projects', ProjectViewSet, basename='Projects') # http://127.0.0.1:8080/DrawingApi/v1/Projects/
# 註冊Sensor對象
router.register('Datas', DataViewSet, basename='Datas') # http://127.0.0.1:8080/DrawingApi/v1/Datas/
# 註冊Sensor對象
router.register('Drawings', DrawingViewSet, basename='Drawings') # http://127.0.0.1:8080/DrawingApi/v1/Drawings/

urlpatterns = [

]

# ====3.附加到urlpatterns集合中====
urlpatterns += router.urls

編寫總urls.py代碼(gveInformationSystemBE\urls.py)

from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('DrawingApi/v1/',include('DrawingManagementSystem.urls')),
]

編寫後運行django項目

python manage.py runserver

瀏覽器輸入:http://127.0.0.1:8000/DrawingApi/v1/

可以看到界面如下:

說明簡單後端介面已經完成,可以簡單測試下:

發現存入的時間是北美市區,將gveInformationSystemBE\settings.py中的USE_TZ = True改為:USE_TZ = False

發現存入的時間是帶毫秒:參考解決方法為

或者直接在資料庫軟體中

可以避免存入毫秒的問題

8、DRF進階(增刪改介面、篩選、搜索、分頁)

其實在網址後面加上id,就可以進行數據的刪除修改

(1)DRF的篩選

步驟為:

安裝:pip install django-filter

pip install django-filter==21.1

註冊到installed_apps中

完成filter的篩選類

在apps\DrawingManagementSystem新建filter.py

# =====導入模塊=====
from django_filters import FilterSet
from DrawingManagementSystem.models import Sensor, Project, Data, Drawing


# ---Sensor的Filter類---
class SensorFilter(FilterSet):
    class Meta:
        model = Sensor
        fields = ('sensor_name',) # 感測器名稱


# ---Project的Filter類---
class ProjectFilter(FilterSet):
    class Meta:
        model = Project
        fields = ('project_name', 'sensor') # 項目名稱 所屬感測器


# ---Data的Filter類---
class DataFilter(FilterSet):
    class Meta:
        model = Data
        fields = ('data_name', 'sensor', 'project') # 資料名稱 所屬感測器 所屬項目


# ---Drawing的Filter類---
class DrawingFilter(FilterSet):
    class Meta:
        model = Drawing
        fields = ('drawing_name', 'material_code', 'drawing_spec', 'drawing_client_id')  # 材料名稱、物料編號、規格/圖紙號、客戶編號

在viewset中添加篩選類

# ====== 導入模塊 ======
from rest_framework.viewsets import ModelViewSet  # 封裝完成的ModelViewset視圖集
from DrawingManagementSystem.models import Sensor, Project, Data, Drawing  # 具體的類
from DrawingManagementSystem.serializer import SensorSerialzer, ProjectSerialzer, DataSerialzer, \
    DrawingSerialzer  # 序列化類
from django_filters.rest_framework import DjangoFilterBackend  # 實現篩選的後臺模塊
from DrawingManagementSystem.filter import SensorFilter, ProjectFilter, DataFilter, DrawingFilter


# ---Sensor視圖---
class SensorViewSet(ModelViewSet):
    queryset = Sensor.objects.all()
    serializer_class = SensorSerialzer
    # 設定篩選的後臺
    filter_backends = (DjangoFilterBackend,)
    # 指定篩選的類
    filter_class = SensorFilter

# ---Project---
class ProjectViewSet(ModelViewSet):
    queryset = Project.objects.all()
    serializer_class = ProjectSerialzer
    # 設定篩選的後臺
    filter_backends = (DjangoFilterBackend,)
    # 指定篩選的類
    filter_class = ProjectFilter


# ---Data視圖---
class DataViewSet(ModelViewSet):
    queryset = Data.objects.all()
    serializer_class = DataSerialzer
    # 設定篩選的後臺
    filter_backends = (DjangoFilterBackend,)
    # 指定篩選的類
    filter_class = DataFilter


# ---Sensor視圖---
class DrawingViewSet(ModelViewSet):
    queryset = Drawing.objects.all()
    serializer_class = DrawingSerialzer
    # 設定篩選的後臺
    filter_backends = (DjangoFilterBackend,)
    # 指定篩選的類
    filter_class = DrawingFilter

效果如下:

(2)篩選優化——模糊匹配

# =====導入模塊=====
from django_filters import FilterSet,filters
from DrawingManagementSystem.models import Sensor, Project, Data, Drawing


# ---Sensor的Filter類---
class SensorFilter(FilterSet):
    # 重新需要支持模糊匹配的欄位
    sensor_name = filters.CharFilter(field_name='sensor_name',lookup_expr="icontains")
    class Meta:
        model = Sensor
        fields = ('sensor_name',) # 感測器名稱


# ---Project的Filter類---
class ProjectFilter(FilterSet):
    # 重新需要支持模糊匹配的欄位
    project_name = filters.CharFilter(field_name='project_name', lookup_expr="icontains")
    class Meta:
        model = Project
        fields = ('project_name', 'sensor') # 項目名稱 所屬感測器


# ---Data的Filter類---
class DataFilter(FilterSet):
    # 重新需要支持模糊匹配的欄位
    data_name = filters.CharFilter(field_name='data_name', lookup_expr="icontains")
    class Meta:
        model = Data
        fields = ('data_name', 'sensor', 'project') # 資料名稱 所屬感測器 所屬項目


# ---Drawing的Filter類---
class DrawingFilter(FilterSet):
    # 重新需要支持模糊匹配的欄位
    drawing_name = filters.CharFilter(field_name='drawing_name', lookup_expr="icontains")
    material_code = filters.CharFilter(field_name='material_code', lookup_expr="icontains")
    drawing_spec = filters.CharFilter(field_name='drawing_spec', lookup_expr="icontains")
    drawing_client_id = filters.CharFilter(field_name='drawing_client_id', lookup_expr="icontains")
    class Meta:
        model = Drawing
        fields = ('drawing_name', 'material_code', 'drawing_spec', 'drawing_client_id')  # 材料名稱、物料編號、規格/圖紙號、客戶編號

(3)全局加入篩選後臺

在gveInformationSystemBE\settings.py中加入

# ======= REST Framework全局設置 ===========
REST_FRAMEWORK = {

    # ==== 設置全局的Filter_Backends ====
    'DEFAULT_FILTER_BACKENDS': [
        'django_filters.rest_framework.DjangoFilterBackend',
    ],


}

這樣views.py中就不需要加入

# 設定篩選的後臺
    filter_backends = (DjangoFilterBackend,)

修改後代碼如下:

# ====== 導入模塊 ======
from rest_framework.viewsets import ModelViewSet  # 封裝完成的ModelViewset視圖集
from DrawingManagementSystem.models import Sensor, Project, Data, Drawing  # 具體的類
from DrawingManagementSystem.serializer import SensorSerialzer, ProjectSerialzer, DataSerialzer, \
    DrawingSerialzer  # 序列化類
from DrawingManagementSystem.filter import SensorFilter, ProjectFilter, DataFilter, DrawingFilter


# ---Sensor視圖---
class SensorViewSet(ModelViewSet):
    queryset = Sensor.objects.all()
    serializer_class = SensorSerialzer

    # 指定篩選的類
    filter_class = SensorFilter

# ---Project---
class ProjectViewSet(ModelViewSet):
    queryset = Project.objects.all()
    serializer_class = ProjectSerialzer

    # 指定篩選的類
    filter_class = ProjectFilter


# ---Data視圖---
class DataViewSet(ModelViewSet):
    queryset = Data.objects.all()
    serializer_class = DataSerialzer

    # 指定篩選的類
    filter_class = DataFilter


# ---Sensor視圖---
class DrawingViewSet(ModelViewSet):
    queryset = Drawing.objects.all()
    serializer_class = DrawingSerialzer

    # 指定篩選的類
    filter_class = DrawingFilter

(4)加入搜索

篩選【filter】:一個值只能對應一個欄位,需要django-filter

搜索【search】;一個值能對應多個欄位,DRF自帶

在gveInformationSystemBE\settings.py中加入'rest_framework.filters.SearchFilter',

# ======= REST Framework全局設置 ===========
REST_FRAMEWORK = {

    # ==== 設置全局的Filter_Backends ====
    'DEFAULT_FILTER_BACKENDS': [
        'django_filters.rest_framework.DjangoFilterBackend',
        'rest_framework.filters.SearchFilter',

    ],


}

在apps\DrawingManagementSystem\views.py中加入需要搜索匹配的欄位

# ---Sensor視圖---
class DrawingViewSet(ModelViewSet):
    queryset = Drawing.objects.all()
    serializer_class = DrawingSerialzer

    # 指定篩選的類
    filter_class = DrawingFilter
    # 指定查找匹配的欄位
    search_fields = ('drawing_name', 'material_code', 'drawing_spec', 'drawing_client_id')

結果如下:

(5)加入分頁

有2種,一種為全局

即在在gveInformationSystemBE\settings.py中加入

# ======= REST Framework全局設置 ===========
REST_FRAMEWORK = {

    # ==== 設置全局的Filter_Backends ====
    'DEFAULT_FILTER_BACKENDS': [
        'django_filters.rest_framework.DjangoFilterBackend',
        'rest_framework.filters.SearchFilter',

    ],
    # ===== 設置分頁 ===============
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 10


}

還有一種為:按需分頁

apps\DrawingManagementSystem下新建paginations.py

代碼如下:

# ========== 導入 ===========
from rest_framework.pagination import PageNumberPagination


class MyPageNumberPagination(PageNumberPagination):
    page_size = 5
    page_query_param = "page"
    page_size_query_param = 'size'
    max_page_size = 50

在apps\DrawingManagementSystem\views.py中加入:

from DrawingManagementSystem.paginations import MyPageNumberPagination
###
###
###
# ---Sensor視圖---
class DrawingViewSet(ModelViewSet):
    queryset = Drawing.objects.all()
    serializer_class = DrawingSerialzer
    pagination_class = MyPageNumberPagination

    # 指定篩選的類
    filter_class = DrawingFilter
    # 指定查找匹配的欄位
    search_fields = ('drawing_name', 'material_code', 'drawing_spec', 'drawing_client_id')

效果如下:

9、添加Swagger文檔

記得在setting中註冊

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'DrawingManagementSystem',
    'rest_framework',
    'django_filters',
    'drf_yasg',
]

效果如下:

想要中文註釋

效果如下:


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在 HTML 中,屬性(Attribute)和屬性(Property)是用於描述 HTML 元素的相關特性的術語。 屬性(Attribute)是指在 HTML 標簽中聲明的附加信息。它們以鍵值對的形式出現,用於提供元素的初始狀態或配置選項。屬性的名稱是不區分大小寫的,並且值可以是字元串或布爾值。 例 ...
  • ### GC 優化 #### 1.防止大對象Buffer到記憶體中 **現象**:當大包請求時,YGC 耗時嚴重 **原因**:預設情況下 Zuul2 並不會緩存請求體(DirectByteBuffer),也就意味著它會先發送接收到的請求 Headers 到後端服務,之後接收到請求體再繼續發送到後端服 ...
  • 一、什麼是微服務 微服務是一種技術架構,通常我們可以把它理解為一組可以相互之間協同工作的應用程式或服務,這些應用程式或服務能夠被單獨部署到不同的伺服器中,並且能夠自主運行和維護。 微服務技術只是一個名稱而已,或許我們在日常工作中已經或多或少在使用其中的一種或幾種技術和架構,但我們並沒有將其稱之為微服 ...
  • 汽車之家電商系統誕生在2014年,成長於2016~2019年,並經歷多年雙11、818晚會的洪峰考驗,沉澱了穩定可靠、性能卓越的線上交易能力。隨著業務中台的建設浪潮興起,2019年進入中台化建設階段,輸出其在汽車電商領域五年沉澱的能力,助力汽車電商行業發展,加速企業數字化轉型! ...
  • ## 初步瞭解 ### 總體架構設計 Mybatis 整體框架如下: ![img](https://zhangjiahao-blog.oss-cn-beijing.aliyuncs.com/picgo/202305161021323.png) ##### 介面層 MyBatis 和資料庫的交互有兩種 ...
  • # Java語法基礎 ## 註釋 註釋是對代碼的解釋和說明文字,可以提高程式的可讀性,因此在程式中添加必要的註釋文字十分重要。Java中的註釋分為三種: 單行註釋。單行註釋的格式是使用//,從//開始至本行結尾的文字將作為註釋文字。 ~~~java // 這是單行註釋文字 ~~~ 多行註釋。多行註釋 ...
  • ## 教程簡介 Apache Kafka由Scala寫成。Kafka最初是由LinkedIn開發,並於2011年初開源。2012年10月從Apache Incubator畢業。該項目的目標是為處理實時數據提供一個統一、高通量、低等待的平臺。 Kafka是一個分散式的、分區的、多複本的日誌提交服務。它 ...
  • 最近在壓測一批介面,發現介面處理速度慢的有點超出預期,感覺很奇怪,後面定位發現是資料庫批量保存這塊很慢。 這個項目用的是 mybatis-plus,批量保存直接用的是 mybatis-plus 提供的 saveBatch。 我點進去看了下源碼,感覺有點不太對勁: 繼續追蹤了下,從這個代碼來看,確實是 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...