+# -*- coding: utf-8 -*-
"""
Models and managers for generic tagging.
"""
+
# Python 2.3 compatibility
-if not hasattr(__builtins__, 'set'):
+try:
+ set
+except NameError:
from sets import Set as set
from django.contrib.contenttypes import generic
from django.db import connection, models
from django.utils.translation import ugettext_lazy as _
from django.db.models.base import ModelBase
+from django.core.exceptions import ObjectDoesNotExist
qn = connection.ops.quote_name
if tag not in current_tags:
self.intermediary_table_model._default_manager.create(tag=tag, content_object=obj)
+ def remove_tag(self, obj, tag):
+ """
+ Remove tag from an object.
+ """
+ content_type = ContentType.objects.get_for_model(obj)
+ self.intermediary_table_model._default_manager.filter(content_type__pk=content_type.pk,
+ object_id=obj.pk, tag=tag).delete()
+
def get_for_object(self, obj):
"""
Create a queryset matching all tags associated with the given
WHERE %(tagged_item)s.content_type_id = %(content_type_id)s
AND %(tagged_item)s.object_id IN
(
- SELECT temporary.object_id
+ SELECT *
FROM (
SELECT %(tagged_item)s.object_id
FROM %(tagged_item)s, %(tag)s
HAVING COUNT(%(tagged_item)s.object_id) = %(tag_count)s
) AS temporary
)
+ AND %(tag)s.id NOT IN (%(tag_id_placeholders)s)
%(extra_where)s
GROUP BY %(tag_columns)s
%(min_count_sql)s
unique_together = (('tag', 'content_type', 'object_id'),)
def obj_unicode(self):
- return u'%s [%s]' % (self.content_type.get_object_for_this_type(pk=self.object_id), self.tag)
-
+ try:
+ return u'%s [%s]' % (self.content_type.get_object_for_this_type(pk=self.object_id), self.tag)
+ except ObjectDoesNotExist:
+ return u'<deleted> [%s]' % self.tag
+
# Set up a dictionary to simulate declarations within a class
attrs = {
'__module__': model.__module__,