覆盖保存方法以在多对多字段

时间:2017-01-04 18:54:01

标签: django django-models

我有这个模型来保存用户的帖子:

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

def add_tags(obj_id, body):
    object = Post.objects.get(id=obj_id)
    tag_list = [Tag.objects.create(name=word) for word in body.split()]
    for tag in tag_list:
        object.tags.add(tag)

class Post(models.Model):
    user = models.ForeignKey(User)
    body = models.TextField()
    tags = models.ManyToManyField(Tag, blank=True)
    pub_date = models.DateTimeField(default=timezone.now)
    activity = GenericRelation(Activity, related_query_name="posts")

    def save(self, *args, **kwargs):
        super(Post, self).save(*args, **kwargs)
        if self.body:
            body = self.body
            obj_id = self.id
            add_tags(obj_id, body)

因此,每当用户发布某些内容时,我想检查是否在主体内部使用了任何哈希标记。如果有标签,则获取列表中的标签。

但是当我发布时,会创建标记对象,但它们不会为Post.tags字段添加。

post.body example = 检查来自http://somesitedotcom/page#idtop #hell的#是啊!

我在这里做错了什么?

2 个答案:

答案 0 :(得分:2)

这是人们常犯的错误。为了更新模型对象的m2m关系,需要首先将对象保存在数据库中。 Django m2m实际上是使用一个中间表来存储关系,所以如果不保存两端,就无法形成关系。

我不会依赖覆盖save()方法来实现这一点,而是在views方法中单独处理这个过程,因为save()可能在任何情况下发生,但你可能并不总是这样过程发生。为了正确起见,您应该在super(Post, self).save(*args, **kwargs)方法中致电save后再进行此操作。

修改

听起来你的代码也有错误。 tag_list是字符串列表,但您的代码self.tags.add(*tag_list)将其视为Tag个对象。您需要创建Tag个对象,然后使用add链接该关系。

答案 1 :(得分:0)

在保存之前,您无法将Posttag相关联:

def save(self, *args, **kwargs):
    super(Post, self).save(*args, **kwargs)
    if self.body:
        tag_list = [word for word in self.body.split() if word.startswith("#")]
        self.body = tag_list
        self.tags.add(*tag_list)