代码之家  ›  专栏  ›  技术社区  ›  Bite code

关于这个使用Django Orm的泛型关系错误有什么线索吗?

  •  4
  • Bite code  · 技术社区  · 14 年前

    这是一个有趣的:-)

    在EAV上,我们在运行时将通用关系处理程序注入到模型中。

    model_cls 是任何一个班级 EavValue 类具有指向它的泛型关系。从一开始就很好用 EavValues ,但另一方面,我们需要注入一个访问器来简化:

    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 分类为 型号\ 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_name 在里面 GenericRelation ,但事实并非如此!我们得到完全相同的错误,只是名称不同。

    第二件奇怪的事,用Sqlite而不是MySql运行相同的unittests:all-pass。

    register 我们称之为 登记 unregister 注销

    最后一个奇怪的事实:我们在运行unittest时得到了错误,但是我们无法手动复制它。最糟糕的是,在我同事的电脑上,当我们使用同一版本的Python、Django、Ubuntu和MySQL时,它没有出现错误。

    这个伟大游戏的新线索:

    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:

    当我们添加一个 登记 模特儿。任何型号,问题都不会再出现了。就这么多了 注销 理论。。。

    我们注意到两个对称的错误(关系的两边)。正在删除 相关名称 抑制其中一个错误0\u o

    1 回复  |  直到 14 年前
        1
  •  1
  •   Bite code    14 年前

    找到了解决办法

    在模型类中放置引用时添加泛型关系 _meta.local_many_to_many

        # 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
    
    推荐文章