【Python百日进阶-Web开发-Peewee】Day288 - Peewee 的扩展(七)shortcuts / 信号支持

13.13 快捷模式 Shortcuts

该模块包含帮助函数,用于表达使用 peewee 的 API 会有些冗长或繁琐的事物。还有用于将模型序列化为字典的助手,反之亦然。

model_to_dict
model_to_dict(model[, recurse=True[, backrefs=False[, only=None[, exclude=None[, extra_attrs=None[, fields_from_query=None[, max_depth=None[, manytomany=False]]]]]]]])

参数:

  • recurse ( bool ) – 是否应该递归外键。
  • backrefs ( bool ) – 是否应该递归相关对象的列表。
  • only – 应包含在结果字典中的字段实例列表(或集合)。
  • exclude – 应从结果字典中排除的字段实例列表(或集合)。
  • extra_attrs – 实例上应包含在字典中的属性或方法名称列表。
  • fields_from_query ( Select ) –SelectQuery创建此模型实例的。只有查询明确选择的字段和值才会被序列化。
  • max_depth ( int ) – 递归时的最大深度。
  • manytomany ( bool ) – 处理多对多字段。
    将模型实例(以及可选的任何相关实例)转换为字典。

例子:

>>> user = User.create(username='charlie')
>>> model_to_dict(user)
{'id': 1, 'username': 'charlie'}

>>> model_to_dict(user, backrefs=True)
{'id': 1, 'tweets': [], 'username': 'charlie'}

>>> t1 = Tweet.create(user=user, message='tweet-1')
>>> t2 = Tweet.create(user=user, message='tweet-2')
>>> model_to_dict(user, backrefs=True)
{
  'id': 1,
  'tweets': [
    {'id': 1, 'message': 'tweet-1'},
    {'id': 2, 'message': 'tweet-2'},
  ],
  'username': 'charlie'
}

>>> model_to_dict(t1)
{
  'id': 1,
  'message': 'tweet-1',
  'user': {
    'id': 1,
    'username': 'charlie'
  }
}

>>> model_to_dict(t2, recurse=False)
{'id': 1, 'message': 'tweet-2', 'user': 1}

model_to_dict的实现相当复杂,因为它试图支持各种用途。如果您有特殊用途,我强烈建议您不要尝试将一些疯狂的参数组合硬塞到此函数中。只需编写一个简单的函数来完成您正在尝试做的事情。

dict_to_model
dict_to_model(model_class, data[, ignore_unknown=False])

参数:

  • model_class ( Model ) – 要构造的模型类。
  • data ( dict ) – 数据字典。外键可以作为嵌套字典包含,反向引用可以作为字典列表。
  • ignore_unknown ( bool ) – 是否允许无法识别的(非字段)属性。
    将数据字典转换为模型实例,在适当的地方创建相关实例。

例子:

>>> user_data = {'id': 1, 'username': 'charlie'}
>>> user = dict_to_model(User, user_data)
>>> user
<__main__.User at 0x7fea8fa4d490>

>>> user.username
'charlie'

>>> note_data = {'id': 2, 'text': 'note text', 'user': user_data}
>>> note = dict_to_model(Note, note_data)
>>> note.text
'note text'
>>> note.user.username
'charlie'

>>> user_with_notes = {
...     'id': 1,
...     'username': 'charlie',
...     'notes': [{'id': 1, 'text': 'note-1'}, {'id': 2, 'text': 'note-2'}]}
>>> user = dict_to_model(User, user_with_notes)
>>> user.notes[0].text
'note-1'
>>> user.notes[0].user.username
'charlie'
update_model_from_dict
update_model_from_dict(instance, data[, ignore_unknown=False])

参数:

  • instance ( Model ) – 要更新的模型实例。
  • data ( dict ) – 数据字典。外键可以作为嵌套字典包含,反向引用可以作为字典列表。
  • ignore_unknown ( bool ) – 是否允许无法识别的(非字段)属性。
    使用给定的数据字典更新模型实例。
resolve_multimodel_query
resolve_multimodel_query(query[, key='_model_identifier'])

参数:

  • query- 复合选择查询。
  • key ( str ) – 用于存储模型标识符的键
    返回:
    一个可迭代游标,它为复合选择查询中选择的每一行生成正确的模型实例。

用于将复合选择查询中返回的行解析为正确模型实例类型的帮助程序。例如,如果您有两个不同表的并集,则此帮助程序将在迭代查询结果时将每一行解析为正确的模型。

