欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

1、問(wèn)題溯源

重點(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的里面有部分東西無(wú)法序列化,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ì)象)。

接下來(lái):調(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)置的沒(méi)有實(shí)現(xiàn)序列化,所以需要自己在某個(gè)步驟接入到這個(gè)序列化的過(guò)程。

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ò)說(shuō)這個(gè):

Object of type AccessOrm is not JSON serializable

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

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

2、flask序列化

flask代碼里面寫(xiě)了:

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中寫(xiě)入

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 都沒(méi)成功,這里簡(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?munch包?/Munch()?的用法詳解

    Python?munch包?/Munch()?的用法詳解

    這篇文章主要介紹了Python?munch包?/Munch()?的用法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-09-09
  • Python統(tǒng)計(jì)序列和文件中元素的頻度

    Python統(tǒng)計(jì)序列和文件中元素的頻度

    這篇文章主要介紹了Python統(tǒng)計(jì)序列和文件中元素的頻度,文章基于python的相關(guān)資料展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值需要的小伙伴可以參考一下
    2022-04-04
  • 基于Python繪制子圖及子圖刻度的變換等的問(wèn)題

    基于Python繪制子圖及子圖刻度的變換等的問(wèn)題

    這篇文章主要介紹了基于Python繪制子圖及子圖刻度的變換等的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-05-05
  • python中jsonpath的使用小結(jié)

    python中jsonpath的使用小結(jié)

    JsonPath是一種信息抽取類庫(kù),是從JSON文檔中抽取指定信息的工具,提供多種語(yǔ)言實(shí)現(xiàn)版本,本文主要介紹了python中jsonpath的使用小結(jié),具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-03-03
  • 淺析Python字符串中的r和u的區(qū)別

    淺析Python字符串中的r和u的區(qū)別

    在Python中,字符串前面我們經(jīng)??吹綍?huì)加一些前綴,例如u、r、b、f。這篇文章將帶大家簡(jiǎn)單了解一下字符串前加r(R)或u/(U)的前綴的區(qū)別,快來(lái)跟隨小編一起學(xué)習(xí)吧
    2021-12-12
  • python實(shí)現(xiàn)的登錄與提交表單數(shù)據(jù)功能示例

    python實(shí)現(xiàn)的登錄與提交表單數(shù)據(jù)功能示例

    這篇文章主要介紹了python實(shí)現(xiàn)的登錄與提交表單數(shù)據(jù)功能,結(jié)合實(shí)例形式分析了Python表單登錄相關(guān)的請(qǐng)求與響應(yīng)操作實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2019-09-09
  • Python+OpenGL制作一個(gè)元宵花燈

    Python+OpenGL制作一個(gè)元宵花燈

    又是一年元宵節(jié)!如果昨天情人節(jié)的紅包發(fā)得手軟又心疼,不妨利用Python OpenGL做一盞花燈送給女朋友,也許比紅包更能討她歡心呢
    2022-02-02
  • python案例中Flask全局配置示例詳解

    python案例中Flask全局配置示例詳解

    這篇文章主要為大家介紹了python案例中Flask全局配置示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • Windows中安裝使用Virtualenv來(lái)創(chuàng)建獨(dú)立Python環(huán)境

    Windows中安裝使用Virtualenv來(lái)創(chuàng)建獨(dú)立Python環(huán)境

    有時(shí)我們的程序中需要調(diào)用不同版本的Python包和模塊,那么借助Virtualenv的虛擬環(huán)境就可以幫助我們隔離使用,接下來(lái)我們就來(lái)看一下在Windows中安裝使用Virtualenv來(lái)創(chuàng)建獨(dú)立Python環(huán)境的方法
    2016-05-05
  • python復(fù)制與引用用法分析

    python復(fù)制與引用用法分析

    這篇文章主要介紹了python復(fù)制與引用,實(shí)例分析了python中復(fù)制與引用的具體使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-04-04

最新評(píng)論