欢迎访问www.allbetgaming.com!

首页科技正文

焦作房产网:第 3 篇:实现博客首页文章列表 API

admin2020-05-0140

作者:HelloGitHub-追梦人物

文中所涉及的示例代码,已同步更新到 HelloGitHub-Team 堆栈

此前在讨论基于模板引擎的开发方式和 django-rest-framework 开发的异同时说过,django-rest-framework 开发和传统的开发方式没有什么差别,区别仅在于返回的数据花样差别而已。

在基于模板引擎的开发方式中,博客首页文章列表的视图函数可能是这样的:

from django.shortcuts import render
from .models import Post

def index(request):
    post_list = Post.objects.all().order_by('-created_time')
    return render(request, 'blog/index.html', context={'post_list': post_list})

在 django-rest-framework,代码逻辑是一样的,只是在最后返回效果时,返回资源序列化后的效果。

from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status

from .models import Post
from .serializers import PostListSerializer

@api_view(http_method_names=["GET"])
def index(request):
    post_list = Post.objects.all().order_by('-created_time')
    serializer = PostListSerializer(post_list, many=True)
    return Response(serializer.data, status=status.200)

暂且忽略掉资源序列化器 PostListSerializer,我们接下来会实现它,先把注重力放在主体逻辑上。

首先,我们从 rest_framework.decorators 中导入了 api_view 装饰器,并用它装饰了 index 视图函数,使其成为一个 RESTful API 视图函数。

为什么需要这个视图函数装饰器呢?之前说过,django-rest-framework 为 API 的开发提供了厚实的功效,包罗内容协商、认证和鉴权、限流等等。这些历程 django 默认的视图函数在处置 HTTP 请求时是没有提供的,而经由 api_view 装饰后的视图,则提供了上述所有功效。

不外我们这里并没有看到任何内容协商、认证和鉴权、限流代码逻辑和设置,这是为什么呢?缘故原由隐藏在 Python 的装饰器邪术里,django-rest-framework 对于上述功效有一套默认的处置逻辑,因此我们不需要举行任何设置,仅需使用 api_view 装饰一个 django 视图函数,所有功效所有自动开启。

视图函数里我们先从数据库获取文章列表资源,然后使用序列化器对其举行序列化,序列化后的数据存在 data 属性里,我们把它通报给 HTTP 响应类 Response,并将这个响应返回。

注重这个 Response 是从 rest_framework.response 中导入的,它类似于 django 的 HTTPResponse 响应类。现实上,这个类是 django-rest-framework 对 django 的模板响应类(SimpleTemplateResponse)的拓展(详细的细节可以不用领会,只要知道 django 使用它来渲染模板并组织 HTTP 响应即可),通常在 RESTful API 的视图函数中我们都市返回这个类,而不是 django 的 HTTP 响应类。此外,通过传入 status 参数,指定 HTTP 响应的状态码。

小贴士

请领会常用的 HTTP 状态码。在 RESTful 架构中,客户端通过 HTTP 请求动词表征对资源的操作意图,而服务端则使用 HTTP 状态码示意资源操作的效果。常用状态码及其寄义如下:

200:通常示意请求乐成。

201:示意资源建立乐成。

400:示意客户端请求错误。

401:没有提供身份认证信息

403:没有操作权限

404 :接见的资源不存在

405:不支持的 HTTP 请求方式

500:服务器内部错误

HTTP 请求和响应历程,django-rest-framework 已经帮我们处置。然则资源的序列化,框架是无法自动化完成的,框架提供了基本的序列化器,我们需要自界说序列化逻辑。以是,让我们来界说 PostListSerializer 序列化器,用它来序列化文章列表。

序列化器由一系列的序列化字段(Field)组成,序列化字段的作用是,在序列化资源时,将 Python 数据类型转为原始数据类型(通常为字符类型或者二进制类型),以便在客户端和服务端之间通报;反序列化时,将原始数据类型转为 Python 数据类型。在转换历程中,还会举行数据合法性的校验。

先来看一个简朴的例子(摘自 django-rest-framework 官网示例),明白序列化器的事情原理和功效。假设我们有一个 Python 类 Comment

from datetime import datetime

class Comment(object):
    def __init__(self, email, content, created=None):
        self.email = email
        self.content = content
        self.created = created or datetime.now()

comment = Comment(email='leila@example.com', content='foo bar')

