2012-01-14 96 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

相關問題