django很多很多字段 - 以编程方式检索关系

时间:2011-08-11 20:18:25

标签: django

我一直在研究标签模型,并试图避免使用内容类型。我在django有几个与ManyToManyField相关的问题。

我有以下型号

taggables / models.py

class Tag(models.Model):
    tag_statuses = (
        (u'P', _('Pending approval')),
        (u'A', _('Approved')),
    )
    slug             = models.SlugField()

    created_at      = models.DateTimeField(null=True, blank=True)
    created_by      = models.ForeignKey(User, related_name='tagged_item_created_by')
    status          = models.CharField(max_length=20, choices=tag_statuses)
    site            = models.ForeignKey(Site, default=settings.SITE_ID, related_name='tagged_item_site')


    def __unicode__(self):
        return self.slug


class TagI18n(models.Model):
    tag                 = models.CharField(max_length=100)
    descriptor          = models.TextField(null=True, blank=True)

    # i18n properties
    item                = models.ForeignKey(Tag)
    language            = models.CharField(max_length=6, choices=settings.LANGUAGES, default=settings.LANGUAGE_CODE)

    class Meta:
        unique_together = (("language", "item"))
    def __unicode__(self):
        return self.tag

我的项目周围也有不同的应用程序,它们使用标记模型作为多个字段。例如事件

evetns / models.py

class Item(models.Model):
    event_status_list = (
        (u'P', _('Pending approval')),
        (u'A', _('Approved')),
        (u'R', _('Rejected')),
        (u'S', _('Spam')),
    )

    published_at        = models.DateTimeField(null=True, blank=True)
    published_by        = models.ForeignKey(User, null=True, blank=True, related_name='item_published_by')
    updated_by          = models.ForeignKey(User, null=True, blank=True, related_name='item_updated_by')
    updated_at          = models.DateTimeField(null=True, blank=True)

    site                = models.ForeignKey(Site, default=settings.SITE_ID, related_name='events_item_site')

    event_slug          = models.SlugField(null=True, blank=True)

    # event timing
    event_start_date    = models.DateField()
    event_start_time    = models.TimeField(null=True, blank=True)
    event_end_date      = models.DateField()
    event_end_time      = models.TimeField(null=True, blank=True)


    event_recurrent     = models.BooleanField(default=False)
    event_status        = models.CharField(max_length=20, choices=event_status_list, default=u'P')

    # relations
    media        = models.ManyToManyField(ImageFile, null=True, blank=True)
    comments     = models.ManyToManyField(Comment, null=True, blank=True)
    votes        = models.ManyToManyField(Vote, null=True, blank=True)
    tags         = models.ManyToManyField(Tag, null=True, blank=True)
    audience     = models.ManyToManyField(Audience, null=True, blank=True)

现在我要做的是运行查询以编程方式将所有相关模型检索到Tag,然后计算标签的使用次数。我确定我可以用contenttypes(泛型类型)做到这一点,但我不知道它会如何在大量使用下执行,这就是为什么我想做多对多的领域..有什么建议吗?

2 个答案:

答案 0 :(得分:0)

如果您经常对标签的使用总数(也就是引用计数)感兴趣,我认为您应该将它存储在数据库中,例如将一个额外字段添加到Tag模型中,例如

referencecount = models.IntegerField( default=0 )

在适当的位置,(示例模型.save()),您可以增加或减少它的值。

答案 1 :(得分:0)

对于您的用例,泛型的性能无关紧要,因为您无论如何都需要在2N个表上进行N个查询(每个“可标记”模型一个,每个m2m连接表一个,至少)。

使用m2m方法,您应该将“可标记”模型列表存储在某处,至少作为(“app_name”,“model”)对的列表。然后使用ContentType(它非常高效)直接从那里获取实际的模型类或查询:

counts = {}
for m in taggable_models:
    ct = ContentType.get_by_natural_key(*m)
    c = ct.model_class().objects.filter(tags=yourtag).distinct().count()
    counts[ct.name] = c