凭据 Comment 类 3 个属性的类型,界说一个序列化器,用于数据序列化和反序列化。我们在上一步教程的 交流的桥梁:谈论功效 中先容过表单(Form)的界说。现实上,django-rest-framework 序列化器的设计参考了 django 表单的设计。序列化器和表单也有许多相似功效,比如对输入数据举行校验等。序列化器的代码如下:

from rest_framework import serializers

class CommentSerializer(serializers.Serializer):
    email = serializers.EmailField()
    content = serializers.CharField(max_length=200)
    created = serializers.DateTimeField()

自界说的序列化器都要继续 serializers.Serializer 基类,基类提供了数据序列化和反序列化的逻辑。凭据被序列化工具的属性的数据类型,需要指定响应的序列化字段(Serializer Field)。django-rest-framework 提供了许多常用的序列化字段,例如本例中用于序列化 email 数据花样的 EmailField,用于序列化字符型数据花样的 CharField,用于序列化日期花样的 DateTimeField。在现实项目中,应该凭据数据类型,选择合适的序列化字段。所有序列化字段,可以参考官方文档 Serializer fields。

有了序列化器,就可以将 Comment 工具序列化了,序列化器用法如下:

>>> serializer = CommentSerializer(comment)
>>> serializer.data
# 输出:
{'email': 'leila@example.com', 'content': 'foo bar', 'created': '2016-01-27T15:17:10.375877'}

首先将需要序列化的工具(comment)传入序列化器(CommentSerializer),组织一个序列化器工具(serializer),接见序列化器工具的 data 属性,就可以获得序列化后的数据。

被序列化工具序列化后的数据是一个扁平的 Python 字典,字典中的数据形貌了这个工具资源。有了序列化天生的 Python 字典,我们就可以将字典数据进一步花样化为 JSON 字符串或者 XML 文档字符串,在客户端和服务端之间传输。试想,客户端服务端通常都通过 HTTP 协议传输数据,传输的数据只能是字符串或者二进制数据,不能能将一个 Python 的工具直接通报,这就是为什么要序列化的缘故原由。一端接收到序列化的数据后,如果有需要,可以对数据举行反序列化,重新恢复为 Python 工具。

以上就是一个尺度序列化器的界说。其要害点在于,凭据被序列化工具属性的数据类型,选择合适的序列化字段。回首我们在上一步教程的 交流的桥梁:谈论功效 中对谈论表单的界说,我们通过继续 ModelForm 界说了表单,而并没有显示地指定表单字段的类型。缘故原由在于,对于 django 中的模子(Model),已经有了界说其数据类型的模子字段,因此 django 表单可以凭据关联的模子,自动推测需要使用的表单字段,在背后帮我们完成表单字段的选择,简化了表单的界说。

和表单类似,django-rest-framework 的序列化器也可以凭据关联的模子,自动检测被序列化模子各个属性的数据类型,推测需要使用的序列化字段,无需我们显示界说。此时,自界说的序列化器不再继续尺度的 Serializer,而是继续其子类,ModelSerializer

我们来编写文章(Post)模子的序列化器代码。根据习惯,序列化器的代码位于响应应用的 serializers.py 模块中,因此在 blog 应用下新建一个 serializers.py 文件,写上如下代码:

from rest_framework import serializers
from .models import Post

class PostListSerializer(serializers.ModelSerializer):
    category = CategorySerializer()
    author = UserSerializer()
    
    class Meta:
        model = Post
        fields = [
            'id',
          	'title',
          	'created_time',
          	'excerpt',
          	'category',
          	'author',
          	'views',
        ]

使用 ModelSerializer 时,只需要在序列化器的内部类 Meta 中指定关联的模子,以及需要序列化的模子属性,django-rest-framework 就会凭据各个属性的数据类型,自动推测需要使用的系列化字段,从而天生尺度的序列化器。事实上,我们可以来看一下 django-rest-framework 最终天生的序列化器长什么样子:

class PostListSerializer():
    id = IntegerField(label='ID', read_only=True)
    title = CharField(label='题目', max_length=70)
    created_time = DateTimeField(label='建立时间', required=False)
    excerpt = CharField(allow_blank=True, label='摘要', max_length=200, required=False)
    category = CategorySerializer()
    author = UserSerializer()

