码迷,mamicode.com
首页 > 其他好文 > 详细

rest_framework中视图相关

时间:2018-07-18 23:23:28      阅读:178      评论:0      收藏:0      [点我收藏+]

标签:前端   div   read_only   身份认证   views   models   校验   objects   没有   

 

模型类的定义

# 定义图书模型类BookInfo
class BookInfo(models.Model):
    btitle = models.CharField(max_length=20, verbose_name=名称)
    bpub_date = models.DateField(verbose_name=发布日期)
    bread = models.IntegerField(default=0, verbose_name=阅读量)
    bcomment = models.IntegerField(default=0, verbose_name=评论量)
    is_delete = models.BooleanField(default=False, verbose_name=逻辑删除)

    class Meta:
        db_table = tb_books  # 指明数据库表名
        verbose_name = 图书  # 在admin站点中显示的名称
        verbose_name_plural = verbose_name  # 显示的复数名称

    def __str__(self):
        """定义每个数据对象的显示信息"""
        return self.btitle

 

定义一个序列化器

from rest_framework import serializers  # 引入类

class BookInfoSerializer(serializers.Serializer):
    """ 图书列表序列化器"""
    id = serializers.IntegerField(label="ID", read_only=True)
    btitle = serializers.CharField(label="名称", max_length=20)
    bpub_date = serializers.DateField(label=发布日期, required=False)
    bread = serializers.IntegerField(label=阅读量, required=False)
    bcomment = serializers.IntegerField(label=评论量, required=False)
    is_delete = serializers.BooleanField(label=逻辑删除, required=False)
    heroinfo_set = serializers.PrimaryKeyRelatedField(read_only=True, many=True)  # 新增

    def create(self, validated_data):
        """新建"""
        return BookInfo.objects.create(**validated_data)

    def update(self, instance, validated_data):
        """更新,instance为要更新的对象实例"""
        instance.btitle = validated_data.get(btitle, instance.btitle)
        instance.bpub_date = validated_data.get(bpub_date, instance.bpub_date)
        instance.bread = validated_data.get(bread, instance.bread)
        instance.bcomment = validated_data.get(bcomment, instance.bcomment)
        instance.save()
        return instance

 

django本身的View类来构建一个RESTful风格的API接口的开发;

import json
from django.forms import model_to_dict
from django.http import JsonResponse
from django.shortcuts import HttpResponse
from django.views import View
from rest_framework.viewsets import ModelViewSet

from .models import BookInfo


class BooksAPIView(View):
    def get(self, request):
        """
        查询所有图书
        :param request:
        :return:
        """
        queryset = BookInfo.objects.all().values()
        book_list = []
        book_list = list(queryset)

        return JsonResponse(book_list, safe=False)

    def post(self, request):
        """
        新增图书
        :param request:
        :return:
        """
        json_bytes = request.body
        json_str = json_bytes.decode()
        book_dict = json.loads(json_str)
        book = BookInfo.objects.create(
            **book_dict
        )

        return JsonResponse({
            "id": book.id,
            "btitle": book.btitle,
            bpub_date: book.bpub_date,
            bread: book.bread,
            bcomment: book.bcomment,
        }, status=201)


class BookAPIView(View):
    """
    获取单个图书的信息
    """

    def get(self, request, pk):
        try:
            book = BookInfo.objects.get(id=pk)
        except Exception as e:
            print(e)
            return HttpResponse(status=404)

        book_dict = model_to_dict(book)
        return JsonResponse(book_dict)

    def put(self, request, pk):
        """
        修改图书信息
        :param request:
        :param pk:
        :return:
        """
        try:
            book = BookInfo.objects.get(id=pk)
        except Exception as e:
            print(e)
            return HttpResponse(status=404)

        # 校验参数

        json_bytes = request.body
        json_str = json_bytes.decode()
        book_dict = json.loads(json_str)

        BookInfo.objects.filter(id=pk).update(**book_dict)
        book_dict = model_to_dict(BookInfo.objects.get(id=pk))
        return JsonResponse(book_dict)

    def delete(self, request, pk):
        """
        删除
        :param request:
        :param pk:
        :return:
        """
        try:
            book = BookInfo.objects.get(id=pk)
        except Exception as e:
            print(e)
            return HttpResponse(status=404)

        book.delete()
        return HttpResponse(status=204)


"""
urlpatterns = [
    url(r‘^books/$‘, views.BooksAPIView.as_view()),
    url(r‘^books/(?P<pk>\d+)/$‘, views.BookDetailView.as_view()),
]
"""

 

通过(from rest_framework.views import APIView)中的APIView类构建一个RESTful风格的API接口的开发;

from .models import BookInfo

