2014-01-03 6 views
0

У меня есть модель книги, в которой есть полевое имя для многих. Если я объединю две книги, я хочу убедиться, что объединенная книга имеет только уникальных авторов, а не двойников. Я думал, что лучший способ достижения этой цели была переопределить метод сохранения(), и до сих пор я пришел к этой модели:Django: обновление ManyToManyField при сохранении

class Book(models.Model): 
    authors = models.ManyToManyField() 

    def save(self): 
     authors_new = [] 
     authors = self.authors.all() 
     for author in authors: 
      if author not in authors_new: 
       authors_new.append(author) 
     self.authors = authors_new   #This won't work 
     super(Book, self).save() 

Предпоследняя линия, очевидно, не работает, но я просто не могу похоже, правильно синтаксис. Я думаю, что то, что я хочу достичь, довольно очевидно. Кто-нибудь знает, что такое правильный синтаксис?

Edit 1:

Для объяснения слияния: Я должен сказать, что я не полностью понять код (написанный кем-то другим - слияние занимает места в течение нескольких функций), так показывая, что здесь выиграл» Я помогу мне. Что он делает, так это: скажем, есть две книги в базе данных, которые, очевидно, одинаковы. Первая книга имеет

title= “Harry Potter and the Philosopher’s Stone” 
author=“JK Rowling” 
year=1999 

и другая книга имеет

title=“Harry Potter (book 1)” 
author=“JK Rowling” 
pages=320 

При объединении вам нужно выбрать, какая книга является основной книгой. Если бы я выбрал первый, чтобы быть первичным, слияние должно закончиться как

title=“Harry Potter and the Philosopher’s Stone” 
author=“JK Rowling” 
year=1999 
pages=320 

Проблема заключается в том, что слияние заканчивается автор = «Джоан Роулинг» дважды я думал, что я мог бы дублирующие в функции сохранения.

Edit 2:

Слияние занимает места в этой функции, что я не писал:

def merge_model_objects(primary_object, *alias_objects): 
    # Use this function to merge model objects and migrate all of 
    # the related fields from the alias objects to the primary object. 

    for alias_object in alias_objects: 
     meta = alias_object._meta 
     for related_object in meta.get_all_related_objects(): 
      alias_varname = related_object.get_accessor_name() 
      obj_varname = related_object.field.name 
      related_objects = getattr(alias_object, alias_varname) 
      for obj in related_objects.all(): 
       if getattr(obj, 'do_not_merge', False): 
        continue 
       setattr(obj, obj_varname, primary_object) 
       obj.save() 

     related_objects = meta.get_all_related_many_to_many_objects() 
     for related_many_object in related_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) 

     alias_object.delete() 
    primary_object.save() 
    return primary_object 

Это довольно общая функция и может объединить более двух объектов, но если я объединю книгу 1 (= primary_object) и книгу 2 (= alias_object), она сохранит ее как книгу с автором = «JK Rowling» дважды.

+0

Извините, я не думаю, что это очевидно. Что вы подразумеваете под «слиянием» двух книг? Почему у вас есть дубликаты? –

+0

В действительности могут быть дубликаты, разные люди добавляют книги в базу данных. Если книги объединены, я хочу убедиться, что каждый автор добавляется только один раз в книгу. –

+1

Я думаю, что django ManyToManyField уже обходит уникальные отношения. Ты это пробовал? –

ответ

Смежные вопросы