Django REST framework视图的用法

前言

在了解了REST farmwork封装的视图类之后,我对python的面向对象有了更深刻的理解。

Django RESR framework框架内置的视图类充分发挥了面向对象封装与继承的特性。

自己写一个类似于DRF内置视图类的功能

实现一个图书出版社的增、删、改、查、查功能,两个查一个是查所有出版社,一个是查具体的某一个出版社。

首先是一个简略的表结构设计models.py:

from django.db import models

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

  def __str__(self):
    return self.name

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

  def __str__(self):
    return self.name

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

  def __str__(self):
    return self.title

然后是路由url:

将用到pk,与不用到pk的路由业务区分开

from django.contrib import admin
from django.urls import path, re_path
from bms import views

urlpatterns = [
  path('admin/', admin.site.urls),
  # 查所有对象,与添加对象
  re_path(r'publishers/$', views.PublisherView.as_view()),
  # 带pk查询具体某一条数据
  re_path(r'publishers/(?P<pk>\d+)/$', views.PublisherDetailView.as_view()), # 出版社详情
]

再到序列化类,自创建的serializers.py

这里我省略了新增需要重写的create方法和更新需要重写的update方法。

from bms import models
from rest_framework import serializers

class PublisherModelSerializer(serializers.ModelSerializer):
  class Meta:
    model = models.Publisher
    fields = "__all__"

class AuthorModelSerializer(serializers.ModelSerializer):
  class Meta:
    model = models.Author
    fields = "__all__"

最后视图views.py

from bms import models
from rest_framework.views import APIView
from rest_framework.response import Response
from bms.serializers import PublisherModelSerializer

##################### 面向对象,手动实现REST framework视图功能##################
class GenericView(APIView):
  '''公用类'''
  queryset = None
  serializer_class = None

  def get_queryset(self):
    # 让每一次请求来的时候都现查一次数据
    print('GeneriView------',self)
    return self.queryset.all()

  def get_object(self, request, pk):
    # 获取具体queryset
    return self.get_queryset().filter(pk=pk)

