最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Flask自定義序列化超詳細講解

 更新時間:2022年11月10日 08:54:28   作者:京金  
序列化其實就是將數(shù)據(jù)轉(zhuǎn)化成一種可逆的數(shù)據(jù)結(jié)構(gòu),自然,逆向的過程就叫做反序列化。php將數(shù)據(jù)序列化和反序列化會用到兩個函數(shù):serialize 將對象格式化成有序的字符串、unserialize 將字符串還原成原來的對象

1、問題溯源

重點就是一個Flask.make_response,這里會做請求的響應(yīng)的處理。

里面行代碼:

elif isinstance(rv, dict):
     rv = jsonify(rv)

rv是我需要返回的響應(yīng):

{
	'msg': [
        {'roleName': 'guest', 'access_list':[<accessName root>]},
        {'roleName': 'admin', 'access_list': [...]}
        ], 
    'error_no': 0
}

rv是一個字典,但是msg的里面有部分東西無法序列化,jsonify里面返回如下。

return current_app.response_class(
        f"{dumps(data, indent=indent, separators=separators)}\n",
        mimetype=current_app.config["JSONIFY_MIMETYPE"],
    )

里面的data就是上面交道的類似json的數(shù)據(jù)(不是json,實際是對象)。

接下來:調(diào)用了flask下的自帶的一個json庫。

代碼片段: M-1

_dump_arg_defaults(kwargs, app=app)
return _json.dumps(obj, **kwargs)

代碼片段: M -2

if cls is None:
        cls = JSONEncoder
return cls(
        skipkeys=skipkeys, ensure_ascii=ensure_ascii,
        check_circular=check_circular, allow_nan=allow_nan, indent=indent,
        separators=separators, default=default, sort_keys=sort_keys,
        **kw).encode(obj)

這里的obj的:

{'msg': [{...}, {...}], 'error_no': 0}

就是我們之前講到的東西。

代碼片段: M-4,這個是內(nèi)置的json庫的default方法。內(nèi)置的沒有實現(xiàn)序列化,所以需要自己在某個步驟接入到這個序列化的過程。

def default(self, o):
        """Implement this method in a subclass such that it returns
        a serializable object for ``o``, or calls the base implementation
        (to raise a ``TypeError``).
        For example, to support arbitrary iterators, you could
        implement default like this::
            def default(self, o):
                try:
                    iterable = iter(o)
                except TypeError:
                    pass
                else:
                    return list(iterable)
                # Let the base class default method raise the TypeError
                return JSONEncoder.default(self, o)
        """
        raise TypeError(f'Object of type {o.__class__.__name__} '
                        f'is not JSON serializable')

o在這里就是AccessOrm是實例對象,所以他報錯說這個:

Object of type AccessOrm is not JSON serializable

歸因:就是flask沒有自帶實現(xiàn)對類的序列化

解決: 就是通過flask的機制,綁定一個序列化類。

2、flask序列化

flask代碼里面寫了:

class JSONEncoder(_json.JSONEncoder):
    """The default JSON encoder. Handles extra types compared to the
    built-in :class:`json.JSONEncoder`.
    -   :class:`datetime.datetime` and :class:`datetime.date` are
        serialized to :rfc:`822` strings. This is the same as the HTTP
        date format.
    -   :class:`uuid.UUID` is serialized to a string.
    -   :class:`dataclasses.dataclass` is passed to
        :func:`dataclasses.asdict`.
    -   :class:`~markupsafe.Markup` (or any object with a ``__html__``
        method) will call the ``__html__`` method to get a string.
    Assign a subclass of this to :attr:`flask.Flask.json_encoder` or
    :attr:`flask.Blueprint.json_encoder` to override the default.
    """

在片段代碼M-1中:

_dump_arg_defaults(kwargs, app=app)

函數(shù)內(nèi)容如下:

def _dump_arg_defaults(
    kwargs: t.Dict[str, t.Any], app: t.Optional["Flask"] = None
) -> None:
    """Inject default arguments for dump functions."""
    if app is None:
        app = current_app
    if app:
        cls = app.json_encoder #app的json_encoder
        bp = app.blueprints.get(request.blueprint) if request else None  # type: ignore
        if bp is not None and bp.json_encoder is not None:
            cls = bp.json_encoder #這里設(shè)置藍圖的json_encoder,藍圖的優(yōu)先級高于app.json_encoder
        # Only set a custom encoder if it has custom behavior. This is
        # faster on PyPy.
        if cls is not _json.JSONEncoder:
            kwargs.setdefault("cls", cls)
        kwargs.setdefault("cls", cls)
        kwargs.setdefault("ensure_ascii", app.config["JSON_AS_ASCII"])
        kwargs.setdefault("sort_keys", app.config["JSON_SORT_KEYS"])
    else:
        kwargs.setdefault("sort_keys", True)
        kwargs.setdefault("cls", JSONEncoder)

3、解決方法

使用自帶的序列化類

在入口函數(shù)setup.py中寫入

from flask import Flask
from flask.json import JSONEncoder
from config import Config,LogConfig
from db import init_db
from scripts import user_cli
from flask_bcrypt import Bcrypt
from utils import RedisPool
class ExtendJSONEncoder(JSONEncoder):
    def default(self, o):
        if getattr(o,'toJson'):
            return o.toJson(o)
        else:
            return super().default(o)
