2012-01-14 95 views
2

我发现这个代码http://djangosnippets.org/snippets/2283/,但我认为它不适用于许多tomanyfields使用另一个模型(关键字通过) - 我试图合并时得到一个AttributeError。在Django 1.3中合并重复的最佳方式是什么?

你知道有什么方法可以解决这个或另一种合并对象的方法吗?

编辑:详情

我有3个模型:A,B,C

A具有多对多字段 “m2mfield” 通过B.

指向C当我运行从代码Django的片段时,出现异常

'ManyRelatedManager' object has no attribute 'remove' 

我觉得这事做在Django源(django.db.models.fields.related.py线499)评论它说:

# If the ManyToMany relation has an intermediary model, 
# the add and remove methods do not exist. 

我认为我得到的代码片段并没有在有和没有中间模型的ManyToMany关系之间有任何区别。这就是为什么我正在寻找一些方法来修复该代码或其他方式来实现我想要的(合并)。

+1

你能更详细地描述你的问题,也许提供了模型样参与? – 2012-01-14 03:00:09

+0

显示你做了什么,并显示出了什么问题(回溯)。这是沟通问题的好的第一步。 – 2012-01-14 03:32:18

+0

我用一些细节更新了我的问题。我认为我确定了什么是错的,但我不知道如何使它工作... – Weier 2012-01-14 10:19:19

回答

2

我最终修改了代码以处理通过模型创建的ManyToMany字段的情况。 这里是要被修改:

# Migrate all many to many references from alias object to primary object. 
for related_many_object in alias_object._meta.get_all_related_many_to_many_objects(): 
    alias_varname = related_many_object.get_accessor_name() 
    obj_varname = related_many_object.field.name 

    # Treatment depends on if the many_to_many field is created through another model 
    if getattr(alias_object, alias_varname).through._meta.auto_created: 
     if alias_varname is not None: 
      # standard case 
      related_many_objects = getattr(alias_object, alias_varname).all() 
     else: 
      # special case, symmetrical relation, no reverse accessor 
      related_many_objects = getattr(alias_object, obj_varname).all() 
     for obj in related_many_objects.all(): 
      getattr(obj, obj_varname).remove(alias_object) 
      getattr(obj, obj_varname).add(primary_object) 
    else: 
     related_many_objects = getattr(alias_object, alias_varname).all() 

     through_model = getattr(alias_object, alias_varname).through 
     through_field_name = None 
     for f in through_model._meta.fields: 
      if isinstance(f, ForeignKey): 
       if f.rel.to == primary_class : 
       # f is the field in our 'through' model which points to an instance of primary_class 
        through_field_name = f.name 

     for obj in related_many_objects.all(): 
      kwargs = { 
       through_field_name: obj, 
      } 
      for through_obj in through_model.objects.filter(**kwargs): 
       setattr(through_obj, through_field_name, primary_object) 
       through_obj.save() 
0

您有错误意味着您尝试填充的manytomany字段是使用直通模式进行管理的。

有一个在片段您粘贴应该通过模型了解的合并工作代码,它开始L55:

# Migrate all many to many references from alias object to primary object. 
    for related_many_object in alias_object._meta.get_all_related_many_to_many_objects(): 
     alias_varname = related_many_object.get_accessor_name() 
     obj_varname = related_many_object.field.name 

     if alias_varname is not None: 
      # standard case 
      related_many_objects = getattr(alias_object, alias_varname).all() 
     else: 
      # special case, symmetrical relation, no reverse accessor 
      related_many_objects = getattr(alias_object, obj_varname).all() 
     for obj in related_many_objects.all(): 
      getattr(obj, obj_varname).remove(alias_object) 
      getattr(obj, obj_varname).add(primary_object) # this can't work 

你必须提供merge_model_objects功能的字典,其中merge_model_objects会能够选择一个函数来构建通过类。很可能这段代码应该替换上面代码片段的最后一行。

但是你也应该注意一点,A1,A2和C1,C2可能相等,而B1,B2不相等,当前代码也不能处理。

+0

事实上,我修改了代码,以处理通过模型的情况: – Weier 2012-01-19 15:18:02

+0

@Thomas关闭了问题,或给你的自我解决方案,thansk。 – amirouche 2012-01-19 15:54:19

相关问题