rest_framework视图
rest_framework视图:一步步精简代码
使用APIView实现(返回时使用自己封装的response)
# models.py
from django.db import models
class Student(models.Model):
sid = models.AutoField(primary_key=True)
name = models.CharField(max_length=24)
age = models.IntegerField()
gender = models.CharField(max_length=1)
# urls.py
path('studentAPI/', views.StudentsAPIView.as_view()),
re_path(r'studentAPI/(?P<pk>\d+)/', views.StudentAPIView.as_view()),
# modelserializer.py
from rest_framework import serializers
from drf_day03.models import Student
class StudentModelSerializer(serializers.ModelSerializer):
class Meta:
model = Student
fields = '__all__'
read_only_fields = ('sid', )
# Respon封装类 utils.py
from rest_framework.response import Response
class MyResponse(Response):
def __init__(self, info_status, message, data=''):
self.back_dic = {
'status': info_status, # 请求返回的状态码
'message': message, # 提示信息
'request': data # 返回的数据
}
super().__init__(data=self.back_dic)
# views.py
from rest_framework.views import APIView
from drf_day03.modelserializer import StudentModelSerializer
from drf_day03.models import Student
from drf_day03.utils import MyResponse
"""使用APIView实现5个接口, 使用自己封装的Response方法返回数据"""
class StudentsAPIView(APIView):
def get(self, request):
instance_list = Student.objects.all()
stuModelSerializer = StudentModelSerializer(instance=instance_list, many=True)
return MyResponse(100, 'ok', stuModelSerializer.data)
def post(self, request):
stuModelSerializer = StudentModelSerializer(data=request.data)
if stuModelSerializer.is_valid():
stuModelSerializer.save()
return MyResponse(101, '创建成功', stuModelSerializer.data)
else:
return MyResponse(103, '创建失败', stuModelSerializer.errors)
class StudentAPIView(APIView):
def get(self, request, pk):
instance = Student.objects.filter(pk=pk).first()
if instance:
stuModelSerializer = StudentModelSerializer(instance=instance)
return MyResponse(100, 'ok', stuModelSerializer.data)
else:
return MyResponse(104, '数据不存在')
def put(self, request, pk):
instance = Student.objects.filter(pk=pk).first()
if instance:
stuModelSerializer = StudentModelSerializer(instance=instance, data=request.data)
if stuModelSerializer.is_valid():
stuModelSerializer.save()
return MyResponse(100, '修改成功', stuModelSerializer.data)
else:
return MyResponse(101, '修改失败', stuModelSerializer.errors)
else:
return MyResponse(104, '数据不存在')
def delete(self, request, pk):
Student.objects.filter(pk=pk).delete()
return MyResponse(100, '删除成功')
使用GenericAPIView(需要两个参数:queryset、serializer_class)
# urls.py
path('studentGenericAPI/', views.StudentsGenericAPIView.as_view()),
re_path(r'studentGenericAPI/(?P<pk>\d+)/', views.StudentGenericAPIView.as_view()),
# views.py
from rest_framework.generics import GenericAPIView
from drf_day03.modelserializer import StudentModelSerializer
from drf_day03.models import Student
from drf_day03.utils import MyResponse
class StudentsGenericAPIView(GenericAPIView):
queryset = Student.objects
serializer_class = StudentModelSerializer
def get(self, request):
instance_list = self.get_queryset()
stuModelSerializer = self.get_serializer(instance=instance_list, many=True)
return MyResponse(100, 'ok', stuModelSerializer.data)
def post(self, request):
stuModelSerializer = self.get_serializer(data=request.data)
if stuModelSerializer.is_valid():
stuModelSerializer.save()
return MyResponse(101, '创建成功', stuModelSerializer.data)
else:
return MyResponse(103, '创建失败', stuModelSerializer.errors)
class StudentGenericAPIView(GenericAPIView):
queryset = Student.objects
serializer_class = StudentModelSerializer
def get(self, request, pk):
instance = self.get_object()
if instance:
stuModelSerializer = self.get_serializer(instance=instance)
return MyResponse(100, 'ok', stuModelSerializer.data)
else:
return MyResponse(104, '数据不存在')
def put(self, request, pk):
instance = self.get_object()
if instance:
stuModelSerializer = self.get_serializer(instance=instance, data=request.data)
if stuModelSerializer.is_valid():
stuModelSerializer.save()
return MyResponse(100, '修改成功', stuModelSerializer.data)
else:
return MyResponse(101, '修改失败', stuModelSerializer.errors)
else:
return MyResponse(104, '数据不存在')
def delete(self, request, pk):
Student.objects.filter(pk=pk).delete()
return MyResponse(100, '删除成功')
使用5个视图扩展类实现(继承GenericAPIView以及一个或多个视图扩展类)
- ListModelMixin:查多条数据self.list(request)
- CreateModelMixin:创建一条数据self.create(request)
- UpdateModelMixin:修改一条数据self.update(request, pk)
- RetrieveModelMixin:查询一条数据self.retrieve(request, pk)
- DestroyModelMixin:删除一条数据self.destroy(request, pk)
# urls.py
path('studentGenericAPI2/', views.StudentsGenericAPIView2.as_view()),
re_path(r'studentGenericAPI2/(?P<pk>\d+)/', views.StudentGenericAPIView2.as_view()),
# views.py
from rest_framework.mixins import ListModelMixin, CreateModelMixin, UpdateModelMixin, RetrieveModelMixin, DestroyModelMixin
class StudentsGenericAPIView2(GenericAPIView, ListModelMixin, CreateModelMixin):
queryset = Student.objects
serializer_class = StudentModelSerializer
def get(self, request):
return self.list(request)
def post(self, request):
return self.create(request)
class StudentGenericAPIView2(GenericAPIView, UpdateModelMixin, RetrieveModelMixin, DestroyModelMixin):
queryset = Student.objects
serializer_class = StudentModelSerializer
def get(self, request, pk):
return self.retrieve(request, pk)
def put(self, request, pk):
return self.update(request, pk)
def delete(self, request, pk):
return self.destroy(request, pk)
使用ModelViewSet实现CURD(继承GenericViewSet以及5个视图扩展类,路由的as_view()中必须指定actions)
-
GenericViewSet又继承了ViewSetMixin和GenericAPIView,其核心功能就在ViewSetMixin重写的as_view方法中
def view(request, *args, **kwargs): self = cls(**initkwargs) self.action_map = actions # {'get': 'list', 'post': 'create'} for method, action in actions.items(): # method就是请求方式(get),action就是对应的方法(list) handler = getattr(self, action) # 通过反射获取请求方式对应方法的内存地址 setattr(self, method, handler) # 对象.get = list、对象.post=create # for循环执行完毕后对象.get就指向了list的内存地址,对象.post就指向了create的内存地址 # 我们可以通过继承ViewSetMixin的视图类来实现多个接口指向同一个类视图执行不同的方法
# urls.py
path('studentModelViewSet/', views.StudentsModelViewSet.as_view(
actions={'get': 'list', 'post': 'create'})),
re_path(r'studentModelViewSet/(?P<pk>\d+)/', views.StudentsModelViewSet.as_view(
actions={'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
# views.py
from rest_framework.viewsets import ModelViewSet
class StudentsModelViewSet(ModelViewSet):
queryset = Student.objects
serializer_class = StudentModelSerializer