我一直在研究标签模型,并试图避免使用内容类型。我有几个问题与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