不可用的类型:' list'尝试使用Django中的post_save动态添加m2m关系时出错

时间:2016-08-23 10:54:19

标签: django django-models many-to-many django-orm

我的内容模型与Tag模型有多对多的关系。当我保存Content对象时,我想动态添加关系。我这样做的方式如下。

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'])

基本上,当保存Content对象时,接收器用于调用post_save方法,后者又调用tag_content方法来添加m2m关系。但是,我收到了这个错误:

TypeError
unhashable type: 'list'

它专门引用.add()函数。知道我为什么会收到这个错误吗?任何帮助表示赞赏。另外,请注意我在数据库中有ids = 1,2和3的Tag对象。

修改

好吧,我把tag_content改成了这样的东西:

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

这是因为add()方法接受对象实例,而不是id。但是,它仍然无法工作:/我没有错误,但关系根本没有建立。

这是特别奇怪的,因为print tag命令可以工作并打印出标签。换句话说,正在调用该函数。有什么帮助吗?顺便说一句,我正在运行Django 1.9.8。

2 个答案:

答案 0 :(得分:4)

您无法将列表传递给add(),这就是您收到错误的原因。您需要一次添加一个项目或将列表扩展为一系列参数,例如:

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

这仍然会导致错误,因为您无法将ID传递给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)

答案 1 :(得分:3)

根据add docs,您需要将实际模型作为参数传递。

如果你真的想要一个模型列表,你需要解压缩它,但你也可以在这种情况下直接将objs作为参数传递。