使用django-taggit获取most_common标记,忽略某些标记对象

时间:2015-07-28 14:57:22

标签: django django-taggit

我正在使用django-taggit标记一些对象,书签。书签具有布尔is_private属性。

在获取最常用标签的列表时,我可以这样做:

Bookmark.tags.most_common()

但是如何才能获得最常用的标签,忽略is_private书签上的所有标签?如果有帮助,那么Bookmark.public_objects经理只会返回非私人书签。

1 个答案:

答案 0 :(得分:0)

I stumbled across the answer while looking through the django-taggit docs and code for something else. You can set a custom Manager on your model's tags attribute, and use this to add extra functionality.

So, previously, my Bookmark model had this:

from django.db import models
from taggit.managers import TaggableManager

class Bookmark(models.Model):
    # Other attributes here
    tags = TaggableManager

I've now changed that to this:

from django.db import models
from taggit.managers import TaggableManager
from .managers import _BookmarkTaggableManager

class Bookmark(models.Model):
    # Other attributes here
    tags = TaggableManager(manager=_BookmarkTaggableManager)

And then in myapp/managers.py I have this:

from django.db import models
from taggit.managers import _TaggableManager

class _BookmarkTaggableManager(_TaggableManager):

    def most_common_public(self):
        extra_filters = {'bookmark__is_private': False}

        return self.get_queryset(extra_filters).annotate(
            num_times=models.Count(self.through.tag_relname())
        ).order_by('-num_times')

That most_common_public() method is a copy of django-taggit's standard most_common() method but with the addition of passing that extra_filters to the queryset.

Then when I want the list of most common tags, but excluding private Bookmarks, I use this:

Bookmark.tags.most_common_public()

There might be a different method -- I'm a little uneasy about duplicating the entire query from most_common() for instance -- but this seems to work.