有关使用Django Orm的通用关系的这个错误的任何线索?

时间:2010-09-10 10:37:27

标签: django orm field generic-relations

这很有趣: - )

在EAV上工作时,我们在运行时在模型中注入一个通用关系处理程序。

model_cls是任何类,EavValue类具有指向它的通用关系。它从EavValuesmodel_cls工作正常,但另一方面,我们需要注入一个访问器来缓解事情:

generic_relation = generic.GenericRelation(EavValue,
                                               object_id_field='entity_id',
                                               content_type_field='entity_ct',
                                               related_name=model_cls.__name__)
generic_relation.contribute_to_class(model_cls, 'eav_values')

同样,我们在运行时这样做,因为我们希望它能够与不可触摸的第三方库一起使用。

使用Patient类作为model_cls进行单元测试时,我们收到以下错误:

eav_ng.patient: Accessor for m2m field 'eav_values' clashes with related m2m field 'EavValue.Patient'. Add a related_name argument to the definition for 'eav_values'.

现在,我们认为简单的解决方法是在contribute_to_class中更改related_nameGenericRelation的第二个参数,但事实并非如此!我们得到完全相同的错误,只有不同的名称。

第二个奇怪的是,使用Sqlite而不是MySql运行相同的单元测试:全部通过。

更重要的是,无论顺序还是测试,我们总是在第二次测试中得到这个错误。由于此过程以register方式发生,我们在设置时调用registerunregister并拆除,因此我猜测我们的unregister方法不完善。

最后一个奇怪的事实:我们在运行unittest时遇到错误,但是我们无法手动重现它。最糟糕的是,在我的同事计算机上,当我们使用相同版本的Python,Django,Ubuntu和MySQL时,它不会出错。

我们解决了很多困难问题,但我们仍然坚持这一点,所以任何线索都会受到赞赏。

更新

这场伟大比赛的新线索:

在第245行(django 1.2.1)的django.core.management.validation中从此代码段引发错误:

for r in rel_opts.get_all_related_many_to_many_objects():
    if r.field is not f:
        if r.get_accessor_name() == rel_name:
            e.add(opts, "Accessor for m2m field '%s' clashes with related m2m field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.get_accessor_name(), f.name))
        if r.get_accessor_name() == rel_query_name:
            e.add(opts, "Reverse query name for m2m field '%s' clashes with related m2m field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.get_accessor_name(), f.name))

对我们来说r.get_accessor_name() == rel_name是真的,因为两者都是“患者”。

更新2:

当我们添加register模型的应用时。任何型号,问题都不会再出现了。 unregister理论......

我们处于两个对称错误(关系的两侧)。删除related_name会删除其中一个错误0_o

1 个答案:

答案 0 :(得分:1)

找到解决方案

在模型类_meta.local_many_to_many属性中添加一个通用关系,这是一个列表。 Django检查,但没有办法摆脱它。修复是:

    # remove remaining reference to the generic relation
    for field in model_cls._meta.local_many_to_many:
        if field.name == 'eav_value': # your related name
            model_cls._meta.local_many_to_many.remove(field)
            break