DRF-View
控制序列化器的执行(检验、保存、转换数据) 控制数据库查询的执行
APIView是REST framework提供的所有视图的基类,继承自Django的View父类。
APIView与View的不同之处在于:
传入到视图方法中的是REST framework的Request对象,而不是Django的HttpRequeset对象;
视图方法可以返回REST framework的Response对象,视图会为响应数据设置(render)符合前端要求的格式;
任何APIException异常都会被捕获到,并且处理成合适的响应信息;
在进行dispatch()分发前,会对请求进行身份认证、权限检查、流量控制。
请求
request.data 返回解析之后的请求体数据。类似于Django中标准的request.POST和request.FILES属性
request.query_params与Django标准的request.GET相同
响应
Response(data, status=None, template_name=None, headers=None, content_type=None)
data只需传递python的内建类型数据即可,REST framework会使用renderer渲染器处理data。
data不能是复杂结构的数据,如Django的模型类对象,对于这样的数据我们可以使用Serializer序列化器序列化处理后(转为了Python字典类型)再传递给data参数。
参数说明:
data: 为响应准备的序列化处理后的数据;
status: 状态码,默认200;
template_name: 模板名称,如果使用HTMLRenderer 时需指明;
headers: 用于存放响应头信息的字典;
content_type: 响应数据的Content-Type,通常此参数无需传递,REST framework会根据前端所需类型数据来设置该参数。
常用属性:
1).data
传给response对象的序列化后,但尚未render处理的数据
2).status_code
状态码的数字
3).content
经过render处理后的响应数据
- 使用django原生的方法、:
# class GetUserViews(View):
# """
# 使用django原生的方法进行输入
# """
# def get(self,request):
# # 获取Users里的所有数据---》得到一个包括全部内容的查询集
# users_imformation = Users.objects.all()
# # 用for循环取得每一条数据,
# # 将每一条数据中所对应的数据用数据名获取出来放入空列表中
# # 列表最终显示的结果为[{K:V},{K:V}......]
# data = []
# for imformation in users_imformation:
# data.append({
# 'uname':imformation.uname,
# 'uage':imformation.uage,
# 'umobile':imformation.umobile,
# 'ugender':imformation.ugender
# })
#
# return JsonResponse(data, safe=False)
- 使用Drf中APIView的方法:
# class DrfGetUsersViews(APIView):
# """
# 使用drf获取Users的数据
# """
# def get(self,requset):
# # 获取信息---》得到查询集
# datas = Users.objects.all()
# # 进行序列化操作
# serializer_data = Userserializers(datas,many=True)
# # 将序列化对象传递给rest_framework中定义的response进行显示
# return Response(serializer_data.data)
- 使用GenericAPIView: GenericAPIView 继承自APIVIew,主要增加了操作序列化器和数据库查询的方法,作用是为下面Mixin扩展类的执行提供方法支持。通常在使用时,可搭配一个或多个Mixin扩展类。
# class GetAllUsers(GenericAPIView):
# # 设置指定的序列化器
# serializer_class = Userserializers
# # 配置指定的查询集
# queryset = Users.objects.all()
#
# def get(self,request):
# """
# 查询全部信息
# :param request: 请求对象
# :return: json
# """
#
# # 获取全部信息的查询集(从函数外定义的类对象上调用方法--使用self获取对象)
# cx = self.get_queryset()
# # 序列化查询集(从函数外定义的类对象上调用方法--使用self获取对象)
# serializer_datas = self.serializer_class(cx,many=True)
#
# return Response(serializer_datas.data)
class GetChooseUser(GenericAPIView):
# """查询指定正则表达式中的值 /GetChooseUser/1/"""
# queryset = Users.objects.all()
# serializer_class = Userserializers
#
# def get(self,request,pk):
#
# search_imf = self.get_object()
# serializer_datas = self.get_serializer(search_imf)
#
# return Response(serializer_datas.data)
- 使用五大拓展类: ListModelMixin 查多 RetrieveModelMixin 查单一 CreateModelMixin 创建 UpdateModelMixin 更新 DestroyModelMixin 删除
使用拓展类实现create和List:
# class ListAllUsers(ListModelMixin, GenericAPIView, CreateModelMixin):
# queryset = Users.objects.all()
# serializer_class = Userserializers
#
# def get(self,request):
# return self.list(request)
#
# def post(self, request):
# return self.create(request)
-
子类方法:
1) CreateAPIView
提供 post 方法
继承自: GenericAPIView、CreateModelMixin
2)ListAPIView
提供 get 方法
继承自:GenericAPIView、ListModelMixin
3)RetrieveAPIView
提供 get 方法
继承自: GenericAPIView、RetrieveModelMixin
4)DestoryAPIView
提供 delete 方法
继承自:GenericAPIView、DestoryModelMixin
5)UpdateAPIView
提供 put 和 patch 方法
继承自:GenericAPIView、UpdateModelMixin
6)RetrieveUpdateAPIView
提供 get、put、patch方法
继承自: GenericAPIView、RetrieveModelMixin、UpdateModelMixin
7)RetrieveUpdateDestoryAPIView
提供 get、put、patch、delete方法
继承自:GenericAPIView、RetrieveModelMixin、UpdateModelMixin、DestoryModelMixin -
使用视图集ViewSet,可以将一系列逻辑相关的动作放到一个类中:
list() 提供一组数据
retrieve() 提供单个数据
create() 创建数据
update() 保存数据
destory() 删除数据
ViewSet视图集类不再实现get()、post()等方法,而是实现动作 action 如 list()–>get 、create()–>post 等。
视图集只在使用as_view()方法的时候,才会将action动作与具体请求方式对应上
ViewSet继承自APIView与ViewSetMixin,作用也与APIView基本类似,提供了身份认证、权限校验、流量管理等。
ViewSet主要通过继承ViewSetMixin来实现在调用as_view()时传入字典(如{‘get’:‘list’})的映射处理工作。
class UsersViewSet(viewsets.ViewSet):
def list(self, request):
pass
def retrieve(self, request, pk=None):
pass
url(r"^drfcheckusers/$",views.UsersListView.as_view({'get':'list'})
url(r"^drfcheckusers/(?P<pk>\d+)/$", views.UsersOneView.as_view({'get':'retrieve'}))
在ViewSet中,没有提供任何动作action方法,需要我们自己实现action方法。如list 、retrieve 等
使用ViewSet通常并不方便,因为list、retrieve、create、update、destory等方法都需要自己编写
- GenericViewSet 集成了GenericAPIView与ViewSetMixin,在实现了调用as_view()时传入字典(如{‘get’:‘list’})的映射处理工作的同时,还提供了GenericAPIView提供的基础方法,可以直接搭配Mixin扩展类使用。
class GetPostUsersView(GenericViewSet,RetrieveModelMixin,UpdateModelMixin,CreateModelMixin):
queryset = Users.objects.all()
serializer_class = Userserializers
def get(self,request,pk):
return self.retrieve(request,pk)
def post(self,request,pk):
return self.update(request)
def put(self, request, *args, **kwargs):
return self.create(request)
class UsersViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, GenericViewSet):
queryset = Users.objects.all()
serializer_class = UsersModelsSerializer
def latest(self, request):#自定义接口,与url中的as_view内的接口名称对应
"""
返回最新的用户信息
get users/latest/
"""
users = Users.objects.latest('id') # latest 倒序取第一个
serializer = self.get_serializer(users)
return Response(serializer.data)
def update_uage(self, request, pk):#自定义接口,与url中的as_view内的接口名称对应
"""
修改用户的年龄数据
put users/3/update_uage/
"""
users = self.get_object()
users.uage = request.data.get('age')
users.save()
serializer = self.get_serializer(users)
return Response(serializer.data)
"""
============================================================================
"""
url(r'^users/latest/$', views.UsersViewSet.as_view({'get': 'latest'})),#自定义接口
url(r'^users/(?P<pk>\d+)/age/$', views.UsersViewSet.as_view({'put': 'update_uage'})),#自定义接口
- ReadOnlyModelViewSet 与GenericViewSet类似,集成了GenericViewSet,同时包括了ListModelMixin、RetrieveModelMixin。
- ModelViewSet 继承自GenericViewSet,同时包括了ListModelMixin、RetrieveModelMixin、CreateModelMixin、UpdateModelMixin、DestoryModelMixin。
- 利用router生成url路由:
router = routers.SimpleRouter()
router.register(r'users', views.UsersViewSet, base_name='user')
urlpatterns += router.urls
Router提供了一种简单,快速,集成的方式来定义一系列的urls
例子:
from rest_framework import routers
router = routers.SimpleRouter()
router.register(‘users’, UserViewSet)
router.register(‘account’, AccountViewSet)
urlpatterns = router.ulrs
register()函数有两个必要参数:
prefix: 字首,用来表示一系列的urls
viewset: viewset class
可选的参数:
base_name: 用来生成urls名字,如果viewset中没有包含queryset, base_name一定要有
上面的例子生成的url:
URL pattern: ^users/$ Name: ‘user-list’
URL pattern: ^users/{pk}/$ Name: ‘user-detail’
URL pattern: ^accounts/$ Name: ‘account-list’
URL pattern: ^accounts/{pk}/$ Name: ‘account-detail’
在routers中使用include
routers实例的urls属性表示一系列的urls.可以通过不同的方式来包含其他的urls
from rest_framework import routers
router = routers.DefaultRouter()
router.register(‘users’, UserViewSet)
router.register(‘accounts’, AccountViewSet)
urlpatters = pattern(
url(’^forget_password/$’, ForgetPasswordViewSet.as_view())
)
urlpatterns += router.urls
你也可以使用include:
from rest_framework import routers
router = routers.DefaultRouter()
router.register(‘users’, UserViewSet)
router.register(‘accounts’, AccountViewSet)
urlpatters = pattern(
url(’^forget_password/$’, ForgetPasswordViewSet.as_view())
url('^', include(router.urls))
)
额外的连接和操作
viewset定义了list, update, retrieve, create, update, destory, partial_update方法, 如果你有一些额外的操作,可以使用@detail_route 或者 @list_route来实现
from rest_framework.decorators import detail_route
class UserViewSet(ModelViewSet):
@detail_route(methods=[‘POST’])
def set_password(self, request, pk=None):
pass
它对应的url为: /users/{pk}/set_password Name: user-set-password
如果你不想使用默认的url,你可以通过设置url_path参数来改变url
from rest_framework.decorators import detail_route
class UserViewSet(ModelViewSet):
@detail_route(methods=[‘POST’], url_path=‘change-password’)
def set_password(self, request, pk=None):
pass
urlpattern: /users/{pk}/change-password/$ Name: user-change-password