class ListMixin(object):
  # mixi.n 混合类,不能单独使用,利用python支持多继承
  def get(self, request):
    print('ListMixin------------', self)
    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 RetrieveMixin(object):
  """ 获取具体某一条记录"""
  def retrieve(self, request, pk):
    '''将此get方法与ListMixin中的get方法区分'''
    obj = self.get_object(request, pk).first()
    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):
    obj = self.get_object(request, pk).first()
    if obj:
      ser_obj = self.serializer_class(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("无效的id")

class DestroyMixin(object):
  def delete(self, request, pk):
    obj = self.get_object(request, pk)
    if obj:
      obj.delete()
      return Response("删除成功")
    else:
      return Response("无效的id")

class RetrieveView(GenericView, RetrieveMixin):
  '''因两个get方法相冲图,在此曲线访问查询具体对象的get方法'''
  def get(self, request, pk):
    return self.retrieve(request, pk)

# 出版社
class PublisherView(GenericView, ListMixin, CreateMixin):
  '''查所有出版社,增加出版社'''
  # 只用写配置项
  queryset = models.Publisher.objects.all()
  serializer_class = PublisherModelSerializer

class PublisherDetailView(RetrieveView, UpdateMixin, DestroyMixin):
  '''查询具体某一出版社,编辑,删除'''
  queryset = models.Publisher.objects.all()
  serializer_class = PublisherModelSerializer

这样写就实现了简单的增删改查查功能,而且用对象封装,如果要添加其他表的查询,只需要简单的6行代码就可以实现;

比如:实现作者的增删改查查

# 作者
class AuthorListView(ListCreateAPIView):
  queryset = models.Author.objects.all()
  serializer_class = AuthorModelSerializer

class AuthorDetailView(RetrieveUpdateDestroyAPIView):
  queryset = models.Author.objects.all()
  serializer_class = AuthorModelSerializer

利用面向对象的封装与继承极大地简化了代码,减少了代码冗余。

但我们自己写的功能不够全面,不够严谨,Django REST framework 给我们封装了内置的视图类ModelViewSet。

Django REST framework 视图组件

视图组件是用来优化接口逻辑的

首先看看ModelViewSet

就是继承了5个混合类和一个公共类。

mixins.py中就是那五个类,封装了增删改查查 5个方法,还有其他严谨功能的方法,结构与上面实现的类似

而使用这个视图类就更简单了,一张表只需要一个类

from rest_framework.viewsets import ModelViewSet
class AuthorViewSet(ModelViewSet):
  """
    内部封装了这五个方法
    list()
    create()
    retrieve()
    update()
    destroy()

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

因内置类中封装的方法与请求方式的名并不一样

list()   对应查询所有对象的get方法

create()   对应添加的post方法

retrieve()  对应查询具体对像的get方法

update()   对应更新对象的put方法

destroy()   对应删除delete 方法

所以url要设置 actions 让它们一一对应

urlpatterns = [
  path('admin/', admin.site.urls),
  # 查所有对象,与添加对象
  re_path(r'publishers/$', views.PublisherView.as_view()),
  # 带pk查询具体某一条数据
  re_path(r'publishers/(?P<pk>\d+)/$', views.PublisherDetailView.as_view()), # 出版社详情

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

并且REST framework还封装了路由类,上面关于authors的路由还可以这样写

from rest_framework.routers import DefaultRouter

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

urlpatterns += router.urls

不过这样写路由,业务关系不清晰,一般用的少。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 详解Django rest_framework实现RESTful API

    一.什么是REST 面向资源是REST最明显的特征,资源是一种看待服务器的方式,将服务器看作是由很多离散的资源组成.每个资源是服务器上一个可命名的抽象概念.因为资源是一个抽象的概念,所以它不仅仅能代表服务器文件系统中的一个文件.数据库中的一张表等等具体的东西,可以将资源设计的要多抽象有多抽象,只要想象力允许而且客户端应用开发者能够理解. 与面向对象设计类似,资源是以名词为核心来组织的,首先关注的是名词.一个资源可以由一个或多个URI来标识.URI既是资源的名称,也是资源在Web上的地址.对某个资

  • Django REST Framework序列化外键获取外键的值方法

    需求:序列化外键,获取外键的除id之外的值 使用Django REST Framework虽然开发接口快速,但是如果想要获取到除外键id值之外的外键信息,直接继承serializers.ModelSerializer类,然后在fields中指定返回的字段是获取不到外键的其他值的,比如我现在需要外键的name属性值,下面就给大家介绍两种方法通过序列化外键来获取我们想要的外键的值. 这里有两个Model:问卷(Questionnaire):问题(Question).一张问卷中包含多个问题,问题通过外

  • django rest framework 实现用户登录认证详解

    1.安装 pip install djangorestframework 2.创建项目及应用 创建项目 创建应用 目录结构如图 3.设置settings.py 设置数据库连接 # MySQL 增加mysql 连接 DATABASES = { 'default':{ 'ENGINE':'django.db.backends.mysql', 'HOST':'127.0.0.1', 'PORT':'3306', 'NAME':'dbname', # 数据库名 'USER':'username', 'P

  • Django Rest framework认证组件详细用法

    本文详细讲述了DRF认证组件的原理以及用法. 源码剖析 讲解DRF版本的时候我们都知道了,在dispatch方法里执行了initial方法来初始化我们的版本. 而在initial方法里有我们的认证.权限.频率组件,如下图: 我们再点进去认证组件看看: 可以看到,我们的权限组件返回的是request.user,那么这里返回的request是新的还是旧的呢? initial方法是在request重新赋值之后执行的,所以我们这里的request是新的--也就是Request类的实例化对象. 所以,这个

  • django rest framework vue 实现用户登录详解

    后端代码就不介绍了,可以参考 django rest framework 实现用户登录认证 这里介绍一下前端代码,和前后端的联调过程 在components下新建login.vue 文件 <template> <div class="login"> <el-form label-width="80px"> <el-form-item label="用户名"> <el-input v-model

  • Django Rest framework频率原理与限制

    前言 开发平台的API接口调用需要限制其频率,以节约服务器资源和避免恶意的频繁调用. DRF就为我们提供了一些频率限制的方法. DRF中的版本.认证.权限.频率组件的源码是一个流程,且频率组件在最后执行. DRF频率组件原理 DRF中的频率控制基本原理是基于访问次数和时间的,当然我们也可以通过自己定义的方法来实现. 当请求进来,走到我们的频率组件时,DRF内部会有一个字典来记录访问者的IP. 以这个字典的IP为key,value为一个列表,存放访问者每次访问的时间:{PI1: [第三次访问时间,

  • Django REST framework视图的用法

    前言 在了解了REST farmwork封装的视图类之后,我对python的面向对象有了更深刻的理解. Django RESR framework框架内置的视图类充分发挥了面向对象封装与继承的特性. 自己写一个类似于DRF内置视图类的功能 实现一个图书出版社的增.删.改.查.查功能,两个查一个是查所有出版社,一个是查具体的某一个出版社. 首先是一个简略的表结构设计models.py: from django.db import models class Publisher(models.Mode

  • Django rest framework工具包简单用法示例

    本文实例讲述了Django rest framework工具包简单用法.分享给大家供大家参考,具体如下: Django rest framework 工具包做API非常方便. 下面简单说一下几个功能的实现方法. 实现功能为,匿名用户访问首页一分钟能访问3次,登录用户一分钟访问6次,只有登录用户才能访问order页面. 第一步,注册app INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contri

  • django rest framework使用django-filter用法

    django rest framework使用django-filter注意事项: 一定要在setting文件里面加载如下代码,而不是只安装包,否则django应用不报错,但是不能正确过滤. "` INSTALLED_APPS = [ 'django_filters' ] REST_FRAMEWORK = { 'DEFAULT_FILTER_BACKENDS': ( 'django_filters.rest_framework.DjangoFilterBackend', ), } 补充知识:re

  • Django REST framework 视图和路由详解

    DRF中的Request 在Django REST Framework中内置的Request类扩展了Django中的Request类,实现了很多方便的功能--如请求数据解析和认证等. 比如,区别于Django中的request从request.GET中获取URL参数,从request.POST中取某些情况下的POST数据. 在APIView中封装的request,就实现了请求数据的解析: 对于GET请求的参数我们通过request.query_params来获取. 对于POST请求.PUT请求的

  • Django框架中视图的用法

    视图层 一个视图函数,简称视图,是一个简单的 Python 函数,它接受 Web 请求并且返回 Web 响应. 响应可以是一个 HTML 页面.一个 404 错误页面.重定向页面.XML 文档.或者一张图片... 无论视图本身包含什么逻辑,都要返回响应.代码写在哪里都可以,只要在 Python 目录下面,一般放在项目的 views.py 文件中. 每个视图函数都负责返回一个 HttpResponse 对象,对象中包含生成的响应. 视图层中有两个重要的对象:请求对象(request)与响应对象(H

  • Django rest framework使用类视图实现首页API

    django-rest-framework 类视图拓展自 django 的类视图,只是针对数据的序列化和反序列化等逻辑做了封装. django-rest-framework 中最基本的类视图是 views.APIView,这个类可以看成是上一篇教程中用到的 api_view 装饰器的类版本.这个类比较基础,其核心功能就是 HTTP 请求预处理.分发请求给对应的处理函数,以及 HTTP 响应后处理,还有就是 as_view 方法将类转为函数(要注意与被请求的 URL 绑定的视图必须是一个可调用对象

  • django rest framework之请求与响应(详解)

    前言:在上一篇文章,已经实现了访问指定URL就返回了指定的数据,这也体现了RESTful API的一个理念,每一个URL代表着一个资源.当然我们还知道RESTful API的另一个特性就是,发送不同的请求动作,会返还不同的响应,这篇文章就讲一下django-rest-framework这个工具在这方面给我们带来的便捷操作. 一.Request对象 平时我们在写Django的视图函数的时候,都会带上一个request参数,这样就能处理平时搭建网站时,浏览器访问网页时发出的常规的HttpReques

  • Zend Framework动作控制器用法示例

    本文实例讲述了Zend Framework动作控制器用法.分享给大家供大家参考,具体如下: 动作控制器简介 为了使用Zend_Controller_Action类,需要在实际控制器类中把它子类化. 代码: <?php class FooController extends Zend_Controller_Action{ public function barAction(){ //do something } public function bazAction(){ //do something

  • Django rest framework基本介绍与代码示例

    本文研究的主要是Django rest framework的相关内容,分享了example,具体如下. Django REST框架是构建Web API的强大而灵活的工具包. 您可能希望使用REST框架的一些原因: Web浏览的API是您的开发人员的巨大的可用性胜利. 验证策略包括OAuth1a和OAuth2的包. 支持ORM和非ORM数据源的序列化. 如果不需要功能更强大的功能,可以自定义一切 - 只需使用基于功能的常规视图. 广泛的文档和极好的社区支持. 由Mozilla,Red Hat,He

  • django rest framework 数据的查找、过滤、排序的示例

    对于管理系统,常常需要展示列表数据,我们对于列表内的数据常常需要查找.过滤.排序等操作,其中查找等操作大部分是在后台进行的.django rest framework可以轻松的实现数据的查找.过滤等操作.接下来我们将以实际的例子进行介绍. 示例代码github地址: https://github.com/jinjidejuren/drf_learn 例如cmdb系统,作为资产管理系统常常需要对数据进行过滤或查找,获取期望的信息. 实现model 1.在这个示例项目中,需要实现对物理服务器的条件过

随机推荐