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

Django REST Framework 数码宝贝 - 3步进化 - 混合类 -->

时间:2019-01-14 23:01:27      阅读:168      评论:0      收藏:0      [点我收藏+]

标签:instance   出版   lis   mixin   lock   tle   round   导入   刷新   

  读了我这篇博客, 你会刷新对面对对象的认知, 之前的面对对象都是LJ~~~

 

表结构

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

    def __str__(self):
        return self.name


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

    def __str__(self):
        return self.name


class Book(models.Model):
    title = models.CharField(max_length=32)
    pub_date = models.DateField()
    CHOICES = ((1, Python), (2, Go), (3, linux))
    category = models.IntegerField(choices=CHOICES)
    publisher = models.ForeignKey(to=Publisher, on_delete=models.CASCADE)
    authors = models.ManyToManyField(to=Author)

    def __str__(self):
        return self.title

 

 原路由:

urlpatterns = [
    url(r^admin/, admin.site.urls),
    url(r^books/$, views.BookListView.as_view()),
    url(rbook/(?P<pk>\d+)$, views.BookDetailView.as_view()),

    url(r^publishers/$, views.PublisherView.as_view()),
    url(rpublishers/(?P<pk>\d+)$, views.PublisherDetailView.as_view()),

]

 


 

原始版:

  获取出版社信息  

# 获取出版社信息
class PublisherView(APIView):
    """使用Django REST framework 内置的序列化"""

    def get(self,request):
        """Json格式返回所有的书籍信息"""
        queryset = models.Publisher.objects.all()
        ser_obj = ModelPublisherSerlizer(queryset, many=True)
        return Response(ser_obj.data)

    def post(self, request):
        ser_obj = ModelPublisherSerlizer(data=request.data)
        if ser_obj:
            ser_obj.save()
            return Response(ok)
        else:
            return Response(ser_obj.errors)

 

  获取具体某个出版社信息 查 改 删 -- > 

# 获取具体某个出版社信息
class PublisherDetailView(APIView):

    def get(self,pk):
        publisher_ob = models.Publisher.objects.filter(pk=pk)
        publisher_obj = models.Publisher.objects.filter(pk=pk).first()
        print("publisher_ob", publisher_ob, "publisher_obj", publisher_obj)

        if publisher_obj:
            ser_obj = ModelPublisherSerlizer(publisher_obj)
            return Response(ser_obj.data)
        else:
            return Response("无效的id")

    def put(self, request, pk):
        publisher_obj = models.Publisher.objects.filter(pk=pk).first()

        if publisher_obj:
            ser_obj = ModelPublisherSerlizer(instance=publisher_obj, data=request.data, partial=True)
            if ser_obj.is_valid():
                ser_obj.save()
                return Response(ser_obj.data)
            else:
                return Response(ser_obj.errors)
        else:
            return Response("没有这本书")


    def delete(self,pk):
        publisher_obj = models.Publisher.objects.filter(pk=pk)

        if publisher_obj:
            publisher_obj.delete()
            return Response("删除成功")
        else:
            return Response("没有这本书")

 


 

 

进化版:

  把出版社相关信息封装起来

class CemericView(APIView):
    """视图中可能用到的配置和方法封装起来"""
    queryset = None
    serializer_class = None

    def get_queryset(self):
        # 让每次请求来的时候都先查一次数据
        return self.queryset.all()


class ListMinxin(object):
    def get(self, request):
        queryset = self.get_queryset()
        ser_obj = self.serializer_class(queryset, many=True)
        return Response(ser_obj.data)

class CreateMixin(object):
    def post(self, request):
        ser_obj = self.serializer_class(data=request.data)
        if ser_obj:
            ser_obj.save()
            return Response(ok)
        else:
            return Response(ser_obj.errors)

# 获取出版社信息
class PublisherView(CemericView, ListMinxin, CreateMixin):

    queryset = models.Publisher.objects.all()
    serializer_class = ModelPublisherSerlizer

 


 

 

超级进化版:

  把某个出版社的信息也封装起来

class GemericView(APIView):
    """视图中可能用到的配置和方法封装起来"""
    queryset = None
    serializer_class = None

    def get_queryset(self):
        # 让每次请求来的时候都先查一次数据
        return self.queryset.all()

    def get_obj(self, request, pk, *args, **kwargs):
        return self.get_queryset().filter(pk=pk).filter(pk=pk).first()