还需要注重一点,titlecreated_timeviews 这些属性都是原始的数据类型(字符型、日期型、整数类型)。而对于文章关联的 categoryauthor,它们自己也是一个工具,django-rest-framework 就无法推测该使用什么类型的系列化字段来序列化它们了。以是这里我们根据尺度序列化器的界说方式,将这两个属性的系列化字段划分界说为 CategorySerializerUserSerializer,意思是告诉 django-rest-framework,请使用 CategorySerializerUserSerializer 来序列化关联的 categoryauthor。现实上,序列化器自己也是一个序列化字段。固然,CategorySerializerUserSerializer 现在还不存在,我们来界说他们:

from django.contrib.auth.models import User
from .models import Category, Post

class CategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = Category
        fields = [
            'id',
          	'name',
        ]
        
class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = [
            'id',
          	'username',
        ]
        
class PostListSerializer(serializers.ModelSerializer):
	# ...

再来回首一下我们的 API 视图函数代码:

@api_view(http_method_names=["GET"])
def index(request):
    post_list = Post.objects.all().order_by('-created_time')
    serializer = PostListSerializer(post_list, many=True)
    return Response(serializer.data, status=status.HTTP_200_OK)

注重这里 PostListSerializer 的用法,组织序列化器时可以传入单个工具,序列化器会将其序列化为一个字典;也可以传入包罗多个工具的可迭代类型(这里的 post_list 是一个 django 的 QuerySet),此时需要设置 many 参数为 True 序列化器会依次序列化每一项,返回一个列表。

api_view 装饰器传入 http_method_names 参数指定允许接见该 API 视图的 HTTP 方式。

现在我们已经有了视图函数,最后,我们需要给这个视图函数绑定 URL,在 blog 应用下的 urls.py 中加入绑定的代码:

path('api/index/', views.index)

启动开发服务器,打开浏览器接见 http://127.0.0.1:8000/api/index/ ,可以看到接口返回了文章列表 JSON 花样的数据(默以为 JSON)。

现在来说,这个接口实在作用不大。不外在后续的教程中,我们学习前端框架 Vue,那个时候,RESTful API 就有了它的用武之地了。

回首一下 index API 视图函数的基本逻辑:

  1. 从数据库取数据
  2. 组织序列化器并将取出的数据序列化
  3. 返回响应

这实在是接见序列型的资源对照常见的逻辑,我们知道,django 专门为这种在 Web 开发中常用的逻辑提供了一系列基于类的通用视图,以提高代码的复用性和削减代码量。只是 django 的通用视图适用于基于模板引擎的开发方式,同样的,django-rest-framework 也提供了专门针对 RESTful API 开发历程中常用逻辑的类视图通用函数。接下来,让我们使用 django-rest-framework 提供的通用类视图,将首页 API 的视图函数改为类视图。

关注民众号加入交流群

,

阳光在线

阳光在线www.kingtaowang.com(原诚信在线)现已开放阳光在线手机版下载。阳光在线游戏公平、公开、公正,用实力赢取信誉。

转载声明:本站发布文章及版权归原作者所有,转载本站文章请注明文章来源!

本文链接:https://www.juneview.com/post/760.html

网友评论

最新评论

  • 环球UG手机版下载 09/21 说:

    欧博开户网址欢迎进入欧博开户网址(Allbet Gaming):www.aLLbetgame.us,欧博网址开放会员注册、代理开户、电脑客户端下载、苹果安卓下载等业务。路过打酱油,不走了

  • 环球UG客户端 09/21 说:

    欧博亚洲注册欢迎进入欧博亚洲注册(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。评论一下,记得我来过

  • 环球UG官网 09/19 说:

    AllbetGmaing手机版下载欢迎进入AllbetGmaing手机版下载(www.aLLbetgame.us):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。别具一格

  • 环球UG注册 09/18 说:

    欧博allbet网址欢迎进入欧博allbet网址(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。感觉还可以,继续追。

  • 环球UG注册 09/18 说:

    欧博allbet网址欢迎进入欧博allbet网址(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。感觉还可以,继续追。

  • 皇冠体育APP 09/18 说:

    欧博开户网址欢迎进入欧博开户网址(Allbet Gaming):www.aLLbetgame.us,欧博网址开放会员注册、代理开户、电脑客户端下载、苹果安卓下载等业务。下笔如有神

  • UG环球网址 09/18 说:

    AllbetGmaing电脑版下载欢迎进入AllbetGmaing电脑版下载(www.aLLbetgame.us):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。反正我跪了

  • UG环球客户端 09/18 说:

    Allbet Gmaing欢迎进入欧博Allbet官网(www.aLLbetgame.us):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。我也来看