python - Django - 如何可视化信号并保存覆盖?

标签 python django architecture software-design

随着项目的增长,依赖项和事件链也在增长,尤其是在被覆盖的 save() 方法和 post_savepre_save 信号中。

例子:

一个被覆盖的 A.save 创建两个与 A 相关的对象 - BC。当 C 被保存时,会调用 post_save 信号来执行其他操作,等等...

如何使这些事件下巴更清晰?有没有办法可视化(自动生成)这样的链/流?我不是在寻找 ERD 也不是 Class 图。我需要确保在一个地方做一件事不会影响项目另一边的某事,所以简单的可视化是最好的。

编辑

明确地说,我知道检查动态生成的信号几乎是不可能的。我只想检查所有(不是动态生成的)post_savepre_save 和覆盖的 save 方法并将它们可视化,这样我就可以立即看到是什么当我 save 某些东西时发生和在哪里。

最佳答案

这不是完整的解决方案,但我希望它可以成为一个好的起点。考虑这段代码:

from django.db import models
from django.db.models.signals import pre_save
from django.dispatch import receiver

class A(models.Model):
    def save(self, *args, **kwargs):
        if not self.pk:
            C.objects.create()

class B(models.Model):
    pass

class C(models.Model):
    b = models.ForeignKey(B, on_delete=models.CASCADE, blank=True)

@receiver(pre_save, sender=C)
def pre_save_c(sender, instance, **kwargs):
    if not instance.pk:
        b = B.objects.create()
        instance.b = b

我们可以使用 inspect 获取应用名称列表的依赖项, django get_models() , 和 signals以这种方式:

import inspect
import re
from collections import defaultdict

from django.apps import apps
from django.db.models import signals

RECEIVER_MODELS = re.compile('sender=(\w+)\W')
SAVE_MODELS = re.compile('(\w+).objects.')

project_signals = defaultdict(list)
for signal in vars(signals).values():
    if not isinstance(signal, signals.ModelSignal):
        continue
    for _, receiver in signal.receivers:
        rcode = inspect.getsource(receiver())
        rmodel = RECEIVER_MODELS.findall(rcode)
        if not rmodel:
            continue
        auto_by_signals = [
            '{} auto create -> {}'.format(rmodel[0], cmodel)
            for cmodel in SAVE_MODELS.findall(rcode)
        ]
        project_signals[rmodel[0]].extend(auto_by_signals)

for model in apps.get_models():
    is_self_save = 'save' in model().__class__.__dict__.keys()
    if is_self_save:
        scode = inspect.getsource(model.save)
        model_name = model.__name__
        for cmodel in SAVE_MODELS.findall(scode):
            print('{} auto create -> {}'.format(model_name, cmodel))
            for smodels in project_signals.get(cmodel, []):
                print(smodels)

这给出了:

A auto create -> C
C auto create -> B

更新:将方法更改为覆盖 save通过实例类字典。

is_self_save = 'save' in model().__class__.__dict__.keys()

关于python - Django - 如何可视化信号并保存覆盖?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55578230/

相关文章:

python - 在极限矩阵上执行二重积分

python - 如何 .pop() 二维列表上的特定项目?

python - Pandas 聚合: How to generate multiple new columns from one column and vise versa

python - keras sparse_categorical_crossentropy 损失函数输出形状不匹配

python - 如何在 Django Admin 的 "Change List"页面显示上传的图片?

python - 上传SimpleUploadedFile时BytesIO流图像为空白

python - 覆盖率测试 django 注销

swift - 在服务器上创建模型的正确方法

Android应用程序架构 - 如何避免 fragment 服务代码重复

c# - 自组织应用