首页 > 其他分享 >drf视图组件与视图基类

drf视图组件与视图基类

时间:2023-02-03 20:45:57浏览次数:36  
标签:return ser get models self 视图 基类 pk drf

drf视图组件

视图就是视图类,我们之前学过的APIView就是drf提供的基类。

APIView与原生View区别:
	1.传入到视图类中的是drf的Request对象而不是django的request对象
	2.视图类应该返回 drf的Request对象
	3.任何异常都会被捕获到,并处理
	4.在进行dispatch()前 会进行3大认证即认证,权限,频率

两个视图基类

APIView

再写一遍,练习加倍

APIView+ModelSerializer+Resposne写5个接口

from django.db import models


# Create your models here.
class Book(models.Model):
    name = models.CharField(max_length=32)
    price = models.CharField(max_length=32)

    publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE)
    authors = models.ManyToManyField(to='Author')

    def publish_detail(self):
        return {'name': self.publish.name, 'addr': self.publish.addr}

    def author_list(self):
        l = []
        for author in self.authors.all():
            l.append({'name': author.name, 'phone': author.phone, 'age': author.detail.age, 'addr': author.detail.addr})
        return l


class Publish(models.Model):
    name = models.CharField(max_length=32)
    addr = models.CharField(max_length=32)


class Author(models.Model):
    name = models.CharField(max_length=32)
    phone = models.CharField(max_length=11)

    detail = models.OneToOneField(to='Detail', on_delete=models.CASCADE)


class Detail(models.Model):
    age = models.CharField(max_length=4)
    addr = models.CharField(max_length=32)
视图类
from .models import Book
from .serializer import BookSerializer


class BookView(APIView):
    def get(self, request):
        books = Book.objects.all()
        ser = BookSerializer(instance=books, many=True)
        return Response(ser.data)

    def post(self, request):
        ser = BookSerializer(data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({'code': 100, 'msg': '新增成功', 'result': ser.data})
    """这里的ser.data为什么能拿到数据是因为他把新增的对象序列化成了一个字典,前提是必须在create方法内返回新增对象"""
        else:
            return Response({'code': 101, 'msg': ser.errors})


class BookDetailView(APIView):
    def get(self, request, pk):
        books = Book.objects.filter(pk=pk).first()
        ser = BookSerializer(instance=books)
        return Response(ser.data)

    def put(self, request, pk):
        books = Book.objects.filter(pk=pk).first()
        ser = BookSerializer(instance=books, data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({'code': 100, 'msg': '修改成功', 'result': ser.data})
        else:
            return Response({'code': 101, 'msg': ser.errors})

    def delete(self, request, pk):
        Book.objects.filter(pk=pk).delete()
        return Response({'code': 100, 'msg': '删除成功'})
序列化类
### ModelSerializer的使用
class BookSerializer(serializers.ModelSerializer):
    # 跟表有关联
    class Meta:
        model = Book
        fields = ['name', 'price', 'publish_detail', 'author_list', 'publish', 'authors']
        extra_kwargs = {'name': {'max_length': 8},
                        'publish_detail': {'read_only': True},
                        'author_list': {'read_only': True},
                        'publish': {'write_only': True},
                        'authors': {'write_only': True},
                        }
路由
urlpatterns = [
    path('admin/', admin.site.urls),
    path('books/', views.BookView.as_view()),
    path('books/<int:pk>/', views.BookDetailView.as_view()),
]
APIView类属性简介
renderer_classes 		# 响应格式
parser_classes 			#能够解析的请求格式
authentication_classes	 #认证类
throttle_classes		#频率类
permission_classes		#权限类
GenericAPIView
重要属性
"""
queryset: 		  要序列化或反序列化 表模型的数据(对象)
serializer_class:  使用的序列化类
lookup_field    查询书籍路由分组匹配的名<int:pk>
				如果路由中不是pk可以改直接在视图类中 lookup_field = pk 
filter_backends  过滤类配置
pagination_class 分页类配置
"""

重要方法:
"""
1.get_queryset    获取序列化的对象 queryset对象[{对象1},{对象2}]
2.get_object     获取单个对象 不需要传pk
3.get_serializer   获取=后面的序列化类
get_serializer_class  重写指定序列化类
4.filter_queryset  过滤相关

"""

别的代码不变只是views中需要继承GenericAPIView

from rest_framework.generics import GenericAPIView
class BookView(GenericAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    def get(self, request):
        """
        get_queryset    固定的方法拿到对象
        get_serializer  固定的方法 后期可以重写get_serializer_class指定序列化类
        """
        objs = self.get_queryset()
        ser = self.get_serializer(instance=objs,many=True)
        return Response(ser.data,status=201,headers={'a':'b'})

    def post(self, request):
        ser = self.get_serializer(data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({'code': 100, 'msg': '新增成功'})
        else:
            return Response({'code': 101, 'msg': ser.errors})

class BookDetailView(GenericAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    """
    get_object 获取单个对象 
    """
    def get(self, request, pk):
        obj = self.get_object()
        ser = self.get_serializer(instance=obj)
        return Response(ser.data)

    def put(self, request, pk):
        obj = self.get_object()
        ser = self.get_serializer(data=request.data, instance=obj)
        if ser.is_valid():
            ser.save()
            return Response({'code': 100, 'msg': '新增成功'})
        else:
            return Response({'code': 101, 'msg': ser.errors})

    def delete(self, request, pk):
        Book.objects.filter(pk=pk).delete()
        return Response({'code': 100, 'msg': '删除成功'})

标签:return,ser,get,models,self,视图,基类,pk,drf
From: https://www.cnblogs.com/LiaJi/p/17090379.html

相关文章