Moved fragment metadata to the right.
[wolnelektury.git] / newtagging / models.py
index 9664772..0c2b0e1 100644 (file)
@@ -8,12 +8,9 @@ if not hasattr(__builtins__, 'set'):
 from django.contrib.contenttypes import generic
 from django.contrib.contenttypes.models import ContentType
 from django.db import connection, models
 from django.contrib.contenttypes import generic
 from django.contrib.contenttypes.models import ContentType
 from django.db import connection, models
-from django.db.models.query import QuerySet
 from django.utils.translation import ugettext_lazy as _
 from django.db.models.base import ModelBase
 
 from django.utils.translation import ugettext_lazy as _
 from django.db.models.base import ModelBase
 
-from newtagging.utils import get_tag_list, get_queryset_and_model
-
 qn = connection.ops.quote_name
 
 try:
 qn = connection.ops.quote_name
 
 try:
@@ -22,10 +19,23 @@ except ImportError:
     parse_lookup = None
 
 
     parse_lookup = None
 
 
+def get_queryset_and_model(queryset_or_model):
+    """
+    Given a ``QuerySet`` or a ``Model``, returns a two-tuple of
+    (queryset, model).
+
+    If a ``Model`` is given, the ``QuerySet`` returned will be created
+    using its default manager.
+    """
+    try:
+        return queryset_or_model, queryset_or_model.model
+    except AttributeError:
+        return queryset_or_model._default_manager.all(), queryset_or_model
+
+
 ############
 # Managers #
 ############
 ############
 # Managers #
 ############
-
 class TagManager(models.Manager):
     def __init__(self, intermediary_table_model):
         super(TagManager, self).__init__()
 class TagManager(models.Manager):
     def __init__(self, intermediary_table_model):
         super(TagManager, self).__init__()
@@ -38,7 +48,7 @@ class TagManager(models.Manager):
         content_type = ContentType.objects.get_for_model(obj)
         current_tags = list(self.filter(items__content_type__pk=content_type.pk,
                                         items__object_id=obj.pk))
         content_type = ContentType.objects.get_for_model(obj)
         current_tags = list(self.filter(items__content_type__pk=content_type.pk,
                                         items__object_id=obj.pk))
