【自学开发之旅】Flask-restful-Jinjia页面编写template-回顾(五)

2023-09-14 22:12:28

restful是web编程里重要的概念

– 一种接口规范也是一种接口设计风格

设计接口:
要考虑:数据返回、接收数据的方式、url、方法

统一风格
rest–表现层状态转移
web–每一类数据–资源
资源通过http的动作来实现状态转移 GET、PUT、POST、DELETE

path组成:
/{version}/{resources}/{resource_id}

restful api设计
方法
/v1/product POST 新增
GET 查询所有
/v1/product/id PUT 修改
DELETE 删除
GET 查询某一个

router/product_view/product_api.py

from flask import Blueprint, request
from flask_restful import Api, Resource
from libs.response import generate_response
from . import product_bp

# 将restful api对象和蓝图绑定
api = Api(product_bp)

# 每个资源就是类,定义类
class ProductView(Resource):
    def get(self, id = None):
        return generate_response(msg="get product")
    def post(self):
        generate_response(msg="add product")
    def put(self, id):
        generate_response(msg="modify success!")
    def delete(self, id):
        return generate_response(msg="delete success!")


# 路由
api.add_resource(ProductView, "/product")
api.add_resource(ProductView, "/product/<id>", endpoint="productid")

为什么要设置endpoint:由flask路由管理可知endpoint全局唯一,不指定的话都会默认endpoint为函数名(这里为类名)ProductView重复名了。

这行代码是使用Flask框架(一个Python微型web框架)来定义一个路由。‘api.add_resource’是Flask-RESTful扩展提供的方法,用于将资源(这里是’ProductView’)映射到URL(这里是’/product’)。‘ProductView’可能是一个你定义的类,它继承自Flask-RESTful的’Resource’类,用于处理与产品相关的HTTP请求。’/product’是URL路径,当用户发送请求到这个路径时,Flask会调用’ProductView’类中对应的方法来处理请求。

接着将增删改查功能都实现restful接口规范
router/product_view/product_api.py

"""
@date: 2023/9/12
@file: product_api
@author: Jiangda
@desc: test

"""
from flask import Blueprint, request
from flask_restful import Api, Resource
from libs.response import generate_response
from . import product_bp
from models.product import ProductInfo
from models import db

# 将restful api对象和蓝图绑定
api = Api(product_bp)

# 每个资源就是类,定义类
class ProductView(Resource):
    def get(self, id = None):
        if id:
            result = ProductInfo.query.get(id)
        else:
            result = ProductInfo.query.all()
        if result:
            if isinstance(result, list):
                result2 = [dict(pro) for pro in result]
            else:
                result2 = dict(result)
            return generate_response(msg="get success!", data=result2)
        else:
            return generate_response(code=1010, msg="data empty!")
    def post(self):
        pro_name = request.json.get("proname")
        pro_kind = request.json.get("prokind")
        pro_price = request.json.get("proprice")
        pro_address = request.json.get("proadd")
        if pro_name and pro_kind and pro_price and pro_address:

            proinfo = ProductInfo(product_name = pro_name,
                                  product_kind = pro_kind,
                                  product_price = pro_price,
                                  product_address = pro_address)
            db.session.add(proinfo)
            db.session.commit()
            return generate_response(msg="add success!")
        else:
            return generate_response(msg="add fail!", code=1011)
    def put(self, id):
        p1 = ProductInfo.query.get(id)
        if p1:
            # 接收客户端的传递
            pro_name = request.json.get("proname")
            pro_kind = request.json.get("prokind")
            pro_price = request.json.get("proprice")
            pro_address = request.json.get("proadd")

            p1.product_name = pro_name
            p1.product_kind = pro_kind
            p1.product_price = pro_price
            p1.product_address = pro_address

            db.session.add(p1)
            db.session.commit()
            return generate_response(msg="modify success!")
        else:
            return generate_response(msg="no such product!", code=1012)
    def delete(self, id):
        p2 = ProductInfo.query.get(id)
        if p2:
            db.seesion.delete(p2)
            db.session.commit()
            return generate_response(msg="delete success!")
        else:
            return generate_response(msg="delete failed!", code=1013)

# 路由
api.add_resource(ProductView, "/product")
api.add_resource(ProductView, "/product/<id>", endpoint="productid")

不做前后端分离的项目的话:直接返回网页 web开发模式:MVC(model数据模型+view视图用户界面+control控制路由查找)

flask – MTV模型(M-model,T-template,V-view),写网站(Jinjia模板引擎)

router/view01.py

#render_template()函数:页面渲染
import render_template
@view01_bp.route("index2")
def index2():
    return render_template("index.html", message = "hello k8s")

templates/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{{ message }}
<img src="/static/images/k8s.jpg">
</body>
</html>

在这里插入图片描述

使用bootstrap4实例:

