【Python/Django】restful api与django rest framework的简单使用

什么是API

API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。 ——百度百科

简单来说就是:别人写好代码,编译号程序,可以让其他人调用使用,就称作API。你使用了别人代码(或者程序)中的某个函数、类、对象,就叫做使用了某个API。

什么是restful

restful是一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。 ——百度百科

restful api

随着前后端分离的流行, 为了减少前后端的沟通成本. 那么势必有一套开发规范来为前后端开发提供标准, restful api就是这样的开发规范。

RESTful API(应用程序接口)是符合RESTful规范的框架,用它可以实现跨平台、广泛覆盖客户端(包括浏览器和移动设备)的HTTP服务。大多数网站提供API,以便开发人员可以在其上进行扩展开发,二次开发等

为什么要进行前后端分离

  • MTV模型这样高度耦合的开发模式更适合个人独立开发, 不适合多人员的配合和快速迭代.

  • 为了适配网页端和移动端等多个终端.

  • 前端业务场景已经越来越复杂, 需要有专业的人员进行开发, 减少了开发人员的学习成本.

 restful api架构

URL用来定位资源, method用来表示操作.

基于HTTP协议扩展的开发规范.

  • URL

  • METHOD

  • HTTP请求格式

    • 请求体

    • 请求头

  • HTTP响应格式

    • 返回头

    • 返回数据类型

状态码

  • 200  表示成功

  • 400

    • 401  没有权限

    • 403  访问被禁止

    • 404  未找到对应资源

  • 500  表示服务器内部错误.

面向资源的涉及理念

将前端和后端之间的交互抽象为对数据, 也就是资源的操作.

url只表示资源的路径

动词不应该出现在url当中

可以在域名中体现当前api接口

可以在url当中体现当前api接口的版本

HTTP协议中的method表示操作

  • GET(retrieve)

  • POST(create)

  • PUT(update)

  • DELETE(delete)

 关于restful的更多详细内容,可参考:

http://www.ruanyifeng.com/blog/2014/05/restful_api.html

https://www.jianshu.com/p/73d2415956bd


django rest framework

官网地址:https://www.django-rest-framework.org/

安装

pip install djangorestframework

要求django版本>=2.2

配置

# settings.py

INSTALLED_APPS = [
    ...
    'rest_framework',
]

序列化器 serializers

序列化器有两个主要功能:序列化和反序列化。

如果前端是GET请求,则构造查询集,将结果返回,这个过程为序列化

如果前端是POST请求,要对数据库进行改动,则需要拿到前端发来的数据,进行校验,校验通过将数据写入数据库,这个过程称为反序列化。这能极大的简化视图代码量。

编写serializers模块

  • 新建文件 serializers.py

  • 编写序列化模型

# serializers.py

from rest_framework import serializers
from .models import Article


class ArticleSerializer(serializers.ModelSerializer):
    class Meta:
        # 制定model
        model = Article
        # 可以只填充我们使用到,需要验证的字段
        fields = ("title", "text", "url", "create_time")

序列化方法

model对象 -> OrderedDict对象 -> json对象

# 进入shell环境
from blog.models import Article
from blog.serializers import ArticleSerializer

>>> article_array = Article.objects.all()
>>> se_articles = ArticleSerializer(aritcles, many=True)
>>> json_articles = json.dumps(se_articles.data)

# 序列化单个对象
>>> article = article_array[0]
>>> se_article = ArticleSerializer(aritcle)

反序列化方法

json对象 ->model对象

# 进行反序列化
>>> se_article = ArticleSerializer(json_data)
>>> se_article.is_valid()
>>> True
>>> article = se_article.create(se_article.data)
>>> article
<Article: <Article 课程一(一)>>

编写视图

from rest_framework.views import APIView
from django.db import transaction # 这里同时引入了一个事务库

class ArticleApiView(APIView):
    def get(self, request, *args, **kwargs):
        """
        :param args:
        :param kwargs:
        :return:
        """
        Article.objects.all()
        se_article_array = ArticleSerializer(article_array, many=True)
        return JsonResponse({
            "status": 200,
            "data": se_article_array.data
        }, safe=False)

    def post(self, request, *args, **kwargs):
        """
        添加文章的时候, 需要带上category和tag的信息
        只要article, category, tag有一方报错的时候, 当前文章都算添加失败.
        所以我们应该使用用事务进行包装
        :param request:
        :param args:
        :param kwargs:
        :return:
        """
        try:
            message = {"status": 200}
            with transaction.atomic():
                title = request.POST['title']
                text = request.POST['text']
                categories = json.loads(request.POST['categories'])
                tags = json.loads(request.POST['tags'])

                article_data = {
                    "title": title,
                    "text": text,
                    "url": f"/{time.strftime('%Y/%m/%d')}/{title}.html"
                }
                se_article = ArticleSerializer(data=article_data)
                se_article.is_valid()
                article = se_article.create(se_article.data)
                article.save()

                for category in categories:
                    cate = Category(
                        name=category['name'],
                        slug=category['slug'],
                        uri=f"/categories/{category['slug']}/"
                    )
                    cate.article = article
                    cate.save()

                for tag in tags:
                    tag = Tag(
                        name=tag['name'],
                        slug=tag['slug'],
                        uri=f"/tags/{tag['slug']}/"
                    )
                    tag.article = article
                    tag.save()
        except:
            message = {"status": 500, "reason": "添加文章失败"}
        finally:
            return JsonResponse(message, safe=False)

    def put(self, request, *args, **kwargs):
        """
        request.POST(key)
        :param request: 
        :param args: 
        :param kwargs: 
        :return: 
        """
        pass

    def delete(self, request, *args, **kwargs):
        pass

Everything is going smoothly.

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值