Django REST framework使用案例
引用官方的话说:Django REST framework is a powerful and flexible toolkit for building Web APIs.
如果你不太理解restful架构,请参见理解RESTful架构一文
下面以一个简单的学生管理系统示例,简述一下Django REST framework的使用
环境
mac
python2.7.12
django1.10.3
djangorestframework3.5.3
1.示例简述
model分为班级(Classes)、课程(Course)、学生(Student)、成绩(Score)
2.项目初始化
安装djangorestframework3.5.3
pip install djangorestframework
创建项目及app略
配置settings.py
...
INSTALLED_APPS = [
...
'rest_framework', # 必配项
'stuapp',
]
# 打开分页,设置API只能管理员用户访问(可自行选择配置)
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAdminUser',
],
'PAGE_SIZE': 10
}
...
3.创建model
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
SEX_CHOICES = ((1,u'男'), (2,u'女'))
class Classes(models.Model):
"""班级"""
name = models.CharField(max_length=32)
def __unicode__(self):
return self.name
class Student(models.Model):
"""学生"""
name = models.CharField(max_length=16, null=False, verbose_name=u'学生姓名')
sex = models.CharField(max_length=16, choices=SEX_CHOICES, default=1)
classes = models.ForeignKey(Classes)
def __unicode__(self):
return self.name
class Course(models.Model):
"""课程"""
name = models.CharField(max_length=32)
def __unicode__(self):
return self.name
class Score(models.Model):
"""成绩"""
score = models.DecimalField(max_digits=5, decimal_places=2)
student = models.ForeignKey(Student)
course = models.OneToOneField(Course)
def __unicode__(self):
return self.name
4.创建序列化类
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from stuapp.models import *
from rest_framework import serializers
class ClassesSerializer(serializers.ModelSerializer):
class Meta:
model = Classes
fields = ('id', 'name')
class StudentSerializer(serializers.ModelSerializer):
classes = ClassesSerializer(read_only=True)
class Meta:
model = Student
fields = ('id', 'name', 'sex', 'classes')
class CourseSerializer(serializers.ModelSerializer):
class Meta:
model = Course
fields = ('id', 'name')
class ScoreSerializer(serializers.ModelSerializer):
student = StudentSerializer(many=False, read_only=True)
course = CourseSerializer(many=False, read_only=True)
class Meta:
model = Score
fields = ('id', 'score', 'student', 'course')
REST framework提供了2中装饰器来编写视图,
1.基于函数视图的@api_view
2.基于类视图的APIView
5.创建课程(Course)视图(基于函数视图)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response
from stuapp.models import Course
from stuapp.serializers import CourseSerializer
@api_view(['GET', 'POST'])
def CouList(request):
"""
POST 创建课程; GET 获取课程列表
"""
if request.method == 'GET':
course = Course.objects.all()
serializer = CourseSerializer(course, many=True)
return Response(serializer.data)
elif request.method == 'POST':
serializer = CourseSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@api_view(['GET', 'PUT', 'DELETE'])
def CouDetail(request, pk):
"""
GET 获取某课程详情; PUT 更新某课程; DELETE 删除某课程
"""
try:
course = Course.objects.get(pk=pk)
except Course.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
if request.method == 'GET':
serializer = CourseSerializer(course)
return Response(serializer.data)
elif request.method == 'PUT':
serializer = CourseSerializer(course, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
elif request.method == 'DELETE':
course.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
6.创建学生(Student)视图(基于类视图)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from stuapp.models import *
from stuapp.serializers import StudentSerializer
from django.http import Http404
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
class StuList(APIView):
def get(self, request, format=None):
stu = Student.objects.all()
serializer = StudentSerializer(stu, many=True)
return Response(serializer.data)
def post(self, request, format=None):
serializer = StudentSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.data, status=status.HTTP_400_BAD_REQUEST)
class StuDetail(APIView):
def get_object(self, pk):
try:
return Student.objects.get(pk)
except Student.DoesNotExist:
raise Http404
def get(self, request, pk, format=None):
stu = self.get_object(pk)
serializer = StudentSerializer(stu)
return Response(serializer.data)
def put(self, request, pk, format=None):
stu = self.get_object(pk)
serializer = StudentSerializer(stu, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk, format=None):
stu = self.get_object(pk)
stu.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
7.创建班级(Classes)视图(使用Mixins)
使用基于类的视图的最大优点之一是我们可以方便的重用代码。目前我们使用了很多相似的代码来进行了创建/检索/更新/删除操作,这些常见操作被封装在Mixins类中。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from stuapp.models import *
from stuapp.serializers import ClassesSerializer
from rest_framework import mixins
from rest_framework import generics
class ClaList(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView):
queryset = Classes.objects.all()
serializer_class = ClassesSerializer
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
class ClaDetail(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, generics.GenericAPIView):
queryset = Classes.objects.all()
serializer_class = ClassesSerializer
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)
8.创建成绩视图(Score)(使用通用类视图)
使用Mixins编写视图比之前简单了许多,我们仍可以简写代码,此框架为我们提供了通用类视图
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from stuapp.models import Score
from stuapp.serializers import ScoreSerializer
from rest_framework import generics
class ScoList(generics.ListCreateAPIView):
queryset = Score.objects.all()
serializer_class = ScoreSerializer
class ScoDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Score.objects.all()
serializer_class = ScoreSerializer
9.url配置
from django.conf.urls import url
from django.contrib import admin
from stuapp import stuviews
from stuapp import claviews
from stuapp import couviews
from stuapp import scoviews
from rest_framework.urlpatterns import format_suffix_patterns
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^stu/$', stuviews.StuList.as_view()),
url(r'^stu/(?P<pk>[0-9]+)/$', stuviews.StuDetail.as_view()),
]
urlpatterns += [
url(r'^cla/$', claviews.ClaList.as_view()),
url(r'^cla/(?P<pk>[0-9]+)/$', claviews.ClaDetail.as_view()),
]
# 注意,基于函数的装饰器编写的视图,没有as_view()
urlpatterns += [
url(r'^cou/$', couviews.CouList),
url(r'^cou/(?P<pk>[0-9]+)/$', couviews.CouDetail),
]
urlpatterns += [
url(r'^sco/$', scoviews.ScoList.as_view()),
url(r'^sco/(?P<pk>[0-9]+)/$', scoviews.ScoDetail.as_view()),
]
urlpatterns = format_suffix_patterns(urlpatterns)