-        updated_tags = get_tag_list(tags)
+        updated_tags = self.model.get_tag_list(tags)
     
         # Remove tags which no longer apply
         tags_for_removal = [tag for tag in current_tags \
     
         # Remove tags which no longer apply
         tags_for_removal = [tag for tag in current_tags \
@@ -52,23 +62,6 @@ class TagManager(models.Manager):
             if tag not in current_tags:
                 self.intermediary_table_model._default_manager.create(tag=tag, content_object=obj)
     
             if tag not in current_tags:
                 self.intermediary_table_model._default_manager.create(tag=tag, content_object=obj)
     
-    # def add_tag(self, obj, tag_name):
-    #     """
-    #     Associates the given object with a tag.
-    #     """
-    #     tag_names = parse_tag_input(tag_name)
-    #     if not len(tag_names):
-    #         raise AttributeError(_('No tags were given: "%s".') % tag_name)
-    #     if len(tag_names) > 1:
-    #         raise AttributeError(_('Multiple tags were given: "%s".') % tag_name)
-    #     tag_name = tag_names[0]
-    #     # if settings.FORCE_LOWERCASE_TAGS:
-    #     #     tag_name = tag_name.lower()
-    #     tag, created = self.get_or_create(name=tag_name)
-    #     ctype = ContentType.objects.get_for_model(obj)
-    #     self.intermediary_table_model._default_manager.get_or_create(
-    #         tag=tag, content_type=ctype, object_id=obj.pk)
-
     def get_for_object(self, obj):
         """
         Create a queryset matching all tags associated with the given
     def get_for_object(self, obj):
         """
         Create a queryset matching all tags associated with the given
@@ -77,7 +70,7 @@ class TagManager(models.Manager):
         ctype = ContentType.objects.get_for_model(obj)
         return self.filter(items__content_type__pk=ctype.pk,
                            items__object_id=obj.pk)
         ctype = ContentType.objects.get_for_model(obj)
         return self.filter(items__content_type__pk=ctype.pk,
                            items__object_id=obj.pk)
-
+    
     def _get_usage(self, model, counts=False, min_count=None, extra_joins=None, extra_criteria=None, params=None, extra=None):
         """
         Perform the custom SQL query for ``usage_for_model`` and
     def _get_usage(self, model, counts=False, min_count=None, extra_joins=None, extra_criteria=None, params=None, extra=None):
         """
         Perform the custom SQL query for ``usage_for_model`` and
@@ -214,7 +207,7 @@ class TagManager(models.Manager):
         Passing a value for ``min_count`` implies ``counts=True``.
         """
         if min_count is not None: counts = True
         Passing a value for ``min_count`` implies ``counts=True``.
         """
         if min_count is not None: counts = True
-        tags = get_tag_list(tags)
+        tags = self.model.get_tag_list(tags)
         tag_count = len(tags)
         tagged_item_table = qn(self.intermediary_table_model._meta.db_table)
         tag_columns = self._get_tag_columns()
         tag_count = len(tags)
         tagged_item_table = qn(self.intermediary_table_model._meta.db_table)
         tag_columns = self._get_tag_columns()
@@ -287,12 +280,16 @@ class TaggedItemManager(models.Manager):
           Once the queryset-refactor branch lands in trunk, this can be
           tidied up significantly.
     """
           Once the queryset-refactor branch lands in trunk, this can be
           tidied up significantly.
     """
+    def __init__(self, tag_model):
+        super(TaggedItemManager, self).__init__()
+        self.tag_model = tag_model
+    
     def get_by_model(self, queryset_or_model, tags):
         """
         Create a ``QuerySet`` containing instances of the specified
         model associated with a given tag or list of tags.
         """
     def get_by_model(self, queryset_or_model, tags):
         """
         Create a ``QuerySet`` containing instances of the specified
         model associated with a given tag or list of tags.
         """
-        tags = get_tag_list(tags)
+        tags = self.tag_model.get_tag_list(tags)
         tag_count = len(tags)
         if tag_count == 0:
             # No existing tags were given
         tag_count = len(tags)
         if tag_count == 0:
             # No existing tags were given
@@ -326,7 +323,7 @@ class TaggedItemManager(models.Manager):
         Create a ``QuerySet`` containing instances of the specified
         model associated with *all* of the given list of tags.
         """
         Create a ``QuerySet`` containing instances of the specified
         model associated with *all* of the given list of tags.
         """
-        tags = get_tag_list(tags)
+        tags = self.tag_model.get_tag_list(tags)
         tag_count = len(tags)
         queryset, model = get_queryset_and_model(queryset_or_model)
 
         tag_count = len(tags)
         queryset, model = get_queryset_and_model(queryset_or_model)
 
@@ -365,7 +362,7 @@ class TaggedItemManager(models.Manager):
         Create a ``QuerySet`` containing instances of the specified
         model associated with *any* of the given list of tags.
         """
         Create a ``QuerySet`` containing instances of the specified
         model associated with *any* of the given list of tags.
         """
-        tags = get_tag_list(tags)
+        tags = self.tag_model.get_tag_list(tags)
         tag_count = len(tags)
         queryset, model = get_queryset_and_model(queryset_or_model)
 
         tag_count = len(tags)
         queryset, model = get_queryset_and_model(queryset_or_model)
 
@@ -486,9 +483,9 @@ class TagMeta(ModelBase):
         model = super(TagMeta, cls).__new__(cls, name, bases, attrs)
         if not model._meta.abstract:
             # Create an intermediary table and register custom managers for concrete models
         model = super(TagMeta, cls).__new__(cls, name, bases, attrs)
         if not model._meta.abstract:
             # Create an intermediary table and register custom managers for concrete models
-            intermediary_table_model = create_intermediary_table_model(model)
-            TagManager(intermediary_table_model).contribute_to_class(model, 'objects')
-            TaggedItemManager().contribute_to_class(intermediary_table_model, 'objects')
+            model.intermediary_table_model = create_intermediary_table_model(model)
+            TagManager(model.intermediary_table_model).contribute_to_class(model, 'objects')
+            TaggedItemManager(model).contribute_to_class(model.intermediary_table_model, 'objects')
         return model
 
 
         return model
 
 
@@ -498,4 +495,16 @@ class TagBase(models.Model):
     
     class Meta:
         abstract = True
     
     class Meta:
         abstract = True
+    
+    @staticmethod
+    def get_tag_list(tag_list):
+        """
+        Utility function for accepting tag input in a flexible manner.
+        
+        You should probably override this method in your subclass.
+        """
+        if isinstance(tag_list, TagBase):
+            return [tag_list]
+        else:
+            return tag_list