У меня есть модель книги, в которой есть полевое имя для многих. Если я объединю две книги, я хочу убедиться, что объединенная книга имеет только уникальных авторов, а не двойников. Я думал, что лучший способ достижения этой цели была переопределить метод сохранения(), и до сих пор я пришел к этой модели: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» дважды.
Извините, я не думаю, что это очевидно. Что вы подразумеваете под «слиянием» двух книг? Почему у вас есть дубликаты? –
В действительности могут быть дубликаты, разные люди добавляют книги в базу данных. Если книги объединены, я хочу убедиться, что каждый автор добавляется только один раз в книгу. –
Я думаю, что django ManyToManyField уже обходит уникальные отношения. Ты это пробовал? –