Permalink
Browse files

Added support for a custom slugify.

  • Loading branch information...
1 parent dccc744 commit f759697fd4998be02ea1b41d8d6f94f731162920 @alex alex committed Oct 17, 2010
Showing with 59 additions and 20 deletions.
  1. +2 −2 taggit/managers.py
  2. +10 −5 taggit/models.py
  3. +27 −2 taggit/tests/models.py
  4. +20 −11 taggit/tests/tests.py
View
@@ -142,10 +142,10 @@ def add(self, *tags):
name__in=str_tags
)
tag_objs.update(existing)
-
+
for new_tag in str_tags - set(t.name for t in existing):
tag_objs.add(self.through.tag_model().objects.create(name=new_tag))
-
+
for tag in tag_objs:
self.through.objects.get_or_create(tag=tag, **self._lookup_kwargs())
View
@@ -2,7 +2,7 @@
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.generic import GenericForeignKey
from django.db import models, IntegrityError, transaction
-from django.template.defaultfilters import slugify
+from django.template.defaultfilters import slugify as default_slugify
from django.utils.translation import ugettext_lazy as _, ugettext
@@ -18,7 +18,7 @@ class Meta:
def save(self, *args, **kwargs):
if not self.pk and not self.slug:
- self.slug = slug = slugify(self.name)
+ self.slug = self.slugify(self.name)
if django.VERSION >= (1, 2):
from django.db import router
using = kwargs.get("using") or router.db_for_write(
@@ -39,11 +39,17 @@ def save(self, *args, **kwargs):
return res
except IntegrityError:
transaction.savepoint_rollback(sid, **trans_kwargs)
- i += 1
- self.slug = "%s_%d" % (slug, i)
+ self.slug = self.slugify(self.name, i)
else:
return super(TagBase, self).save(*args, **kwargs)
+ def slugify(self, tag, i=None):
+ slug = default_slugify(tag)
+ if i is not None:
+ slug += "_%d" % i
+ return slug
+
+
class Tag(TagBase):
class Meta:
verbose_name = _("Tag")
@@ -137,4 +143,3 @@ class TaggedItem(GenericTaggedItemBase, TaggedItemBase):
class Meta:
verbose_name = _("Tagged Item")
verbose_name_plural = _("Tagged Items")
-
View
@@ -1,7 +1,8 @@
from django.db import models
from taggit.managers import TaggableManager
-from taggit.models import TaggedItemBase, GenericTaggedItemBase, TagBase
+from taggit.models import (TaggedItemBase, GenericTaggedItemBase, TaggedItem,
+ TagBase, Tag)
class Food(models.Model):
@@ -106,7 +107,7 @@ class OfficialHousePet(OfficialPet):
class Media(models.Model):
tags = TaggableManager()
-
+
class Meta:
abstract = True
@@ -115,3 +116,27 @@ class Photo(Media):
class Movie(Media):
pass
+
+
+class ArticleTag(Tag):
+ class Meta:
+ proxy = True
+
+ def slugify(self, tag, i=None):
+ slug = "category-%s" % tag
+ if i is not None:
+ slug += "-%d" % i
+ return slug
+
+class ArticleTaggedItem(TaggedItem):
+ class Meta:
+ proxy = True
+
+ # Basically we want to overide the tag ForeignKey to point at the proxy
+ # inherited ArticleTag so we can get the right slugify, unfortunately I
+ # can't seem to figure out how to do this, so we're on hold ATM.
+
+class Article(models.Model):
+ title = models.CharField(max_length=100)
+
+ tags = TaggableManager(through=ArticleTaggedItem)
View
@@ -12,18 +12,18 @@
from taggit.tests.models import (Food, Pet, HousePet, DirectFood, DirectPet,
DirectHousePet, TaggedPet, CustomPKFood, CustomPKPet, CustomPKHousePet,
TaggedCustomPKPet, OfficialFood, OfficialPet, OfficialHousePet,
- OfficialThroughModel, OfficialTag, Photo, Movie)
+ OfficialThroughModel, OfficialTag, Photo, Movie, Article)
from taggit.utils import parse_tags, edit_string_for_tags
class BaseTaggingTest(object):
- def assert_tags_equal(self, qs, tags, sort=True):
- got = map(lambda tag: tag.name, qs)
+ def assert_tags_equal(self, qs, tags, sort=True, attr="name"):
+ got = map(lambda tag: getattr(tag, attr), qs)
if sort:
got.sort()
tags.sort()
self.assertEqual(got, tags)
-
+
def assert_num_queries(self, n, f, *args, **kwargs):
original_DEBUG = settings.DEBUG
settings.DEBUG = True
@@ -61,6 +61,15 @@ def test_add(self):
yummy = self.tag_model.objects.create(name="yummy")
apple.tags.add(yummy)
+ def test_slugify(self):
+ a = Article.objects.create(title="django-taggit 1.0 Released")
+ a.tags.add("awesome", "release", "AWESOME")
+ self.assert_tags_equal(a.tags.all(), [
+ "category-awesome",
+ "category-release",
+ "category-awesome-1"
+ ], attr="slug")
+
class TagModelDirectTestCase(TagModelTestCase):
food_model = DirectFood
tag_model = Tag
@@ -113,21 +122,21 @@ def test_add_tag(self):
apple.delete()
self.assert_tags_equal(self.food_model.tags.all(), ["green"])
-
+
def test_add_queries(self):
apple = self.food_model.objects.create(name="apple")
# 1 query to see which tags exist
# + 3 queries to create the tags.
# + 6 queries to create the intermediary things (including SELECTs, to
# make sure we don't double create.
self.assert_num_queries(10, apple.tags.add, "red", "delicious", "green")
-
+
pear = self.food_model.objects.create(name="pear")
# 1 query to see which tags exist
# + 4 queries to create the intermeidary things (including SELECTs, to
# make sure we dont't double create.
self.assert_num_queries(5, pear.tags.add, "green", "delicious")
-
+
self.assert_num_queries(0, pear.tags.add)
def test_require_pk(self):
@@ -245,15 +254,15 @@ def test_taggeditem_unicode(self):
unicode(self.taggeditem_model.objects.all()[0]),
"ross tagged with president"
)
-
+
def test_abstract_subclasses(self):
p = Photo.objects.create()
p.tags.add("outdoors", "pretty")
self.assert_tags_equal(
p.tags.all(),
["outdoors", "pretty"]
)
-
+
m = Movie.objects.create()
m.tags.add("hd")
self.assert_tags_equal(
@@ -340,9 +349,9 @@ def test_formfield(self):
self.assertEqual(ff.label, 'categories')
self.assertEqual(ff.help_text, u'Add some categories')
self.assertEqual(ff.required, False)
-
+
self.assertEqual(ff.clean(""), [])
-
+
tm = TaggableManager()
ff = tm.formfield()
self.assertRaises(ValidationError, ff.clean, "")

0 comments on commit f759697

Please sign in to comment.