zoukankan      html  css  js  c++  java
  • fastapi之根据model生成schema和router

      概述

      fastapi没有对应的admin,所以在需要配置后端的时候,会比较麻烦,每个接口都需要自己手动写。

      但是很多时候我们可能需要一个比较标准的东西,比如…一个装饰器

      通过装饰器装饰model就可以自动注册路由,自动生成对应的标准方法,再根据更多的一些自定义配置,甚至不需要自己手动写schema,然后不需要自己单独写路由相关的东西。(相当于给sqlalchemy的model增加django的model的部分功能)

      原理

      通过type动态生成对应的model。再自动注册到服务器

      使用说明

      使用方法如下:

      #创建model的时候,get_basemodel装饰系统

      @get_basemodel

      class User(Base):

      __tablename__='users'

      id = Column(Integer, primary_key=True, index=True)

      email = Column(String(64), unique=True, index=True,default="chise123@live.com")

      hashed_password = Column(String(64))

      is_active = Column(Boolean, default=True)

      items = relationship("Item", back_populates="owner")

      在main里面的router注册:

      # user是model,app是写入系统,

      User.__model__.write2route('/user',app,User,get_db = SessionLocal())

      这是一个demo,做技术验证用,之后会逐步完善该功能,

      装饰器代码

      这里只是有一个list的方法(对应methods的get)

      # -*- encoding: utf-8 -*-

      """

      @File : test_selializers.py

      @Time : 2020/4/1 1:03

      @Author : chise

      @Email : chise123@live.com

      @Software: PyCharm

      @info :尝试将model转为basemodel的类,实现操作

      """

      from pydantic import BaseModel, Field

      from typing import NewType

      from sqlalchemy import Integer, Table

      UserId = NewType('UserId', int)

      # admin_basemodel = []

      from fastapi import APIRouter

      class RouterBaseModel(BaseModel):

      """这个类主要是给生成的schema增加操作"""

      @staticmethod

      def list(model, db): # 对应get方法

      """methods=get,读取列表"""

      def res():

      return db.query(model).all()

      # print(model.__table__.select())

      return res

      def write2route(self, ul, route: APIRouter, model, get_db):

      """注册到路由"""

      route.get(ul)(self.list(model, get_db))

      class Config:

      orm_mode = True

      def get_basemodel(cls):

      """通过读取model的信息,创建schema"""

      model_name = cls.__name__

      # mappings为从model获取的相关配置

      __mappings__ = {} # {'name':{'field':Field,'type':type,}}

      for filed in cls.__table__.c:

      filed_name = str(filed).split('.')[-1]

      if filed.default:

      default_value = filed.default

      elif filed.nullable:

      default_value = ...

      else:

      default_value = None

      # 生成的结构: id:int=Field(...,)大概这样的结构

      res_field = Field(default_value, description=filed.description) # Field参数

      if isinstance(filed.type, Integer):

      tp = NewType(filed_name, int)

      else:

      tp = NewType(filed_name, str)

      __mappings__[filed_name] = {'tp': tp, 'Field': res_field}

      res = type(model_name, (RouterBaseModel,), __mappings__)

      # 将schema绑定到model

      cls.__model__ = res()

      return cls

      实现效果

  • 相关阅读:
    2.六角星绘制
    1.五角星绘制
    Redis
    javaScript
    反射
    区分'方法'和'函数'
    递归,二分法
    匿名函数,排序函数,过滤函数,映射函数,
    生成器,生成器函数,推导式,生成器表达式.
    函数,闭包,迭代器
  • 原文地址:https://www.cnblogs.com/djw12333/p/12620324.html
Copyright © 2011-2022 走看看