models.py
from django.db import models
class Book(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=32)
price = models.DecimalField(max_digits=5,decimal_places=2)
publish = models.CharField(max_length=32)
author = models.CharField(max_length=32)
ser.py(自定义序列化文件)
from app01 import models
from rest_framework import serializers
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = models.Book
fields = "__all__"
view.py
from app01 import models
from app01.ser import BookSerializer
from rest_framework.views import APIView
from rest_framework.response import Response
# 自定义一个Response对象
class MyResponse():
def __init__(self):
self.status = ‘1000‘
self.msg = ‘成功‘
@property
def get_dict(self):
return self.__dict__
class BookView1(APIView):
# 查询一条数据
def get(self,request,pk):
response_msg = MyResponse()
book_obj = models.Book.objects.filter(id=pk).first()
book_ser = BookSerializer(instance=book_obj)
response_msg.data = book_ser.data
return Response(response_msg.get_dict)
# 删除一条数据
def delete(self,request,pk):
response_msg = MyResponse()
models.Book.objects.filter(pk=pk).delete()
response_msg.msg = ‘删除成功‘
return Response(response_msg.get_dict)
# 修改一条数据
def put(self,request,pk):
response_msg = MyResponse()
book_obj = models.Book.objects.filter(pk=pk).first()
book_ser = BookSerializer(instance=book_obj,data=request.data)
if book_ser.is_valid():
book_ser.save()
response_msg.data = book_ser.data
else:
response_msg.status = ‘1001‘
response_msg.msg = ‘校验失败,请稍后再试‘
response_msg.data = book_ser.errors
return Response(response_msg.get_dict)
class BooksView1(APIView):
# 查询所有数据
def get(self,request):
response_msg = MyResponse()
books_obj = models.Book.objects.all()
books_ser = BookSerializer(instance=books_obj,many=True)
response_msg.data = books_ser.data
return Response(response_msg.get_dict)
# 新增一条数据
def post(self,request):
response_msg = MyResponse()
book_ser = BookSerializer(data=request.data)
if book_ser.is_valid():
book_ser.save()
response_msg.msg = ‘新增成功‘
response_msg.data = book_ser.data
else:
response_msg.status = ‘1001‘
response_msg.msg = ‘新增失败,情稍后再试‘
response_msg.data = book_ser.errors
return Response(response_msg.get_dict)
urls.py
url(r‘^book1/(?P<pk>\d+)‘, views.BookView1.as_view()),
url(r‘^books1/‘, views.BooksView1.as_view()),
总结
1. 继承关系: APIView继承View
2. APIView基于View的拓展:
APIView重写了View的dispatch方法, 在该方法中实现了实现了一下功能:
(1) 对来的原生请求对象request进行了封装.
(2) 提供了对包装过后的请求对象的三段认证: 认证, 权限控制, 频率控制
(3) 重写了View中通过本次请求的方式动态的反射到自定义继承APIView类实例化的对象中定义的请求方法
(4) 使用异常处理处理2,3步骤中的异常
(5) 处理完毕异常以后使用drf的response对象对请求响应
3. 针对路由配置
路由中的有名分组必须指定pk, 视图中使用必须使用相同的关键字参数接受
models.py
from django.db import models
class Book(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=32)
price = models.DecimalField(max_digits=5,decimal_places=2)
publish = models.CharField(max_length=32)
author = models.CharField(max_length=32)
ser.py(自定义序列化文件)
# 最好使用ModelSerializer类,不用重写update和create方法
from app01 import models
from rest_framework import serializers
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = models.Book
fields = "__all__"
view.py
from rest_framework.generics import GenericAPIView
class BookGenericView2(GenericAPIView):
# queryset要传queryset对象,查询了所有的图书
# serializer_class使用哪个序列化类来序列化这堆数据
queryset = models.Book.objects
serializer_class = BookSerializer
# queryset=models.Book.objects.all()
# 查询一条数据
def get(self,request,pk):
response_msg = MyResponse()
book_obj = self.get_object()
book_ser = self.get_serializer(book_obj)
response_msg.data = book_ser.data
return Response(response_msg.get_dict)
# 删除一条数据
def delete(self,request,pk):
response_msg = MyResponse()
self.get_object().delete()
response_msg.msg = ‘删除成功‘
return Response(response_msg.get_dict)
# 修改一条数据
def put(self,request,pk):
response_msg = MyResponse()
book_obj = self.get_object()
book_ser = self.get_serializer(book_obj,request.data)
if book_ser.is_valid():
book_ser.save()
response_msg.data = book_ser.data
else:
response_msg.status = ‘1001‘
response_msg.msg = ‘校验失败,请稍后再试‘
response_msg.data = book_ser.errors
return Response(response_msg.get_dict)
class BooksGenericView2(GenericAPIView):
# queryset要传queryset对象,查询了所有的图书
# serializer_class使用哪个序列化类来序列化这堆数据
queryset = models.Book.objects
serializer_class = BookSerializer
# queryset=models.Book.objects.all()
# 查询所有数据
def get(self,request):
response_msg = MyResponse()
books_obj = self.get_queryset()
books_ser = self.get_serializer(books_obj,many=True)
response_msg.data = books_ser.data
return Response(response_msg.get_dict)
# 新增一条数据
def post(self,request):
response_msg = MyResponse()
book_ser = self.get_serializer(data=request.data)
if book_ser.is_valid():
book_ser.save()
response_msg.msg = ‘新增成功‘
response_msg.data = book_ser.data
else:
response_msg.status = ‘1001‘
response_msg.msg = ‘新增失败,情稍后再试‘
response_msg.data = book_ser.errors
return Response(response_msg.get_dict)
urls.py
url(r‘^bookG2/(?P<pk>\d+)‘,views.BookGenericView2.as_view()),
url(r‘^bookGs2/‘,views.BooksGenericView2.as_view()),
总结
1.GenericAPIView继承自APIView,它在APIView的功能上增加了两个功能:
- 通用的模型类(传入需要序列化的模型数据) queryset = None;
- 通用的序列化器(传入对应的序列化器对象) serializer_class = None
- 通用的有名分组名
lookup_field = ‘pk‘:好像不能改
lookup_url_kwarg = None:可以改,改成自己的有名分组名即可
2.三个常用方法
- get_queryset() # 获取queryset对象,用于查询多条数据
- get_object() # 获取一条对象数据
- get_serializer(*args, **kwargs) # 获取序列化器对象,该传什么参数就传什么参数
4.在写视图类时,模型表必须是queryset对象(加上objects),即queryset = Book.objects
5.
models.py
from django.db import models
class Book(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=32)
price = models.DecimalField(max_digits=5,decimal_places=2)
publish = models.CharField(max_length=32)
author = models.CharField(max_length=32)
ser.py(自定义序列化文件)
# 最好使用ModelSerializer类,不用重写update和create方法
from app01 import models
from rest_framework import serializers
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = models.Book
fields = "__all__"
view.py
from rest_framework.mixins import ListModelMixin,CreateModelMixin,UpdateModelMixin,DestroyModelMixin,RetrieveModelMixin
class BookGenericView3(GenericAPIView,UpdateModelMixin,DestroyModelMixin,RetrieveModelMixin):
"""
UpdateModelMixin:修改
DestroyModelMixin:删除
RetrieveModelMixin:查询一条数据
"""
# queryset要传queryset对象,查询了所有的图书
# serializer_class使用哪个序列化类来序列化这堆数据
queryset = models.Book.objects
serializer_class = BookSerializer
# 查询一条数据
def get(self,request,pk):
return self.retrieve(request,pk)
# 删除一条数据
def delete(self,request,pk):
return self.destroy(request,pk)
# 修改一条数据
def put(self,request,pk):
return self.update(request,pk)
class BooksGenericView3(GenericAPIView,ListModelMixin,CreateModelMixin):
"""
ListModelMixin:查询所有
CreateModelMixin:创建一条数据
"""
# queryset要传queryset对象,查询了所有的图书
# serializer_class使用哪个序列化类来序列化这堆数据
queryset = models.Book.objects
serializer_class = BookSerializer
# queryset=models.Book.objects.all()
# 查询所有数据
def get(self,request):
return self.list(request)
# 新增一条数据
def post(self,request):
return self.create(request)
urls.py
url(r‘^bookG3/(?P<pk>\d+)‘,views.BookGenericView3.as_view()),
url(r‘^bookGs3/‘,views.BooksGenericView3.as_view()),
总结
1.使用GenericAPIView写不同类的接口,只是queryset参数和serializer_class参数的不同,其他的方法几乎完全一样
2.这五个扩展类需要搭配GenericAPIView父类,因为五个扩展类的实现需要调用GenericAPIView提供的序列化器与数据库查询的方法。
3.DestroyModelMixin、RetrieveModelMixin、UpdateModelMixin的路由中,必须使用pk
# ListModelMixin 内部封装了list方法, 实现了查询所有数据
提供list(request, *args, **kwargs)方法快速实现列表视图,返回200状态码。
该Mixin的list方法会对数据进行过滤和分页。
# CreateModelMixin 内部封装了create方法, 实现了新增一条数据
提供create(request, *args, **kwargs)方法快速实现创建资源的视图,成功返回201状态码。
如果序列化器对前端发送的数据验证失败,返回400错误。
# RetrieveModelMixin 内部封装了retrieve方法, 实现了查询一条数据
提供retrieve(request, *args, **kwargs)方法,可以快速实现返回一个存在的数据对象。
如果存在,返回200, 否则返回404。
# UpdateModelMixin 内部封装了update方法, 实现了更新一条数据
提供update(request, *args, **kwargs)方法,可以快速实现更新一个存在的数据对象。
同时也提供partial_update(request, *args, **kwargs)方法,可以实现局部更新。
成功返回200,序列化器校验数据失败时,返回400错误。
# DestroyModelMixin 内部封装了destroy方法,实现了删除一条数据
提供destroy(request, *args, **kwargs)方法,可以快速实现删除一个存在的数据对象。
成功返回204,不存在返回404。
4.在写视图类时,模型表必须是queryset对象(加上objects),即queryset = Book.objects
models.py
from django.db import models
class Book(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=32)
price = models.DecimalField(max_digits=5,decimal_places=2)
publish = models.CharField(max_length=32)
author = models.CharField(max_length=32)
ser.py(自定义序列化文件)
# 最好使用ModelSerializer类,不用重写update和create方法
from app01 import models
from rest_framework import serializers
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = models.Book
fields = "__all__"
view.py
from rest_framework.generics import GenericAPIView,
CreateAPIView, DestroyAPIView, UpdateAPIView, ListAPIView, RetrieveAPIView,
ListCreateAPIView, RetrieveDestroyAPIView, RetrieveUpdateDestroyAPIView, RetrieveUpdateAPIView
# 创建一个数据
class BookCreateAPIView(CreateAPIView):
queryset = Book.objects
serializer_class = BookModelSerializer
# 删除一个数据
class BookDestroyAPIView(DestroyAPIView):
queryset = Book.objects
serializer_class = BookModelSerializer
# 修改一个数据
class BookUpdateAPIView(UpdateAPIView):
queryset = Book.objects
serializer_class = BookModelSerializer
# 获取所有数据
class BookListAPIView(ListAPIView):
queryset = Book.objects
serializer_class = BookModelSerializer
# 获取一个数据
class BookRetrieveAPIView(RetrieveAPIView):
queryset = Book.objects
serializer_class = BookModelSerializer
# 获取所有数据和创造一个数据
class BookListCreateAPIView(ListCreateAPIView):
queryset = Book.objects
serializer_class = BookModelSerializer
# 获取一个数据和删除一个数据
class BookRetrieveDestroyAPIView(RetrieveDestroyAPIView):
queryset = Book.objects
serializer_class = BookModelSerializer
# 获取一个数据和修改一个数据
class BookRetrieveUpdateAPIView(RetrieveUpdateAPIView):
queryset = Book.objects
serializer_class = BookModelSerializer
# 获取一个数据和修改一个数据和删除一个数据
class BookRetrieveUpdateDestroyAPIView(RetrieveUpdateDestroyAPIView):
queryset = Book.objects
serializer_class = BookModelSerializer
urls.py
url(r‘^books/$‘, views.BookModelViewSet.as_view(),
url(r‘^books/(?P<pk>\d+)‘,views.BookModelViewSet.as_view(),
总结
1.不需要指定路由的actions参数,因为根本就没有
2.在写视图类时,模型表必须是queryset对象(加上objects),即queryset = Book.objects
models.py
from django.db import models
class Book(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=32)
price = models.DecimalField(max_digits=5,decimal_places=2)
publish = models.CharField(max_length=32)
author = models.CharField(max_length=32)
ser.py(自定义序列化文件)
# 最好使用ModelSerializer类,不用重写update和create方法
from app01 import models
from rest_framework import serializers
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = models.Book
fields = "__all__"
view.py
from rest_framework.viewsets import ModelViewSet
class BookGenericView4(ModelViewSet):
"""
5个接口都有,但是路由有点问题
问?怎么区别那种请求触发该请求方式的方法
需要在路由中添加一个参数:actions={‘get‘:‘list‘,‘post‘:‘create‘,‘get‘:‘retrieve‘,‘delete‘:‘destroy‘,‘put‘:‘update‘}
"""
queryset = models.Book.objects
serializer_class = BookSerializer
urls.py
url(r‘^bookG4/(?P<pk>\d+)‘, views.BookGenericView4.as_view(actions={‘delete‘:‘destroy‘,‘get‘:‘retrieve‘,‘put‘:‘update‘})), # 这个路由中有删除一个、查询一个、修改一个的请求
url(r‘^bookGs4/‘, views.BookGenericView4.as_view(actions={‘get‘:‘list‘,‘post‘:‘create‘})), # 这个路由中有查询所有、增添一个的请求
总结
1.路由处的as_view()中必须传一个action参数(字典),格式:action={‘get‘:‘list‘,‘post‘:‘creat‘}
2.在写视图类时,模型表必须是queryset对象(加上objects),即queryset = Book.objects
models.py
from django.db import models
class Book(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=32)
price = models.DecimalField(max_digits=5,decimal_places=2)
publish = models.CharField(max_length=32)
author = models.CharField(max_length=32)
ser.py(自定义序列化文件)
# 最好使用ModelSerializer类,不用重写update和create方法
from app01 import models
from rest_framework import serializers
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = models.Book
fields = "__all__"
view.py
from rest_framework.viewsets import ViewSetMixin
class BookGenericView5(ViewSetMixin,GenericAPIView):
queryset = models.Book.objects
serializer_class = BookSerializer
# 查询一条数据
def get_one_data(self,request,pk):
response_msg = MyResponse()
book_obj = self.get_object()
book_ser = self.get_serializer(book_obj)
response_msg.data = book_ser.data
return Response(response_msg.get_dict)
# 删除一条数据
def delete_one_data(self,request,pk):
response_msg = MyResponse()
self.get_object().delete()
response_msg.msg = ‘删除成功‘
return Response(response_msg.get_dict)
# 修改一条数据
def put_one_data(self,request,pk):
response_msg = MyResponse()
book_obj = self.get_object()
book_ser = self.get_serializer(book_obj,request.data)
if book_ser.is_valid():
book_ser.save()
response_msg.data = book_ser.data
else:
response_msg.status = ‘1001‘
response_msg.msg = ‘校验失败,请稍后再试‘
response_msg.data = book_ser.errors
return Response(response_msg.get_dict)
class BooksGenericView5(ViewSetMixin,GenericAPIView):
queryset = models.Book.objects
serializer_class = BookSerializer
# 查询所有数据
def get_all_data(self,request):
response_msg = MyResponse()
books_obj = self.get_queryset()
books_ser = self.get_serializer(books_obj,many=True)
response_msg.data = books_ser.data
return Response(response_msg.get_dict)
# 新增一条数据
def post_one_data(self,request):
response_msg = MyResponse()
book_ser = self.get_serializer(data=request.data)
if book_ser.is_valid():
book_ser.save()
response_msg.msg = ‘新增成功‘
response_msg.data = book_ser.data
else:
response_msg.status = ‘1001‘
response_msg.msg = ‘新增失败,情稍后再试‘
response_msg.data = book_ser.errors
return Response(response_msg.get_dict)
urls.py
url(r‘^bookG5/(?P<pk>\d+)‘, views.BookGenericView5.as_view(actions={‘delete‘:‘delete_one_data‘,‘get‘:‘get_one_data‘,‘put‘:‘put_one_data‘})), # 这个路由中有删除一个、查询一个、修改一个的请求
url(r‘^bookGs5/‘, views.BooksGenericView5.as_view(actions={‘get‘:‘get_all_data‘,‘post‘:‘post_one_data‘})), # 这个路由中有查询所有、增添一个的请求
总结
1.ViewSetMixin类一定要放在GenericAPIView类前面
2.ViewSetMixin类可以与APIView类使用,请求函数和使用APIView类时一样,只不过可以自定义自己的请求方式名
def get_all_data(,self,request):
pass
3.自定义自己的请求方式函数时,需要在路由的as_view()中的action中设置好映射关系
url(r‘^index/‘,view.Data.as_view(action={‘get‘:‘get_all_data‘}))
4.在写视图类时,模型表必须是queryset对象(加上objects),即queryset = Book.objects
原文:https://www.cnblogs.com/borntodie/p/14330777.html