from .serializers import BookInfoSerializer
from rest_framework.views import APIView
from rest_framework.response import Response


class BooksAPIView(APIView):
    """
    与django中的view相比
    """

    def get(self, request):
        # 数据库中取数据;
        books = BookInfo.objects.all()
        # 序列化器的使用;
        serializer = BookInfoSerializer(books, many=True)
        # 返回数据
        return Response(serializer.data)


"""
from app001 import views
urlpatterns = [
    url(r‘^books/$‘, views.BooksAPIView.as_view()),
]
"""

"""
此时继承的APIView与django中的view比较;
1,传入到视图方法中的是REST framework的Request对象,而不是Django的HttpRequeset对象;
2,视图方法可以返回REST framework的Response对象,视图会为响应数据设置(render)符合前端要求的格式;
3,任何APIException异常都会被捕获到,并且处理成合适的响应信息;
4,在进行dispatch()分发前,会对请求进行身份认证、权限检查、流量控制。
"""

 

通过APIView的子类GenericAPIView子类构建一个RESTful风格的API接口的开发;

 

from .models import BookInfo
from .serializers import BookInfoSerializer
from rest_framework.response import Response
from rest_framework.generics import GenericAPIView


class BooksAPIView(GenericAPIView):
    """
    与restframework中的APIView相比
    """
    # 取出queryset对象
    queryset = BookInfo.objects.all()
    # 定义一个序列化器的类
    serializer_class = BookInfoSerializer

    def get(self, request):
        # 数据库中取数据;
        qs = self.get_queryset()
        # 序列化器的使用;
        serializer = self.get_serializer(qs, many=True)
        # 返回数据
        return Response(serializer.data)


class BookDetailView(GenericAPIView):
    # 取出queryset对象
    queryset = BookInfo.objects.all()
    # 定义一个序列化器的类
    serializer_class = BookInfoSerializer

    def get(self, request, pk):
        # 数据库中取数据;
        qs = self.get_object()
        # 序列化器的使用;
        serializer = self.get_serializer(qs)
        # 返回数据
        return Response(serializer.data)


"""
from app001 import views
urlpatterns = [
    url(r‘^books/$‘, views.BooksAPIView.as_view()),
    url(r‘^books/(?P<pk>\d+)/$‘, views.BookDetailView.as_view()),
]
"""

"""
获取多个对象时候使用的方法( qs = self.get_queryset())
1,在这个视图中需要自己传入要返回的queryset对象;
2,要传来做序列化的类;
3,在定义的具体方法中来使用self.get_queryset()来获取类中的对象;
4,获取序列化的类然后处理数据;
5,将处理后的类返回到接口中;

获取单个对象使用的方法(qs = self.get_object())
步骤类似

总结:
在GenericAPIView的类中继承需要自己指定模型类;
自己指定方法的映射关系;
自己取对象;
自己取序列化的类;
自己返回数据
"""

 

(from rest_framework.generics import GenericAPIView)(from rest_framework import mixins)通过这两个子类构建一个RESTful风格的API接口的开发;

from .models import BookInfo
from .serializers import BookInfoSerializer
from rest_framework.generics import GenericAPIView
from rest_framework import mixins


class BooksAPIView(mixins.ListModelMixin, GenericAPIView):
    """
    与restframework中的APIView相比
    """
    # 取出queryset对象
    queryset = BookInfo.objects.all()
    # 定义一个序列化器的类
    serializer_class = BookInfoSerializer

    def get(self, request):
        return self.list(request)


class BookDetailView(mixins.RetrieveModelMixin, GenericAPIView):
    # 取出queryset对象
    queryset = BookInfo.objects.all()
    # 定义一个序列化器的类
    serializer_class = BookInfoSerializer

    def get(self, request, pk):
        return self.retrieve(request)


"""
from app001 import views
urlpatterns = [
    url(r‘^books/$‘, views.BooksAPIView.as_view()),
    url(r‘^books/(?P<pk>\d+)/$‘, views.BookDetailView.as_view()),
]
"""

"""
总结:
在mixins.RetrieveModelMixin与GenericAPIView相比较;
1,封装(self.get_queryset()的方法;
2,封装了self.paginate_queryset()的方法;
3,封装了serializer = self.get_serializer(queryset, many=True)的方法;
4,将序列化后的结果返回;
"""

 

(from rest_framework.generics import ListAPIView)类构建一个RESTful风格的API接口的开发;

from .models import BookInfo
from .serializers import BookInfoSerializer
from rest_framework.generics import ListAPIView


class BooksAPIView(ListAPIView):
    # 取出queryset对象
    queryset = BookInfo.objects.all()
    # 定义一个序列化器的类
    serializer_class = BookInfoSerializer


