Python3 - Django rest_framework实现 API
一、什么是REST
面向资源是REST最明显的特征,资源是一种看待服务器的方式,将服务器看作是由很多离散的资源组成。每个资源是服务器上一个可命名的抽象概念。因为资源是一个抽象的概念,所以它不仅仅能代表服务器文件系统中的一个文件、数据库中的一张表等等具体的东西,可以将资源设计的要多抽象有多抽象,只要想象力允许而且客户端应用开发者能够理解。
与面向对象设计类似,资源是以名词为核心来组织的,首先关注的是名词。一个资源可以由一个或多个URI来标识。URI既是资源的名称,也是资源在Web上的地址。对某个资源感兴趣的客户端应用,可以通过资源的URI与其进行交互。对于同一个资源的一组不同的操作。资源是服务器上一个可命名的抽象概念,资源是以名词为核心来组织的,首先关注的是名词。
REST要求,必须通过统一的接口来对资源执行各种操作。对于每个资源只能执行一组有限的操作。(7个HTTP方法:GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS)
二、什么是RESTful
API符合REST架构设计的API。
概念不多说了,具体通过下面的一个简单例子看看Django框架是怎么实现RESTful。
三、rest_framework模块
使用pip命令下载:pip3 install djangorestframework
创建项目: 之前的博客已经详细介绍了创建django项目的方法,这里不再多说。
打开settings.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
30INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'apitest', # 添加apitest app
'rest_framework', # 添加rest_framework
]
#增加一段REST_FRAMEWORK配置
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
# 'DEFAULT_PAGINATION_CLASS': 'utils.pagination.LinkHeaderPagination',
# 分页条数
'PAGE_SIZE': 3,
# 权限
'DEFAULT_AUTHENTICATION_CLASSES': (),
# 重构renderer
'DEFAULT_RENDERER_CLASSES': ('utils.function.CustomJsonRenderer',),
# 配置过滤
'DEFAULT_FILTER_BACKENDS': (
'rest_framework.filters.DjangoFilterBackend',
'rest_framework.filters.SearchFilter',
)
}- 打开model.py,创建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
26from django.db import models
# Create your models here.
class Grade(models.Model):
g_name = models.CharField(max_length=20)
g_create_time = models.DateTimeField(auto_now_add=True)
class Meta:
db_table = 'grade'
class Student(models.Model):
s_name = models.CharField(max_length=20, null=False, unique=True)
s_create_time = models.DateTimeField(auto_now_add=True)# 添加是创建 不可更改
s_operate_time = models.DateTimeField(auto_now=True)
s_img = models.ImageField(upload_to='upload', null=True)
g = models.ForeignKey(Grade)
s_python = models.IntegerField(null=True)
s_html = models.IntegerField(null=True)
delete = models.BooleanField(default=False)
class Meta:
db_table = 'student'
def __unicode__(self):
return '%s: %s' % (self.s_name, self.s_python)
app/urls.py 配置API路由
1
2
3
4
5
6
7
8from rest_framework.routers import SimpleRouter
# 自定义router路由
router = SimpleRouter()
router.register(r'^api/student', api_views.api_student)
router.register(r'^api/grade', api_views.api_grade)
urlpatterns += router.urls创建serializer.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
44from collections import OrderedDict
from rest_framework import serializers, response
from app.models import Student, Grade
class StudentSerializer(serializers.ModelSerializer):
# 自定义错误信息
s_name = serializers.CharField(max_length=20,error_messages={
'blank': '姓名不能为空',
})
class Meta:
# 指定model
model = Student
# 需要展示的字段
fields = ['id','s_name', 's_html','s_python','s_img' ,'g']
# 重写方法显示班级名称信息
def to_representation(self, instance):
# 循环序列化出学生对象
data = super().to_representation(instance)
# 给学生对象添加一个班级名称字段
data['g_name'] = instance.g.g_name
return data
class GradeSerializer(serializers.ModelSerializer):
# student_set = StudentSerializer(many=True)
class Meta:
model = Grade
# fields = ['g_name', 'student_set']
fields = ['id', 'g_name']
def do_update(self, instance, validated_data):
instance.g_name = validated_data['g_name']
instance.save()
data = self.to_representation(instance)
return data视图文件 api_views.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
58from rest_framework import mixins, viewsets
from rest_framework.response import Response
from app.filters import StudentFilter, GradeFilter
from app.models import Student, Grade
from app.serializer import StudentSerializer, GradeSerializer
class api_student(mixins.ListModelMixin,
mixins.CreateModelMixin,
mixins.UpdateModelMixin,
mixins.RetrieveModelMixin,
mixins.DestroyModelMixin,
viewsets.GenericViewSet):
# 查询学生的所有信息
queryset = Student.objects.filter(delete=0)
# 序列化学生的所有信息
serializer_class = StudentSerializer
# 过滤
filter_class = StudentFilter
# 子类重构父类函数, 实现过滤
def get_queryset(self):
return self.queryset.order_by('id')
# 软删除 更改数据库数据, 不显示在前端
def perform_destroy(self, instance):
instance.delete = True
instance.save()
class api_grade(mixins.ListModelMixin,
mixins.UpdateModelMixin,
mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
viewsets.GenericViewSet):
# 查询课程所有信息
queryset = Grade.objects.all()
# 序列化所有课程信息
serializer_class = GradeSerializer
# 过滤
filter_class = GradeFilter
def update(self, request, *args, **kwargs):
# 获取当前对象
instance = self.get_object()
# 序列化对象, 调用重写的方法
serializer = self.serializer_class(instance, request.data)
serializer.is_valid(raise_exception=True)
# 调用重写的 do_update方法 保存数据
serializer.do_update(instance, request.data)
data = serializer.data
data['code'] = 200
data['msg'] = '请求成功'
return Response(data)api/student/返回结果:
1 | { |
评论系统未开启,无法评论!