我一直在研究标签模型,并试图避免使用内容类型。我在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(泛型类型)做到这一点,但我不知道它会如何在大量使用下执行,这就是为什么我想做多对多的领域..有什么建议吗?
答案 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