2016-08-23 2 views
0

Мое содержание модели имеет отношение «многие ко многим» к модели тегов. Когда я сохраняю объект Content, я хочу динамически добавлять отношения. Я делаю это следующим образом.Unshashable type: ошибка «list» при попытке добавить связи m2m динамически с использованием post_save в Django

def tag_content(obj): 
    obj.tags.add([1,2,3]) 
    obj.is_tagged = True 
    obj.save() 
    return obj 

class Tag(models.Model): 
    name = models.CharField(max_length=255) 

class Content(models.Model): 
    title = models.CharField(max_length=255) 
    is_tagged = models.BooleanField(default=False) 
    tags = models.ManyToManyField(Tag, blank=True) 

    def save(self, *args, **kwargs): 
     super(Content, self).save(*args, **kwargs) 

@receiver(post_save, sender = Content) 
def update_m2m_relationships_on_save(sender, **kwargs): 
    if not kwargs['instance'].is_tagged: 
     tag_content(kwargs['instance']) 

В основном, когда объект контента сохраняется, приемник используется для вызова метода post_save, который в свою очередь вызывает метод tag_content добавить М2М отношения. Однако, я получаю эту ошибку:

TypeError 
unhashable type: 'list' 

Он конкретно ссылается на функцию .add(). Любая идея, почему я получаю эту ошибку? Любая помощь приветствуется. Кроме того, обратите внимание, что у меня есть объекты Tag с идентификаторами ids = 1, 2 и 3 в базе данных.

EDIT

Хорошо, я изменил свое tag_content на что-то вроде этого:

def tag_content(obj): 
    for tag in Tag.objects.all(): 
     print tag 
     obj.tags.add(tag) 

Это происходит потому, что метод Add() принимает экземпляры объектов, а не идентификаторами. Однако он все еще не работает:/Я не получаю ошибки, но отношения просто не установлены.

Это особенно странно, поскольку команда print tag работает и распечатывает теги. Другими словами, функция вызывается. Любая помощь, пожалуйста? Кстати, я запускаю Django 1.9.8.

+0

какая версия Django вы используете? –

+0

re: ваше редактирование, вы выполняете 'obj.save()'? вы делали в предыдущей версии –

+0

Да, я выполняю метод сохранения. –

ответ

1

В соответствии с add docs вам нужны фактические модели, которые будут переданы как args.

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

+0

Я обновил вопрос. Вы можете проверить это. –

2

Вы не можете передать список add(), поэтому вы получаете ошибку. Вы либо должны добавить один пункт в то время, или расширить список в ряд аргументов, например:

obj.tags.add(*[1,2,3]) # The * expands the list into the function arguments 

Это будет по-прежнему вызывает ошибку, потому что вы не можете передавать идентификаторы add() - вы должны пройти Tag объекты Это. Так что-то вроде этого будет работать:

# Get a list of Tag objects 
tags_to_add = [Tag.objects.get(id=j) for j in [1, 2, 3]] 
# Now pass this to the add() function: 
obj.tags.add(*tags_to_add) 
+0

Я обновил вопрос. Вы можете проверить это. –

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