class ListMinxin(object):
    def get(self, request):
        queryset = self.get_queryset()
        ser_obj = self.serializer_class(queryset, many=True)
        return Response(ser_obj.data)


class CreateMixin(object):
    def post(self, request):
        ser_obj = self.serializer_class(data=request.data)
        if ser_obj.is_valid():
            ser_obj.save()
            return Response(ok)
        else:
            return Response(ser_obj.errors)


# 获取出版社信息
class PublisherView(GemericView, ListMinxin, CreateMixin):

    queryset = models.Publisher.objects.all()
    serializer_class = ModelPublisherSerlizer


class RetrieveMixin(object):
    def get(self, request, pk, *args, **kwargs):
        obj = self.get_obj(request, pk, *args, **kwargs)
        if obj:
            ser_obj = self.serializer_class(obj)
            return Response(ser_obj.data)
        else:
            return Response("无效的id")


class UpdateMixin(object):
    def put(self, request, pk, *args, **kwargs):
        obj = self.get_obj(request, pk, *args, **kwargs)

        if obj:
            ser_obj = ModelPublisherSerlizer(instance=obj, data=request.data, partial=True)
            if ser_obj.is_valid():
                ser_obj.save()
                return Response(ser_obj.data)
            else:
                return Response(ser_obj.errors)
        else:
            return Response("没有这本书")


class DelMixin(object):
    def delete(self, request, pk, *args, **kwargs):
        obj = self.get_obj(request, pk, *args, **kwargs)
        print(obj)
        # print(obj.filter(pk = pk))

        if obj:
            obj.delete()
            return Response("删除成功")
        else:
            return Response("没有这本书")


# 获取具体某个出版社信息
class PublisherDetailView(GemericView, RetrieveMixin, UpdateMixin, DelMixin):
    queryset = models.Publisher.objects.all()
    serializer_class = ModelPublisherSerlizer

 

  如果在写一个api 的话 只需要3行代码, 

    但是 封装的代码好像有点多, 继承关系有点乱,

      其实框架本身提供了内置方法, 

from rest_framework.mixins import ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin

注意: 单纯的导入 不能成功, 因为 此方法中不是以 get ,post 等命名的, 导致 MVC模型中 as.view(), 找不到 请求的方式, 需要 对 这些方法进行进一步封装

技术分享图片

 就有了下面的内置方法

from rest_framework.generics import ListCreateAPIView,RetrieveDestroyAPIView

#这个包里里面 封装了 各种用于API 开发的浏览器 请求方式, 及组合方式, 直接调用即可

 

  一共 7行 代码解决

 

from rest_framework.generics import ListCreateAPIView, RetrieveDestroyAPIView

# 获取出版社信息
class PublisherView(ListCreateAPIView):

    queryset = models.Publisher.objects.all()
    serializer_class = ModelPublisherSerlizer

# 获取具体某个出版社信息
class PublisherDetailView(RetrieveDestroyAPIView):
    queryset = models.Publisher.objects.all()
    serializer_class = ModelPublisherSerlizer

 


 

究极进化版:

  上面超级进化版 一张表要写两个视图 定义queryset和serializer_class 重复,

  而且  路由也需要重复, 显然, 究极进化是不允许的~~

  

    重写了as_view()方法,实现了根据请求的方法执行具体的类方法

 

   路由注册的时候,利用actions参数,实现路由的定向分发 而不是简单的 反射

url(rauthors/$, views.AuthorViewSet.as_view(actions={get: list, post: create})),  # 作者列表
url(rauthors/(?P<pk>\d+)/$, views.AuthorViewSet.as_view(
        actions={get: retrieve, put: update, delete: destroy})
        ),  # 作者详情   

    路由都重复写两条:

   还可以利用内置的DefaultRouter来实现路由的注册

from rest_framework.routers import DefaultRouter

router = DefaultRouter()
router.register(authors, views.AuthorViewSet)

urlpatterns += router.urls

 

from rest_framework.viewsets import ModelViewSet
class AuthorViewSet(ModelViewSet):
    """
        list()
        create()
        retrieve()
        update()
        destroy()

    """
    queryset = models.Author.objects.all()
    serializer_class = AuthorModelSerializer

 

总结:  

  建议用以下两种方式技术分享图片

 

Django REST Framework 数码宝贝 - 3步进化 - 混合类 -->

标签:instance   出版   lis   mixin   lock   tle   round   导入   刷新   

原文地址:https://www.cnblogs.com/konghui/p/10268393.html

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