flask_bcrypt = Bcrypt()
def create_app():
    Flask.json_encoder = ExtendJSONEncoder 
    #之前在with app.app_context()
    #或者在app實例化之后,修改app的JSONEncoder 都沒成功,這里簡單粗暴一點,直接修改Flask的。
    app = Flask(__name__)
    app.config.from_object(Config)
    LogConfig.openLog()
    from utils import initException,initBeforeRequestHandle
    with app.app_context():
        init_db(app)
        RedisPool(app)
        initException(app)
        initBeforeRequestHandle(app)
        flask_bcrypt.init_app(app)
        app.cli.add_command(user_cli)
        import controller
        for bp in controller.__all__:
            app.register_blueprint(controller.__dict__[bp])
    return app

這時候,我的orm類需要一個toJson方法。

class AccessOrm(Base):
    __tablename__ = 'access'
    id = Column(Integer, primary_key=True)
    accessName = Column(String(255), nullable=True)
    def __repr__(self) -> str:
        return "<accessName {}>".format(
            self.accessName,
            )
    def toJson(self,o):
        return {
            'accessName': o.accessName,
        }

到此這篇關(guān)于Flask自定義序列化超詳細講解的文章就介紹到這了,更多相關(guān)Flask序列化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python安裝.whl文件流程以及問題解決方法

    Python安裝.whl文件流程以及問題解決方法

    WHL文件是以Wheel格式保存的Python安裝包,Wheel是Python發(fā)行版的標準內(nèi)置包格式,下面這篇文章主要給大家介紹了關(guān)于Python安裝.whl文件流程以及問題解決方法的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-05-05
  • Python安裝jieba庫詳細教程

    Python安裝jieba庫詳細教程

    jieba庫是一款優(yōu)秀的 Python 第三方中文分詞庫,jieba 支持三種分詞模式:精確模式、全模式和搜索引擎模式,這篇文章主要介紹了Python安裝jieba庫教程,需要的朋友可以參考下
    2023-03-03
  • 用python寫一個帶有g(shù)ui界面的密碼生成器

    用python寫一個帶有g(shù)ui界面的密碼生成器

    這篇文章主要介紹了用python寫一個帶有g(shù)ui界面的密碼生成器,幫助大家更好的理解和使用python,感興趣的朋友可以了解下
    2020-11-11
  • python多線程請求帶參數(shù)的多個接口問題

    python多線程請求帶參數(shù)的多個接口問題

    這篇文章主要介紹了python多線程請求帶參數(shù)的多個接口問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • 詳解Python中的__new__、__init__、__call__三個特殊方法

    詳解Python中的__new__、__init__、__call__三個特殊方法

    用雙下劃線包圍的特殊方法在Python中又被成為魔術(shù)方法,類似于C++等語言中的構(gòu)造函數(shù),這里我們就來詳解Python中的__new__、__init__、__call__三個特殊方法:
    2016-06-06
  • PyCharm2020.1.2社區(qū)版安裝,配置及使用教程詳解(Windows)

    PyCharm2020.1.2社區(qū)版安裝,配置及使用教程詳解(Windows)

    這篇文章主要介紹了PyCharm2020.1.2社區(qū)版安裝,配置及使用教程(Windows),本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-08-08
  • Python實現(xiàn)的爬取小說爬蟲功能示例

    Python實現(xiàn)的爬取小說爬蟲功能示例

    這篇文章主要介紹了Python實現(xiàn)的爬取小說爬蟲功能,結(jié)合實例形式分析了Python爬取頂點小說站上的小說爬蟲功能相關(guān)實現(xiàn)技巧,需要的朋友可以參考下
    2019-03-03
  • 基于python實現(xiàn)把json數(shù)據(jù)轉(zhuǎn)換成Excel表格

    基于python實現(xiàn)把json數(shù)據(jù)轉(zhuǎn)換成Excel表格

    這篇文章主要介紹了基于python實現(xiàn)把json數(shù)據(jù)轉(zhuǎn)換成Excel表格,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-05-05
  • pycharm三個有引號不能自動生成函數(shù)注釋的問題

    pycharm三個有引號不能自動生成函數(shù)注釋的問題

    這篇文章主要介紹了解決pycharm三個有引號不能自動生成函數(shù)注釋的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • Python爬取科目四考試題庫的方法實現(xiàn)

    Python爬取科目四考試題庫的方法實現(xiàn)

    這篇文章主要介紹了Python爬取科目四考試題庫的方法實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03

最新評論

阿勒泰市| 丰顺县| 高要市| 监利县| 黄大仙区| 确山县| 雷山县| 雅安市| 花莲县| 南华县| 安塞县| 姚安县| 四川省| 无为县| 玉田县| 和静县| 鄢陵县| 新巴尔虎左旗| 顺昌县| 兴国县| 沽源县| 达州市| 华容县| 中西区| 东莞市| 开原市| 惠水县| 丹阳市| 惠州市| 高平市| 铅山县| 洛隆县| 吴桥县| 怀远县| 观塘区| 新民市| 丽水市| 罗平县| 玉屏| 冀州市| 安溪县|