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

Flask自定義序列化超詳細(xì)講解

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

1、問題溯源

重點(diǎn)就是一個(gè)Flask.make_response,這里會(huì)做請(qǐng)求的響應(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是一個(gè)字典,但是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,實(shí)際是對(duì)象)。

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

代碼片段: 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,這個(gè)是內(nèi)置的json庫(kù)的default方法。內(nèi)置的沒有實(shí)現(xiàn)序列化,所以需要自己在某個(gè)步驟接入到這個(gè)序列化的過程。

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是實(shí)例對(duì)象,所以他報(bào)錯(cuò)說這個(gè):

Object of type AccessOrm is not JSON serializable

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

解決: 就是通過flask的機(jī)制,綁定一個(gè)序列化類。

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è)置藍(lán)圖的json_encoder,藍(lán)圖的優(yōu)先級(jí)高于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實(shí)例化之后,修改app的JSONEncoder 都沒成功,這里簡(jiǎn)單粗暴一點(diǎn),直接修改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

這時(shí)候,我的orm類需要一個(gè)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自定義序列化超詳細(xì)講解的文章就介紹到這了,更多相關(guān)Flask序列化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

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

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

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

    Python安裝jieba庫(kù)詳細(xì)教程

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

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

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

    python多線程請(qǐng)求帶參數(shù)的多個(gè)接口問題

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

    詳解Python中的__new__、__init__、__call__三個(gè)特殊方法

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

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

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

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

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

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

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

    pycharm三個(gè)有引號(hào)不能自動(dòng)生成函數(shù)注釋的問題

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

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

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

最新評(píng)論

屏东县| 库伦旗| 大埔区| 电白县| 贺兰县| 开远市| 毕节市| 保康县| 涿鹿县| 云和县| SHOW| 钟祥市| 铁岭县| 兴安县| 郁南县| 乐都县| 舟山市| 柳州市| 凯里市| 伊金霍洛旗| 赞皇县| 新乐市| 忻州市| 天峨县| 合肥市| 泊头市| 浦城县| 岳西县| 睢宁县| 山阴县| 北票市| 永昌县| 色达县| 洪泽县| 德阳市| 大姚县| 商城县| 微山县| 淅川县| 莱阳市| 紫金县|