router/product_view/product.py
添加

import render_template


return render_template("product.html", prolist=result2)

访问http://127.0.0.1:9000/v1/product/get
在这里插入图片描述
templates/product.html
在body加入

  <table class="table">
      <th><td>产品名称</td>
      <td>产品种类</td>
      <td>产品价格</td>
      <td>产品产地</td>
      </th>
      {% for pro in prolist %}
      <tr><td></td>
      <td>{{ pro["product_name"] }}</td>
      <td>{{ pro["product_kind"] }}</td>
      <td>{{ pro["product_price"] }}</td>
      <td>{{ pro["product_address"] }}</td>
  </tr>
      {% endfor %}
  </table>

在这里插入图片描述

加按钮,且利用url_for()通过endpoint找url
templates/product.html

<td>操作</td>
<td><button type="button" class="btn btn-light"><a href="{{ url_for('product_bp.productdelete', id = pro.product_id) }}">删除</a></button></td>

router/product_view/product2.py

@product_bp.route("/product2/delete", methods=['GET'])
def productdelete():
    id = request.args.get("id")
    p2 = ProductInfo.query.get(id)
    if p2:
        db.session.delete(p2)
        db.session.commit()
        return render_template("product.html",msg="delete success!")
    else:
        return generate_response(msg="no such product", code=6)

添加增加功能
router/product_view/product2.py

@product_bp.route("/product2/add" ,methods=['GET','POST'])
def productadd():
    # 接收客户端的传递
    pro_name = request.form.get("proname")
    pro_kind = request.form.get("prokind")
    pro_price = request.form.get("proprice")
    pro_address = request.form.get("proadd")

    proinfo = ProductInfo(product_name = pro_name,
                          product_kind = pro_kind,
                          product_price = pro_price,
                          product_address = pro_address)

    # 生效到数据库
    db.session.add(proinfo)
    db.session.commit()

    return render_template("product_add.html")

templates/product_add.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" type="text/css" href="/static/css/bootstrap.css">
</head>
<body>
<form method="post">

  <div class="form-group row">
    <label for="inputPassword" class="col-sm-2 col-form-label">产品名称</label>
    <div class="col-sm-10">
      <input class="form-control" name="proname">
    </div>
  </div>

      <div class="form-group row">
    <label for="inputPassword" class="col-sm-2 col-form-label">产品类型</label>
    <div class="col-sm-10">
      <input class="form-control" name="prokind">
    </div>
  </div>

      <div class="form-group row">
    <label for="inputPassword" class="col-sm-2 col-form-label">产品价格</label>
    <div class="col-sm-10">
      <input class="form-control" name="proprice">
    </div>
  </div>

      <div class="form-group row">
    <label for="inputPassword" class="col-sm-2 col-form-label">产品产地</label>
    <div class="col-sm-10">
      <input class="form-control" name="proadd">
    </div>
  </div>
    <input type="submit" value="新增">
    <input type="reset" value="取消">
</form>
</body>
</html>

为什么用orm?什么是orm?
对象关系映射,它不需要和复杂的sql语句打交道,直接操控对象就是操控数据库,把表映射为类,把字段映射为属性,每一行记录映射为对象,提高我们开发的速度,方便开发。
可以不用,我们用过pymysql去创建sql语句去做的。

对象关系映射(Object Relational Mapping,简称ORM)是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。它通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。
ORM的由来:面向对象是从软件工程基本原则(如耦合、聚合、封装)的基础上发展起来的,而关系数据库则是从数学理论发展而来的,两套理论存在显著的区别。为了解决这个不匹配的现象,对象关系映射技术应运而生。
简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。 ORM提供了实现持久化层的另一种模式,它采用映射元数据来描述对象关系的映射,使得ORM中间件能在任何一个应用的业务逻辑层和数据库层之间充当桥梁。

什么是restful?
一种接口规范也是一种接口设计风格,一般来说api的设计都会遵循,他是表现层状态转移,它将每一类数据看做成资源,每一类资源又为其设计一种url,这种资源的增删改查通过http的动作(get post put delete)等方法来实现

RESTful是一种网络应用程序的设计风格和开发方式,基于HTTP,可以使用XML格式定义或JSON格式定义。它适用于移动互联网厂商作为业务使能接口的场景,实现第三方OTT调用移动网络资源的功能。
在RESTful中,每个资源都有一个唯一的URL,可以通过HTTP请求来获取或修改该资源的状态。RESTful采用了一种无状态协议,即服务器不维护与客户端的连接状态,每个请求都是独立的。这种无状态协议使得RESTful更加灵活和可扩展,可以轻松地支持并发请求和负载均衡。
RESTful的核心思想是将网络资源视为一种状态,并通过HTTP协议来传输和操作这些状态。在RESTful中,每个资源都有一个唯一的URL,可以通过HTTP请求来获取或修改该资源的状态。客户端使用GET、POST、PUT、DELETE4个表示操作方式的动词对服务端资源进行操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源。

