DjangoRestfulFramework文档
https://q1mi.github.io/Django-REST-framework-documentation/#django-rest-framework
一 DRF初始
1.安装
pip install djangorestframework
2.注册
在INSTALL_APPS=[] 注册
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
]
# 后续DRF相关配置在这里填充
REST_FRAMEWORK={
}
3.Django原生与DRF编写api接口对比
1)使用Django原生编写api接口(CBV模式,使用View视图)
① 路由
from django.urls import path, include, re_path
from stuorg.views import StudentView,StudentInfoView
urlpatterns = [
path('org/students/',StudentView.as_view()), # 获取 添加学生
re_path('org/students/(?P<pk>\d+)',StudentInfoView.as_view()) # 修改 删除学生
]
②视图类编写
import json
from django.views import View
from XuLieHua.models import Students
from django.http.response import JsonResponse
class StudentView(View):
# 获取学生信息
def get(self,request):
stus=Students.objects.values()
print(f'*******所有学生:{stus} \n {type(stus)}')
return JsonResponse(list(stus),safe=False)
# 添加学生
def post(self,request):
# 1.获取客户端数据
try:
data=json.loads(request.body) #
print(f'客户端请求数据:{data} \n{type(data)}')
name = data.get("name")
sex = data.get('sex')
age = data.get('age')
print(f'-----------------------------------age:{age}')
classmate = data.get('classmate')
description = data.get('description')
except Exception as e:
return JsonResponse({"error":f"客户端数据有误{e}"},status=400)
# 2.添加学生
try:
new_stu=Students.objects.create(name=name,sex=sex,age=age,classmate=classmate,description=description)
return JsonResponse({'code':"添加成功","data":str(new_stu)},status=200)
except Exception as e:
return JsonResponse({'code':f"服务端,提交数据失败{e}"},status=500)
class StudentInfoView(View):
# 获取一个学生
def get(self,request,pk):
try:
stu=Students.objects.get(pk=pk)
return JsonResponse(str(stu),safe=False,status=201)
except Exception as e:
return JsonResponse({"error": f"服务端返回数据错误{e}"}, status=500)
# 修改学生信息
def put(self,request,pk):
# 1.获取客户端数据
try:
data=json.loads(request.body)
except Exception as e:
return JsonResponse({"error":f"客户端数据有误{e}"},status=400)
# 2.查询要修改的用户
try:
stu_org=Students.objects.get(pk=pk)
except Exception as e:
return JsonResponse({"error": f"不存在该pk用户 {e}"}, status=500)
stu_org.name=data.get('name')
stu_org.sex = data.get('sex')
stu_org.age = data.get('age')
stu_org.classmate = data.get('classmate')
stu_org.description = data.get('description')
stu_org.save()
return JsonResponse(str(stu_org), safe=False, status=200)
# 删除学生
def delete(self,request,pk):
try:
Students.objects.get(pk=pk).delete()
return JsonResponse({"message": f"删除成功!"}, status=200)
except Exception as e:
return JsonResponse({"error": f"删除失败,不存在该pk用户 {e}"}, status=500)
2)使用DRF编写api接口 (使用ModelViewSet)
① 路由
from rest_framework.routers import DefaultRouter
from . import views
router=DefaultRouter() # 创建视图类
router.register('api/students',views.StudentModelViewSet,basename='students') # 路由注册
# basename:用于创建url的基础名字
# 注意:地址后面不需要加 /
urlpatterns = [
]+router.urls
② 创建序列化器文件
studrf/serializers.py
from rest_framework import serializers
from XuLieHua.models import Students
class StudentModelSerializer(serializers.ModelSerializer):
class Meta:
model=Students
fields="__all__"
③视图函数
DRF中有两个视图类:APIView ModelViewSet
区别:
①APIView需要手动编写CRUD操作,ModelViewSet则根据模型蹄冻了默认的crub操作
②ModelViewSet将查询和序列化器结合在一起,是数据转换更加容易
③APIView允许开发人员完全控制响应内容,有更高的灵活性。ModelViewSet则提供了默认的行为,在大多数情况下都可以满足需求
from rest_framework.viewsets import ModelViewSet
from .serializers import StudentModelSerializer
from XuLieHua.models import Students
class StudentModelViewSet(ModelViewSet):
queryset=Students.objects.all() # 需要的字段
serializer_class=StudentModelSerializer # 通过序列化器转换数据
浏览器访问:
二 drf中的视图
1. 两个基类
1)APIView
APIView继承了Django的View视图,重写了as_view()和dispath()方法。增加功能:
① as_view() : 去掉了crsftoken验证。一般前后端分离的项目不用该认证,常用jwt验证
②dispath():在请求发送前,增加版本管理、限流、认证、序列化等功能。
示例:
from rest_framework.views import APIView
from rest_framework.response import Response
from XuLieHua.models import Students
class StudentsView(APIView):
def get(self,requests,id=None):
students=Students.objects.all().values()
print(students)
return Response({"code":200,"data":students})
def post(self,requests):
stu=requests.data
print(stu,type(stu))
try:
stu_new=Students.objects.create(name=stu["name"],sex=stu['sex'],age=stu['age'],classmate=stu['classmate'],description=stu['description'])
return Response({"code": 200,
"message": "添加新同学成功!",
"data": {"id": stu_new.id,
"name": stu_new.name,
"sex": stu_new.sex,
"age": stu_new.age,
"classmate": stu_new.classmate,
"description": stu_new.description
}
}
)
except Exception as e:
print(e)
return Response({"code":1001,"error":"error"})
def delete(self,requests,id):
# 删除一个学生
print(f'删除学生id:{id}')
try:
Students.objects.get(id=id).delete()
return Response({"code":200,"message":f"删除学生(id={id})成功!"})
except Exception as e:
print(e)
print(type(e))
return Response(
{"code":1001,"error":"删除学生失败","detail":str(e)}
)
def put(self,requests,id):
# 修改学生(全部信息)
# 获取请求数据
data=requests.data
print(f'请求数据:\n{data}')
print(type(data))
name=data["name"]
sex = data["sex"]
sex2 = data["sex2"]
age = data["age"]
classmate = data["classmate"]
description=data["description"]
try:
new_stu=Students.objects.filter(id=id).update(name=name,sex=sex,sex2=sex2,age=age,classmate=classmate,description=description)
return Response({"code":200,
"message":f"修改学生(id={id})成功!",
"data": new_stu
})
except Exception as e:
return Response({"code": 1001,
"message": f"修改学生失败!",
"detail":str(e)
})
def patch(self,requests,id):
# 修改学生(部分信息)
# 获取请求数据
data = requests.data
print(f'请求数据:\n{data}')
print(type(data))
sex = data["sex"]
try:
new_stu = Students.objects.filter(id=id).update(sex=sex)
return Response({"code": 200,
"message": f"修改学生(id={id})成功!",
"data": new_stu
})
except Exception as e:
return Response({"code": 1001,
"message": f"修改学生失败!",
"detail": str(e)
})
from django.urls import path,re_path
from StudayAPIView.views import StudentsView
urlpatterns = [
path('students/',StudentsView.as_view()),
re_path('students/(?P<id>\d)/',StudentsView.as_view())
]
测试5个接口:
2)GenericAPIView
继承了APIView,增加了get_queryset() 和get_serlilzars()