2009-08-26 74 views
1

我一直在试图修改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是包含了相关模型的名称的字符串,而不是模型实例。

我不知道该如何解决此问题。在开始复制字段之前,我是否必须确定模型具有哪些依赖关系,并等待它们全部做好准备?任何关于最佳方式的想法?

回答

0

我最终什么事做的是列出所有依赖的模型有(通过确定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)