统一接口返回
也是restful接口返回的一种规范,返回json数据,返回data,code,message。

更多推荐

使用qt完善对话框功能

1、完善登录框点击登录按钮后,判断账号(admin)和密码(123456)是否一致,如果匹配失败,则弹出错误对话框,文本内容“账号密码不匹配,是否重新登录”,给定两个按钮ok和cancel,点击ok后,会清除密码框中的内容,继续进行登录;如果点击cancel按钮,则关闭界面。如果账号和密码匹配,则弹出信息对话框,给出提

zookeeper + kafka

Zookeeper概述Zookeeper是一个开源的分布式服务管理框架。存储业务服务节点元数据及状态信息,并负责通知再ZooKeeper上注册的服务几点状态给客户端Zookeeper工作机制Zookeeper从设计模式角度来理解:是一个基于观察者模式设计的分布式服务管理框架,它负责存储和管理大家都关心的数据,然后接受观

Spring 框架的 MethodInterceptor 简介

org.springframework.cglib.proxy.MethodInterceptor是CGLIB库(CodeGenerationLibrary)中的一个接口,用于拦截方法的调用。CGLIB是一个用于生成Java字节码的代码生成库,它通常与SpringAOP一起使用,用于创建动态代理。MethodInter

IaaS,PaaS,SaaS 的区别

越来越多的软件,开始采用云服务。云服务只是一个统称,可以分成三大类。IaaS:基础设施服务,Infrastructure-as-a-servicePaaS:平台服务,Platform-as-a-serviceSaaS:软件服务,Software-as-a-serviceSaaS是软件的开发、管理、部署都交给第三方,不需

Java反序列化和PHP反序列化的区别

文章目录PHP反序列化漏洞什么是反序列化漏洞?修改序列化后的数据,目的是什么?Java反序列化漏洞那么漏洞点在哪里?漏洞成因什么是反序列化漏洞?反序列化存在的意义是为了数据传输,类是无法直接进行传输的。通过序列化后转换为字符串格式或者JSON格式进行传输。序列化与反序列化seriallization序列化:将对象转化为

Java多线程篇(4)——wait/notify和park/unPark

文章目录Object-wait/notifyobject.wait()object.notify()LockSupport-park/unparkLockSupport.park()LockSupport.unPark()Object-wait/notifyobject.wait()ObjectSynchronizer

宏任务,微任务,事件循环event loop与promise、setTimeout、async、nextTick【超详细示例讲解】

目录js单线程宏任务:在主线程上排队执行的任务,顺序执行宏任务macrotask:setTimeout,setInterval定时事件,Ajax,DOM事件,script脚本的执行、I/O操作、UI渲染等。微任务:不进入主线程、而进入"微任务列表"的任务微任务microtask(异步):Promise、async/aw

聚合支付备案对聚合支付系统及安全有何要求?

聚合支付备案,依据《收单外包服务机构备案管理办法》《收单外包服务机构自律规范》《关于加强收单外包服务市场规范管理的意见》等政策,对聚合支付系统及安全要求如下:对聚合支付机构要求一是聚合支付机构应当具备必要的、独立的系统、设施和技术,提供安全、稳定且可持续的聚合支付技术服务。其中,独立的系统是指聚合支付系统逻辑独立并与其

芯科科技第二代平台的所有蓝牙片上系统均可支持蓝牙技术联盟的新功能和新标准

中国,北京-2023年9月21日–致力于以安全、智能无线连接技术,建立更互联世界的全球领导厂商SiliconLabs(亦称“芯科科技”,NASDAQ:SLAB),今日宣布其支持蓝牙技术联盟(BluetoothSIG)针对蓝牙网状网络(BluetoothMesh)实现的新功能增强,以及他们新的网络照明控制(NLC)标准,

【从0学习Solidity】17. 库合约 站在巨人的肩膀上

【从0学习Solidity】17.库合约站在巨人的肩膀上博主简介:不写代码没饭吃,一名全栈领域的创作者,专注于研究互联网产品的解决方案和技术。熟悉云原生、微服务架构,分享一些项目实战经验以及前沿技术的见解。关注我们的主页,探索全栈开发,期待与您一起在移动开发的世界中,不断进步和创造!本文收录于不写代码没饭吃的学习汇报系

RHCE---时间服务器

文章目录目录文章目录前言一.安装时间服务器软件初始化系统二.配置时间服务器的服务端三.配置时间服务器的客户端四.远程连接服务器前言Linux中的时间服务器是指NTP服务器,NTP是NetworkTimeProtocol的缩写,即网络时间协议。NTP服务器可以提供精确的时间信息,从而使得网络上的所有设备都能够同步时间,确

热文推荐