使用 django-rest-framework 框架编写接口与页面
Published in:2023-05-09 |
Words: 3.7k | Reading time: 19min | reading:

使用 django-rest-framework 框架编写接口与页面

基础环境搭建

  • 1.python 基础环境与第三方库搭建
    • python 基础环境安装,地址
1
https://www.python.org/downloads/
- 开发工具使用 Pycharm 或 Anaconda
  • 2.第三方库下载安装
1
2
3
4
5
pip install django-restframework-swagger
pip install django-rest-framework
pip install django-rest-framework-jwt
# 或者
pip install -r requirements.txt
  • 3.simpleui 下载安装
1
2
git clone https://github.com/newpanjing/simpleui_demo
python manage.py runserver 8000 #运行

或者使用 Docker 构建

1
2
3
docker pull newpanjing/simpleui_demo

docker run -p 8080:8080 newpanjing/simpleui_demo

rest-framework-django 概述

Django’s class-based views are a welcome departure from the old-style views.

Django REST framework is a powerful and flexible toolkit for building Web APIs.

  • Some reasons you might want to use REST framework:

  • The Web browsable API is a huge usability win for your developers.

  • Authentication policies including packages for OAuth1a and OAuth2.

  • Serialization that supports both ORM and non-ORM data sources.

  • Customizable all the way down - just use regular function-based views if you don’t need the more powerful features.

  • Extensive documentation, and great community support.

  • Used and trusted by internationally recognised companies including Mozilla, Red Hat, Heroku, and Eventbrite.

框架安装

1
pip install djangorestframework

项目配置

  • 1.setteings.py 配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
"""
Django settings for shellapi project.

Generated by 'django-admin startproject' using Django 2.1.7.

For more information on this file, see
https://docs.djangoproject.com/en/2.1/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.1/ref/settings/
"""

import os

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '&%up9@!s_$$4(qurnori=vit2#kg!bzs$_+m64^j$2-vzibx&p'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = ['*', ]

# Application definition

INSTALLED_APPS = [
'simpleui',# simpleui 框架
'drf_spectacular',
'drf_spectacular_sidecar',
"rest_framework",
"rest_framework_swagger",
'import_export',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'shell_sc',
'drf_yasg', #swagger-ui
]

MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'shellapi.urls'

TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]

WSGI_APPLICATION = 'shellapi.wsgi.application'

# Database 需提前安装pymysql
# https://docs.djangoproject.com/en/2.1/ref/settings/#databases

DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
# }
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'sh_data',
'USER': 'root',
'PASSWORD': '1111',
'HOST': '111.2.3.4',
'PORT': '3306',
# 'NAME': '',
'OPTIONS': {
"init_command": "SET foreign_key_checks = 0;",
},
}
}

# Password validation
# https://docs.djangoproject.com/en/2.1/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]

# Internationalization
# https://docs.djangoproject.com/en/2.1/topics/i18n/

LANGUAGE_CODE = 'zh-hans'
# LANGUAGE_CODE = 'en-us'
# LANGUAGE_CODE = 'ja'


TIME_ZONE = 'Asia/Shanghai'

USE_I18N = True

USE_L10N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.1/howto/static-files/

STATIC_URL = '/static/'

# STATICFILES_DIRS = [
# os.path.join(BASE_DIR, "static"),
# ]
STATIC_ROOT = os.path.join(BASE_DIR, "static")

# simpleui 设置

# 首页配置
# SIMPLEUI_HOME_PAGE = 'https://www.baidu.com'
# 首页标题
SIMPLEUI_HOME_TITLE = '后台管理'
# 首页图标,支持element-ui的图标和fontawesome的图标
SIMPLEUI_HOME_ICON = 'el-icon-date'

# 设置simpleui 点击首页图标跳转的地址
SIMPLEUI_INDEX = '/'

# 首页显示服务器、python、django、simpleui相关信息
SIMPLEUI_HOME_INFO = False

# 首页显示快速操作
SIMPLEUI_HOME_QUICK = True

# 首页显示最近动作
SIMPLEUI_HOME_ACTION = False
# SIMPLEUI_HOME_INFO = False
# 自定义SIMPLEUI的Logo
# SIMPLEUI_LOGO = 'https://avatars2.githubusercontent.com/u/13655483?s=60&v=4'