from rest_framework.generics import RetrieveAPIView


class BookDetailView(RetrieveAPIView):
    # 取出queryset对象
    queryset = BookInfo.objects.all()
    # 定义一个序列化器的类
    serializer_class = BookInfoSerializer


"""
from app001 import views
urlpatterns = [
    url(r‘^books/$‘, views.BooksAPIView.as_view()),
    url(r‘^books/(?P<pk>\d+)/$‘, views.BookDetailView.as_view()),
]
"""

"""
总结:
from rest_framework.generics import GenericAPIView
from rest_framework import mixins
等价与
from rest_framework.generics import ListAPIView

调用方式;
在get的方法中指明要调用的类中的封装的方法;
"""

 

 

(from rest_framework.viewsets import GenericViewSet)类构建一个RESTful风格的API接口的开发;

from .models import BookInfo
from .serializers import BookInfoSerializer
from rest_framework import mixins
from rest_framework.viewsets import GenericViewSet

class BooksAPIViewSet(mixins.ListModelMixin,mixins.RetrieveModelMixin,GenericViewSet):
    """
    mixins.ListModelMixin:实现了list的函数;
   GenericViewSet(ViewSetMixin, generics.GenericAPIView):
        ViewSetMixin 重写了as_view的方法(在url中将请求方式和action对应    queryset,serializer_class两个参数);
        GenericAPIView(views.APIView) 实现了get_queryset()和get_object的方法:
    """
    # 取出queryset对象
    queryset = BookInfo.objects.all()
    # 定义一个序列化器的类
    serializer_class = BookInfoSerializer

"""
url的访问形式
urlpatterns = [
    url(r‘^books/$‘, views.BooksAPIViewSet.as_view({"get": "list"})),
    url(r‘^books/(?P<pk>\d+)/$‘, views.BooksAPIViewSet.as_view({"get": "retrieve"})),
]
"""

"""
总结:
from rest_framework.generics import GenericAPIView
from rest_framework import mixins
等价与
from rest_framework.generics import ListAPIView
"""

 

action自定义方法扩张类构建一个RESTful风格的API接口的开发;

from .models import BookInfo
from .serializers import BookInfoSerializer
from rest_framework.viewsets import ModelViewSet
from rest_framework.decorators import action
from rest_framework.response import Response


class BookInfoViewSet(ModelViewSet):
    # 取出queryset对象
    queryset = BookInfo.objects.all()
    # 定义一个序列化器的类
    serializer_class = BookInfoSerializer

    # detail为False 表示不需要处理具体的BookInfo对象
    @action(methods=[get], detail=False)
    def latest(self, request):
        """
        返回最新的图书信息
        """
        book = BookInfo.objects.latest(id)
        serializer = self.get_serializer(book)
        return Response(serializer.data)

    # detail为True,表示要处理具体与pk主键对应的BookInfo对象
    @action(methods=[put], detail=True)
    def read(self, request, pk):
        """
        修改图书的阅读量数据
        """
        book = self.get_object()
        book.bread = request.data.get(read)
        book.save()
        serializer = self.get_serializer(book)
        return Response(serializer.data)


"""
url的访问形式
urlpatterns = [
    url(r‘^books/$‘, views.BookInfoViewSet.as_view({‘get‘: ‘list‘})),
    url(r‘^books/latest/$‘, views.BookInfoViewSet.as_view({‘get‘: ‘latest‘})),
    url(r‘^books/(?P<pk>\d+)/$‘, views.BookInfoViewSet.as_view({‘get‘: ‘retrieve‘})),
    url(r‘^books/(?P<pk>\d+)/read/$‘, views.BookInfoViewSet.as_view({‘put‘: ‘read‘})),
]
"""

"""
总结:
1) ViewSet
继承自APIView,作用也与APIView基本类似,提供了身份认证、权限校验、流量管理等。

在ViewSet中,没有提供任何动作action方法,需要我们自己实现action方法。

2)GenericViewSet
继承自GenericAPIView,作用也与GenericAPIVIew类似,提供了get_object、get_queryset等方法便于列表视图与详情信息视图的开发。

3)ModelViewSet
继承自GenericAPIVIew,同时包括了ListModelMixin、RetrieveModelMixin、CreateModelMixin、UpdateModelMixin、DestoryModelMixin。

4)ReadOnlyModelViewSet
继承自GenericAPIVIew,同时包括了ListModelMixin、RetrieveModelMixin。
"""

 



rest_framework中视图相关

标签:前端   div   read_only   身份认证   views   models   校验   objects   没有   

原文地址:https://www.cnblogs.com/cerofang/p/9332807.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!