django多对多字段编程检索关系



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

我有以下型号的

标签/模型.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

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

级别/型号.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相关的模型,然后计算一个标记的使用次数。我确信我可以用contenttype(泛型类型(做到这一点,但我不知道在大量使用的情况下它会如何执行,这就是为什么我想做多对多字段。

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

referencecount = models.IntegerField( default=0 )

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

对于您的用例,泛型的性能无关紧要,因为您无论如何都需要对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

最新更新