# 登录页粒子动画,默认开启,False关闭
# SIMPLEUI_LOGIN_PARTICLES = False

# 让simpleui 不要收集相关信息
SIMPLEUI_ANALYSIS = True

# 自定义simpleui 菜单
SIMPLEUI_CONFIG = {
# 在自定义菜单的基础上保留系统模块
'system_keep': False,
'menus': [
{
'app': 'shell_sc',
'name': '接口测试',
'icon': 'fas fa-user-shield',
'models': [{
'name': '脚本调用',
# 注意url按'/admin/应用名小写/模型名小写/'命名。
'icon': 'fa fa-surprise',
'url': '/admin/shell_sc/shellmodel/'
}]
},
]
}

# 是否显示默认图标,默认=True
# SIMPLEUI_DEFAULT_ICON = False

# 图标设置,图标参考:
SIMPLEUI_ICON = {
'接口测试': 'fab fa-apple',
# '员工管理': 'fas fa-user-tie'
}

# 指定simpleui 是否以脱机模式加载静态资源,为True的时候将默认从本地读取所有资源,即使没有联网一样可以。适合内网项目
# 不填该项或者为False的时候,默认从第三方的cdn获取

SIMPLEUI_STATIC_OFFLINE = True

# 设置上传目录
MEDIA_ROOT = os.path.join(BASE_DIR, '../cml')
# 设置前缀
MEDIA_URL = '../../cml/'

# 默认主题 设置
SIMPLEUI_DEFAULT_THEME = 'x-blue.css'

# django 3.2要配置
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

# swagger-ui
REST_FRAMEWORK = {
# YOUR SETTINGS
'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
'DEFAULT_PERMISSION_CLASSES': (
# 'rest_framework.permissions.IsAuthenticated',
'rest_framework.permissions.AllowAny',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
# 'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
# 'rest_framework.authentication.BasicAuthentication',
# 'rest_framework.authentication.SessionAuthentication',
# 'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.FormParser',
'rest_framework.parsers.MultiPartParser',
'rest_framework.parsers.JSONParser',
],
# 全局配置异常模块
# 'EXCEPTION_HANDLER': 'utils.exception.custom_exception_handler',
# # 修改默认返回JSON的renderer的类
# 'DEFAULT_RENDERER_CLASSES': (
# 'rendererresponse.customRenderer',
# ),
}

SPECTACULAR_SETTINGS = {
'SECURITY_DEFINITIONS': {
"basic": {
'type': 'apiKey',
'in': 'header',
'name': 'Authorization',
}
},
# 如果需要登录才能够查看接口文档, 登录的链接使用restframework自带的.
'LOGIN_URL': 'rest_framework:login',
'LOGOUT_URL': 'rest_framework:logout',
# 'DOC_EXPANSION': None,
# 'SHOW_REQUEST_HEADERS':True,
# 'USE_SESSION_AUTH': True,
# 'DOC_EXPANSION': 'list',
# 接口文档中方法列表以首字母升序排列
'APIS_SORTER': 'alpha',
# 如果支持json提交, 则接口文档中包含json输入框
'JSON_EDITOR': True,
# 方法列表字母排序
'OPERATIONS_SORTER': 'alpha',
'VALIDATOR_URL': None,
'SHOW_REQUEST_HEADERS': True,
}

  • 2.urls.py 文件中 swagger 配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
from django.contrib import admin
from django.conf import settings
from django.urls import path, include, re_path
from django.views.static import serve
from rest_framework import routers, permissions
from drf_yasg.views import get_schema_view
from drf_yasg import openapi

from shell_sc.viewsets import ShellInfoViewSet

router = routers.DefaultRouter()
router.register('shell_sc', ShellInfoViewSet)
# router.register(r'upload', FileViewSet)
schema_view = get_schema_view(
openapi.Info(
title="测试工程API",
default_version='v1.0',
description="测试工程接口文档",
terms_of_service="",
contact=openapi.Contact(email=""),
license=openapi.License(name="MIT License"),
),
public=True,
permission_classes=(permissions.AllowAny,),
)

