声明性模型生命周期挂钩。
项目描述
Django 生命周期钩子
这个项目提供了一个@hook装饰器以及一个基本模型和 mixin 来为你的 Django 模型添加生命周期钩子。Django 提供生命周期钩子的内置方法是Signals。但是,我的团队经常发现 Signals 引入了不必要的间接性,并且与 Django 的“胖模型”方法不一致。
Django Lifecycle Hooks支持 Python 3.7、3.8 和 3.9,Django 2.0.x、2.1.x、2.2.x、3.0.x、3.1.x 和 3.2.x。
简而言之,您可以像这样编写模型代码:
from django_lifecycle import LifecycleModel, hook, BEFORE_UPDATE, AFTER_UPDATE
class Article(LifecycleModel):
contents = models.TextField()
updated_at = models.DateTimeField(null=True)
status = models.ChoiceField(choices=['draft', 'published'])
editor = models.ForeignKey(AuthUser)
@hook(BEFORE_UPDATE, when='contents', has_changed=True)
def on_content_change(self):
self.updated_at = timezone.now()
@hook(AFTER_UPDATE, when="status", was="draft", is_now="published")
def on_publish(self):
send_email(self.editor.email, "An article has published!")
而不是覆盖save和__init__笨拙的方式会损害可读性:
# same class and field declarations as above ...
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._orig_contents = self.contents
self._orig_status = self.status
def save(self, *args, **kwargs):
if self.pk is not None and self.contents != self._orig_contents:
self.updated_at = timezone.now()
super().save(*args, **kwargs)
if self.status != self._orig_status:
send_email(self.editor.email, "An article has published!")
文档:https://rsinger86.github.io/django-lifecycle
源代码:https://github.com/rsinger86/django-lifecycle
变更日志
1.0.0(2022 年 5 月)
- 放弃对 Python 3.6 的支持
- 添加
priorityhook kwarg 来控制钩子方法触发的顺序。谢谢@EnriqueSoria! - 内部清理/重构。谢谢@EnriqueSoria!
0.9.6(2022 年 2 月)
- 将缺失添加
packaging到install_requires. 谢谢@mikedep333!
0.9.5(2022 年 2 月)
- 通过检查传递给保存的参数,使
has_changed,changes_to条件取决于相关字段是否包含在 SQL 更新/插入语句中。update_fields
0.9.4(2022 年 2 月)
- 添加可选的@hook
on_commit参数以在提交数据库事务时执行挂钩。谢谢@amcclosky!
0.9.3(2021 年 10 月)
- 更正包信息以注意支持 Django 3.2。
0.9.2(2021 年 10 月)
- 在事务中运行挂钩方法,就像信号一样。谢谢@amirmotlagh!
0.9.1(2021 年 3 月)
- 使钩子与 OneToOneFields 一起工作。谢谢@bahmdev!
0.9.0(2021 年 2 月)
- 防止两次以相同状态调用挂钩方法。谢谢@garyd203!
0.8.1(2021 年 1 月)
delete()为方法覆盖添加了缺少的返回。谢谢@oaosman84!
0.8.0(2020 年 10 月)
- 显着的性能改进。谢谢@dralley!
0.7.7(2020 年 8 月)
- 修复了
GenericForeignKey. 谢谢@bmbouter!
0.7.6(2020 年 5 月)
- 更新使用常量作为钩子名称;更新文档以指示 Python 3.8/Django 3.x 支持。谢谢@thejoeejoee!
0.7.5(2020 年 4 月)
- 为钩子名称添加静态类型变量;谢谢@Faisal-Manzer!
- 修复了文档中的一些错别字;谢谢@tomdyson 和@bmispelon!
0.7.1(2020 年 1 月)
- 修复了
utils._get_field_names在某些情况下可能导致递归错误的错误。
0.7.0(2019 年 12 月)
- 添加
changes_to条件 - 感谢@samitnuk!还有一些文档中的错字修复。
0.6.1(2019 年 11 月)
- 删除 Python 3.5 兼容性的变量类型注释。
0.6.0(2019 年 10 月)
- 添加
when_any钩子参数以观察多个字段的状态变化
0.5.0(2019 年 9 月)
- 添加
was_not条件 - 允许观察对 FK 模型字段值的更改,而不仅仅是 FK 引用
0.4.2(2019 年 7 月)
- 修复了破坏安装的缺失 README.md 问题。
0.4.1(2019 年 6 月)
- 修复urlman -兼容性。
0.4.0(2019 年 5 月)
- 修复
initial_value(field_name)行为 - 即使没有变化也应该返回值。谢谢@adamJLev!
0.3.2(2019 年 2 月)
- 修复了阻止钩子触发自定义 PK 的错误。谢谢@atugushev!
0.3.1(2018 年 8 月)
- 修复 m2m 字段错误,其中访问自动生成的反向字段
before_create导致异常 b/c PK 尚不存在。谢谢@garyd203!
0.3.0(2018 年 4 月)
save调用后重置模型的钩子条件比较状态。
0.2.4(2018 年 4 月)
- 修复了对
@hook向同一方法添加多个装饰器的支持。
0.2.3(2018 年 4 月)
- 从早期实现中删除残留的混合方法。
0.2.2(2018 年 4 月)
- Save 方法现在接受
skip_hooks一个可选的布尔关键字参数,用于控制是否调用挂钩方法。
0.2.1(2018 年 4 月)
- 修复了通过访问用或
_potentially_hooked_methods装饰的模型实例方法导致不必要的副作用的错误。@cache_property@property
0.2.0(2018 年 4 月)
- 添加了 Django 1.8 支持。谢谢@jtiai!
- 为 Python 3.4、3.5、3.6 和 Django 1.8、1.11 和 2.0 添加了毒物测试。谢谢@jtiai!
测试
/tests测试位于文件夹中的简化 Django 项目中。安装项目需求并./manage.py test运行它们。
执照
请参阅许可证。