Django的:审计跟踪和懒惰的关系
问题描述:
我一直在试图修改AuditTrail代码,因此它不会复制ForeignKey
领域,而是拷贝相关领域(即我不想对我的数据库表的外键审计模型)。Django的:审计跟踪和懒惰的关系
我写了一个copy_field
功能,看起来像这样:
def copy_field(field):
while(isinstance(field, models.OneToOneField, models.ForeignKey)):
field = field.rel.get_related_field()
if isinstance(field, models.AutoField):
f = models.IntegerField()
else:
f = copy(field)
#...snip some adjusting of fs attributes...
return f
当制备具有AuditTrail
属性模型(通过class_prepared
信号)此代码运行。
然而,这个过程中遇到问题时,ForeignKey
是有关在尚未准备尚未模型的领域中 - get_related_field()
调用将失败,因为field.rel.to
是包含了相关模型的名称的字符串,而不是模型实例。
我不知道该如何解决此问题。在开始复制字段之前,我是否必须确定模型具有哪些依赖关系,并等待它们全部做好准备?任何关于最佳方式的想法?
答
我最终什么事做的是列出所有依赖的模型有(通过确定canoncial应用程序/名称对;复制从django.db.models.fields.related
一些代码,以确定此)和修改我的class_prepared
信号处理程序以侦听所有车型,而不是只是我的目标模型。
当处理程序在我的依赖项列表中识别出模型时,它会从列表中删除它并检查列表是否为空;如果是,则可以创建审计模型。重要的注意事项是在创建模型之前断开class_prepared
处理程序,否则我遇到了无限递归(或者我可能更具体地处理了处理程序)。
dependencies = []
for field in cls._meta.local_fields:
while isinstance(field, (models.OneToOneField, models.ForeignKey)):
if isinstance(field.rel.to,basestring):
dependencies.append(get_canonical(cls,field.rel.to))
break
else:
field = field.rel.get_related_field()
def _contribute(sender, **kwargs):
key = (sender._meta.app_label, sender.__name__)
if key in dependencies:
dependencies.remove(key)
if not dependencies:
models.signals.class_prepared.disconnect(_contribute)
model = create_audit_model(cls)
models.signals.class_prepared.connect(_contribute, weak=False)