2

我正在为网站编写新闻页面,并且有两个具有多对多关系的模型:标签和帖子。现在,我想在每个页面上显示最受欢迎的标签,并且为了避免每次用户访问页面时计算多对多关系链接的数量,我为每个标签存储了一个计数器。我的想法是修改 Post 的“保存”方法以增加该计数器。这是这两个模型的代码:

class Tag(models.Model):
    tag_text = models.CharField(max_length=100, verbose_name='Tag')
    amount = models.IntegerField(blank=True, null=True, default=0)

    def __unicode__(self):
        return self.tag_text

class Post(models.Model):

    IS_DRAFT = (("Y", "Draft post"), ("N", "Finished post"),)

    title = models.CharField(max_length=100)
    slug = models.CharField(max_length=60, unique=True, blank=True)
    text = RichTextField()
    created_on = models.DateTimeField(auto_now_add=True, verbose_name='Created on')
    last_edited_on = models.DateTimeField(auto_now=True, verbose_name='Last edited on', db_index=True)
    draft = models.CharField(choices=IS_DRAFT, max_length=1, verbose_name='Is a post draft')
    tag = models.ManyToManyField(Tag)

    class Meta:
        ordering = ['created_on']

    def save(self, *args, **kwargs):
        if not self.id:
            date = datetime.now()
            tr_title = unicode(unidecode(self.title))
            self.slug = '%i/%i/%i/%s' % (
                date.year, date.month, date.day, slugify(tr_title)
            )
        super(Post, self).save(*args, **kwargs)
        print 'count', self.tag.count()
        for t in self.tag.all():
            print 'tag amount', t.amount
            t.amount += 1
            t.save()

    def __unicode__(self):
        return self.title

我在 save 方法中添加了打印以进行测试,因为出于某种原因,该行

print 'count', self.tag.count()

输出 0(好像没有给这个模型实例分配标签)。但是,在保存方法期间打印出任何其他字段都可以正常工作。例如:

print 'title', self.title

输出标题,因此访问模型字段不是问题。对此我能做些什么吗?还是我必须借助信号来做我想做的事情?

4

1 回答 1

1

在保存模型之前,不能将 ManyToManyField 项添加到模型中。

您的代码没有显示您从哪里创建模型,因此不清楚放置计数器的最佳位置在哪里。

基本上,您需要修改添加标签的方法,而不是保存添加标签之前运行的帖子的方法。

编辑:一个简单的选择是明确定义多对多关系的直通模型,然后您可以修改它的保存方法并在那里进行递增:https ://docs.djangoproject.com/en/1.5/topics/db/models /#多对多关系

于 2013-09-14T11:54:55.587 回答