urlpatterns = [
path('admin/', admin.site.urls),
path('shell_sc/', include('shell_sc.urls')),
# re_path(r"file/(?P<path>.*)$", serve, {"document_root": settings.MEDIA_ROOT}),
# 配置django-rest-framwork API路由
# path('test', views.APIList),
# path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
# 配置drf-yasg路由
path('', include(router.urls)),
path('^swagger(?P<format>\.json|\.yaml)$', schema_view.without_ui(cache_timeout=0), name='schema-json'),
path('swagger', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
path('redoc/', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
]

接口编写

接口编写流程

  • 1.项目构建
1
django-admin startapp book_api_swagger
  • 2.app 构建
1
C:\Users\root\AppData\Roaming\Python\Python38\Scripts\django-admin.exe startapp shellapi
  • 3.Model 文件编写
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from django.db import models

# Create your models here.
from django.db import models


# @admi
class ShellModel(models.Model):
name = models.CharField(help_text="脚本名称", max_length=255)

file = models.FileField(upload_to='upload')

size = models.IntegerField(help_text="大小")

path = models.CharField(help_text="路径", max_length=255)

desc = models.CharField(help_text="脚本描述", max_length=255)

class Meta:
db_table = 'shell_sh'
# 设置表名,默认表名是:应用名称_模型类名
# 带有应用名的表名太长了
# verbose_name = '脚本列表'
# verbose_name_plural = "脚本列表"
verbose_name = '脚本名'
verbose_name_plural = verbose_name

def __str__(self):
return self.name
  • 4.序列化文件编写
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# book_api_swagger/serializers.py
from django.forms import Field
from rest_framework import serializers
from rest_framework.serializers import Serializer

from . import models
from .models import ShellModel


# from .models import APIInfo


class ShellSerializer(serializers.ModelSerializer):
class Meta:
model = ShellModel
fields = "__all__"


class ShellInfoSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = ShellModel
fields = "__all__"

  • 5.viewset 文件编写
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import json

from django.http import HttpResponse
from django.shortcuts import render
# Create your views here.
from rest_framework import viewsets
from rest_framework import generics
from rest_framework.views import APIView

from . import models
from . import serializers


class APIList(generics.ListAPIView):
"""
查看接口列表
"""
queryset = models.APIInfo.objects.all()
serializer_class = serializers.APISerializer


class APIDetail(generics.RetrieveAPIView):
"""
查看接口详细
"""
queryset = models.APIInfo.objects.all()
serializer_class = serializers.APISerializer


class APIDetail(generics.RetrieveUpdateDestroyAPIView):
"""
更新接口内容
"""
queryset = models.APIInfo.objects.all()
serializer_class = serializers.APISerializer


class APIInfoViewSet(viewsets.ModelViewSet):
"""
retrieve:
返回一组(查)

list:
返回所有组(查)

create:
创建新组(增)

delete:
删除现有的一组(删)

partial_update:
更新现有组中的一个或多个字段(改:部分更改)

update:
更新一组(改:全部更改)
"""

queryset = models.APIInfo.objects.all()
serializer_class = serializers.APIInfoSerializer
  • 6.app 中 urls 文件路由配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# from django.urls import path, include
#
import requests
from django.template.defaulttags import url
from django.urls import path, include

from . import viewsets


urlpatterns = [
path('', viewsets.ShellModelList.as_view()),
path('<int:pk>/', viewsets.ShellDetail.as_view()),
path('famous/', viewsets.famous, name='famous'),
]
  • 7.项目 urls 文件配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
router = routers.DefaultRouter()
router.register('shell_sc', ShellInfoViewSet)

urlpatterns = [
path('admin/', admin.site.urls),
path('shell_sc/', include('shell_sc.urls')),
# re_path(r"file/(?P<path>.*)$", serve, {"document_root": settings.MEDIA_ROOT}),
# 配置django-rest-framwork API路由
# path('test', views.APIList),
# path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
# 配置drf-yasg路由
path('', include(router.urls)),
path('^swagger(?P<format>\.json|\.yaml)$', schema_view.without_ui(cache_timeout=0), name='schema-json'),
path('swagger', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
path('redoc/', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
]
  • 8.外部接口调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 外部接口调用
@api_view(['GET'])
def famous(request):
"""
调用外部接口测试
:param request: 请求参数 暂无
:return: 调用接口返回值
"""
url = 'http://localhost:10086/shop/monitor/getOrderCount' # api链接
'''
我用的这个接口没有什么apikey或者参数
如果有的话直接写上参数,类似于这样
apikey = 'chgaxvsf88f3858a15fa4426f4cbdd4d2a02b92ee0747f3'
area = "人生"
areaID = "45"
data = {
"apiKey":apikey,
"area":area,
"areaID":areaID,
}
将数据封装成人家接口定义的格式,请求数据改成以下样子
wb_data = requests.get(url,apikey,data)
'''
wb_data = requests.get(url) # 引入requests库来请求数据
result = wb_data.json() # 将请求的数据转换为json格式
return JsonResponse(json.dumps(result), safe=False) # 用json响应出去,顺便格式化数据

项目接口测试

  • 1.swagger 接口测试地址
1
http://127.0.0.1:8000/swagger
  • 2.后台管理地址
1
http://127.0.0.1:8000/admin
  • 3.测试方式
1
2
3
4
5
# eg:
curl -X 'GET' \
'http://127.0.0.1:8000/shell_sc/4/' \
-H 'accept: application/json' \
-H 'X-CSRFToken: npDP6jrGLiAoUG9ujDsTxCRL2toVaM1EZpRmoNWM9NjtznNnLvtcLgOSkNXw9Wmk'

rest-framework-django 中部分 API 使用

generics

  • 1.list 查询与单个查询 ListCreateAPIView
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 继承了视图基类 GenericAPIView,工具类 ListModelMixin,CreateModelMixin实现群查和单增
class ListCreateAPIView(mixins.ListModelMixin,
mixins.CreateModelMixin,
GenericAPIView):
"""
Concrete view for listing a queryset or creating a model instance.
"""
# 群查
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)

# 单增
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
  • 2.添加
1
2
3
4
5
# 需要什么接口,直接继承就行
# 比如我们在群查,单增的基础上,添加单改接口
class BookListCreateView(ListCreateAPIView, UpdateAPIView):
queryset = models.Book.objects.filter(is_delete=False)
serializer_class = serializers.BookModelSerializer

mixins

mixins : from rest_framework import mixins #导入方式
存放一些增删改查的一些类 增 查 部分修改 更新 删除
CreateModelMixin,ListModelMixin,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
mixins.ListModelMixin

这个是用来显示queryset的数据

mixins.CreateModelMixin

这个用来创建一条model对象

mixins.RetrieveModelMixin

这个是用来显示一个model对象

mixins.DestroyModelMixin

这个是用来删除一个model对象

mixins.UpdateModelMixin

这个是用来更新一个model对象
    1. eg:ListModelMixin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class ListModelMixin(object):
"""
List a queryset.
"""
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())

page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)

serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
  • 2.eg:CreateModelMixin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class CreateModelMixin(object):
"""
Create a model instance.
"""
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

def perform_create(self, serializer):
serializer.save()

def get_success_headers(self, data):
try:
return {'Location': str(data[api_settings.URL_FIELD_NAME])}
except (TypeError, KeyError):
return {}
  • 3.eg:RetriveModelMixin
1
2
3
4
5
6
7
8
class RetrieveModelMixin(object):
"""
Retrieve a model instance.
"""
def retrieve(self, request, *args, **kwargs):
instance = self.get_object()
serializer = self.get_serializer(instance)
return Response(serializer.data)
  • 4.eg:DestroyModelMixin
1
2
3
4
5
6
7
8
9
10
11
class DestroyModelMixin(object):
"""
Destroy a model instance.
"""
def destroy(self, request, *args, **kwargs):
instance = self.get_object()
self.perform_destroy(instance)
return Response(status=status.HTTP_204_NO_CONTENT)

def perform_destroy(self, instance):
instance.delete()
  • 5.eg:UpdateModelMixin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class UpdateModelMixin(object):
"""
Update a model instance.
"""
def update(self, request, *args, **kwargs):
partial = kwargs.pop('partial', False)
instance = self.get_object()
serializer = self.get_serializer(instance, data=request.data, partial=partial)
serializer.is_valid(raise_exception=True)
self.perform_update(serializer)

if getattr(instance, '_prefetched_objects_cache', None):
# If 'prefetch_related' has been applied to a queryset, we need to
# forcibly invalidate the prefetch cache on the instance.
instance._prefetched_objects_cache = {}

return Response(serializer.data)

def perform_update(self, serializer):
serializer.save()

def partial_update(self, request, *args, **kwargs):
kwargs['partial'] = True
return self.update(request, *args, **kwargs)

APIView

1
2
3
4
5
6
7
8
9
10
11
APIView是REST framework提供的所有视图的基类,继承自Django的View类
APIView与View的不同点为:
传入到视图方法中的是REST framework的Request对象,而不是Django的HttpRequeset对象
视图方法可以返回REST framework的Response对象,视图会为响应数据设置(render)符合前端期望要求格式
任何APIException异常都会被捕获到,并且处理成合适格式(json)的响应信息返回给客户端
会重新声明了一个新的as_views方法并在dispatch()进行路由分发前,对请求的客户端进行身份认证、权限检查、流量控制
APIView还新增了如下的类属性:

authentication_classes 列表或元组,身份认证类
permissoin_classes 列表或元组,权限检查类
throttle_classes 列表或元祖,流量控制类
    1. eg 增删改查 APIView
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
from rest_framework.response import Response
from rest_framework.views import APIView

from .models import Students
from .serilizers import StudentsModelSerializers


class StudentsApiview(APIView):

def get(self, request):
# 获取数据集(学生模型对象)
students_data = Students.objects.all()
# 实例化序列化器,得到序列化器对象
ser = StudentsModelSerializers(instance=students_data, many=True)
# 调用序列化器对象的data属性方法获取转换后的数据
data = ser.data
# 响应数据
return Response(data)

def post(self, request):
# 反序列化数据
student = StudentsModelSerializers(data=request.data)
# 校验不通过
if not student.is_valid():
# 返回错误信息
return Response(student.errors)
# 校验通过,保存数据
student.save()
# 响应数据
return Response(student.data)


class StudentDerailApiview(APIView):
# 获取一个学生的信息
def get(self, request, pk):
student = Students.objects.get(pk=pk)
ser = StudentsModelSerializers(instance=student)
return Response(ser.data)

# 修改一个学生的信息
def put(self, request, pk):
instance = Students.objects.get(pk=pk)
ser = StudentsModelSerializers(instance=instance, data=request.data)
if not ser.is_valid():
return Response(ser.errors)
ser.save()
return Response(ser.data)

# 删除一个学生的信息
def delete(self, request, pk):
Students.objects.get(pk=pk).delete()
return Response({'detail': '删除成功!!'})
  • 2.urls 文件统一配置
1
2
3
4
5
6
7
8
9
from django.urls import path, re_path

from .views import StudentsApiview, StudentDerailApiview

urlpatterns = [
path('students/', StudentsApiview.as_view()),
# 单个数据进行操作
re_path('students/(?P<pk>\d+)/', StudentDerailApiview.as_view())
]
  • 3.models 定义
1
2
3
4
5
6
7
8
9
10
11
12
from django.db import models


# Create your models here.
class Students(models.Model):
name = models.CharField(verbose_name='姓名', max_length=255)
classmate = models.IntegerField(verbose_name='班级')
studentID = models.IntegerField(verbose_name='学号')
description = models.TextField(verbose_name='描述')

class Meta:
db_table = 'students'
  • 4.serailizers 定义
1
2
3
4
5
6
7
8
from rest_framework import serializers


class StudentsModelSerializers(serializers.Serializer):
name = serializers.CharField()
classmate = serializers.IntegerField()
studentID = serializers.IntegerField()
description = serializers.CharField()

数据同步与迁移

1
2
python manage.py makemigrations
python manage.py migrate
Prev:
使用 Electron 框架中 http 请求与 Java 后端 websocket 服务端通信
Next:
Android常用脚本