class ThreadSafeDatabaseMetadata
class ThreadSafeDatabaseMetadata

Metadata提供对属性的线程安全访问的模型实现database,允许应用程序在运行时在多线程应用程序中安全地交换数据库。

用法:

from playhouse.shortcuts import ThreadSafeDatabaseMetadata

# Our multi-threaded application will sometimes swap out the primary
# for the read-replica at run-time.
primary = PostgresqlDatabase(...)
read_replica = PostgresqlDatabase(...)

class BaseModel(Model):
    class Meta:
        database = primary
        model_metadata_class = ThreadSafeDatabaseMetadata

13.14 信号支持 Signal support

带有信号钩子的模型(a-la django)在 playhouse.signals. 要使用信号,您需要项目的所有模型都是 的子类playhouse.signals.Model,它会覆盖必要的方法来为各种信号提供支持。

from playhouse.signals import Model, post_save


class MyModel(Model):
    data = IntegerField()

@post_save(sender=MyModel)
def on_save_handler(model_class, instance, created):
    put_data_in_cache(instance.data)

警告
Model.insert()由于我希望是显而易见的原因,当您使用、Model.update()或 Model.delete()方法时,Peewee 信号不起作用。这些方法会生成超出 ORM 范围执行的查询,并且 ORM 不知道在查询执行时哪些模型实例可能会或可能不会受到影响。
信号通过挂钩到更高级别的 peewee API 来工作,例如 Model.save()and Model.delete_instance(),其中受影响的模型实例是提前知道的。

提供以下信号:

  • pre_save:在将对象保存到数据库之前立即调用。提供一个额外的关键字参数created,指示模型是第一次保存还是更新。
  • post_save:在将对象保存到数据库后立即调用。提供一个额外的关键字参数created,指示模型是第一次保存还是更新。
  • pre_delete:在使用时从数据库中删除对象之前立即调用Model.delete_instance() 。
  • post_delete:在使用时从数据库中删除对象后立即调用Model.delete_instance() 。
  • pre_init:第一次实例化模型类时调用

13.14.1 连接处理程序 Connecting handlers

每当发送信号时,它都会调用任何已注册的处理程序。这允许完全独立的代码来响应模型保存和删除等事件。

该类Signal提供了一个connect()方法,该方法接受一个回调函数和“sender”和“name”的两个可选参数。如果指定,“sender”参数应该是单个模型类,并允许您的回调仅接收来自该模型类的信号。如果您希望取消注册信号处理程序,“name”参数用作方便的别名。

示例用法:

from playhouse.signals import *

def post_save_handler(sender, instance, created):
    print('%s was just saved' % instance)

# our handler will only be called when we save instances of SomeModel
post_save.connect(post_save_handler, sender=SomeModel)

所有信号处理程序都接受它们的前两个参数sender和 instance,其中sender是模型类,并且instance是被操作的实际模型。

如果您愿意,还可以使用装饰器连接信号处理程序。这在功能上等同于上面的示例:

@post_save(sender=SomeModel)
def post_save_handler(sender, instance, created):
    print('%s was just saved' % instance)

13.14.2 信号 API

class Signal
class Signal

存储接收者(回调)列表,并在调用“发送”方法时调用它们。

connect(receiver[, sender=None[, name=None]])

参数:

  • receiver ( callable ) – 一个至少需要两个参数的 callable,一个“sender”,它是触发信号的 Model 子类,一个“instance”,它是实际的模型实例。
  • sender ( Model ) – 如果指定,只有这个模型类的实例会触发接收者回调。
  • name ( string ) – 一个简短的别名
    将接收者添加到接收者的内部列表中,每当发送信号时都会调用该列表。
from playhouse.signals import post_save
from project.handlers import cache_buster

post_save.connect(cache_buster, name='project.cache_buster')

disconnect([receiver=None[, name=None]])

参数:

  • receiver ( callable ) – 断开连接的回调
  • name ( string ) – 一个简短的别名
    断开给定的接收器(或具有给定名称别名的接收器),使其不再被调用。必须提供收件人或姓名。
post_save.disconnect(name='project.cache_buster')

send(instance, *args, **kwargs)

参数: 实例– 模型实例
遍历接收器并按照它们连接的顺序调用它们。如果接收者指定了发送者,那么只有当实例是发送者的实例时才会调用它。

  • 12
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

岳涛@心馨电脑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值