Commit 515106b7 by Alex Gaynor

Refactor the inheritance heirarchy to allow custom through models, new tests are fialing

parent f3a56d57
...@@ -6,7 +6,7 @@ from django.template.defaultfilters import slugify ...@@ -6,7 +6,7 @@ from django.template.defaultfilters import slugify
from django.utils.translation import ugettext_lazy as _, ugettext from django.utils.translation import ugettext_lazy as _, ugettext
class Tag(models.Model): class TagBase(models.Model):
name = models.CharField(verbose_name=_('Name'), max_length=100) name = models.CharField(verbose_name=_('Name'), max_length=100)
slug = models.SlugField(verbose_name=_('Slug'), unique=True, max_length=100) slug = models.SlugField(verbose_name=_('Slug'), unique=True, max_length=100)
...@@ -14,8 +14,7 @@ class Tag(models.Model): ...@@ -14,8 +14,7 @@ class Tag(models.Model):
return self.name return self.name
class Meta: class Meta:
verbose_name = _("Tag") abstract = True
verbose_name_plural = _("Tags")
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
if not self.pk and not self.slug: if not self.pk and not self.slug:
...@@ -35,7 +34,7 @@ class Tag(models.Model): ...@@ -35,7 +34,7 @@ class Tag(models.Model):
while True: while True:
try: try:
sid = transaction.savepoint(**trans_kwargs) sid = transaction.savepoint(**trans_kwargs)
res = super(Tag, self).save(*args, **kwargs) res = super(TagBase, self).save(*args, **kwargs)
transaction.savepoint_commit(sid, **trans_kwargs) transaction.savepoint_commit(sid, **trans_kwargs)
return res return res
except IntegrityError: except IntegrityError:
...@@ -45,13 +44,14 @@ class Tag(models.Model): ...@@ -45,13 +44,14 @@ class Tag(models.Model):
else: else:
return super(Tag, self).save(*args, **kwargs) return super(Tag, self).save(*args, **kwargs)
class Tag(TagBase):
class Meta:
verbose_name = _("Tag")
verbose_name_plural = _("Tags")
class TaggedItemBase(models.Model):
if django.VERSION < (1, 2):
tag = models.ForeignKey(Tag, related_name="%(class)s_items")
else:
tag = models.ForeignKey(Tag, related_name="%(app_label)s_%(class)s_items")
class ItemBase(models.Model):
def __unicode__(self): def __unicode__(self):
return ugettext("%(object)s tagged with %(tag)s") % { return ugettext("%(object)s tagged with %(tag)s") % {
"object": self.content_object, "object": self.content_object,
...@@ -82,15 +82,34 @@ class TaggedItemBase(models.Model): ...@@ -82,15 +82,34 @@ class TaggedItemBase(models.Model):
}).distinct() }).distinct()
class TaggedItem(TaggedItemBase): class TaggedItemBase(ItemBase):
if django.VERSION < (1, 2):
tag = models.ForeignKey(Tag, related_name="%(class)s_items")
else:
tag = models.ForeignKey(Tag, related_name="%(app_label)s_%(class)s_items")
class Meta:
abstract = True
class GenericTaggedItemBase(ItemBase):
object_id = models.IntegerField(verbose_name=_('Object id'), db_index=True) object_id = models.IntegerField(verbose_name=_('Object id'), db_index=True)
content_type = models.ForeignKey(ContentType, verbose_name=_('Content type'), if django.VERSION < (1, 2):
related_name="tagged_items") content_type = models.ForeignKey(
ContentType,
verbose_name=_('Content type'),
related_name="%(class)s_tagged_items"
)
else:
content_type = models.ForeignKey(
ContentType,
verbose_name=_('Content type'),
related_name="%(app_label)s_%(class)s_tagged_items"
)
content_object = GenericForeignKey() content_object = GenericForeignKey()
class Meta: class Meta:
verbose_name = _("Tagged Item") abstract=True
verbose_name_plural = _("Tagged Items")
@classmethod @classmethod
def lookup_kwargs(cls, instance): def lookup_kwargs(cls, instance):
...@@ -111,3 +130,9 @@ class TaggedItem(TaggedItemBase): ...@@ -111,3 +130,9 @@ class TaggedItem(TaggedItemBase):
'%s__content_type' % cls.tag_relname(): ct '%s__content_type' % cls.tag_relname(): ct
}).distinct() }).distinct()
class TaggedItem(GenericTaggedItemBase, TaggedItemBase):
class Meta:
verbose_name = _("Tagged Item")
verbose_name_plural = _("Tagged Items")
from django.db import models from django.db import models
from taggit.managers import TaggableManager from taggit.managers import TaggableManager
from taggit.models import TaggedItemBase from taggit.models import TaggedItemBase, GenericTaggedItemBase, TagBase
class Food(models.Model): class Food(models.Model):
...@@ -75,3 +75,31 @@ class CustomPKPet(models.Model): ...@@ -75,3 +75,31 @@ class CustomPKPet(models.Model):
class CustomPKHousePet(CustomPKPet): class CustomPKHousePet(CustomPKPet):
trained = models.BooleanField() trained = models.BooleanField()
# Test custom through model to a custom tag model
class OfficialTag(TagBase):
official = models.BooleanField()
class OfficialThroughModel(GenericTaggedItemBase):
tag = models.ForeignKey(OfficialTag, related_name="tagged_items")
class OfficialFood(models.Model):
name = models.CharField(max_length=50, primary_key=True)
tags = TaggableManager(through=OfficialThroughModel)
def __unicode__(self):
return self.name
class OfficialPet(models.Model):
name = models.CharField(max_length=50, primary_key=True)
tags = TaggableManager(through=OfficialThroughModel)
def __unicode__(self):
return self.name
class OfficialHousePet(CustomPKPet):
trained = models.BooleanField()
...@@ -6,7 +6,8 @@ from taggit.models import Tag, TaggedItem ...@@ -6,7 +6,8 @@ from taggit.models import Tag, TaggedItem
from taggit.tests.forms import FoodForm, DirectFoodForm, CustomPKFoodForm from taggit.tests.forms import FoodForm, DirectFoodForm, CustomPKFoodForm
from taggit.tests.models import (Food, Pet, HousePet, DirectFood, DirectPet, from taggit.tests.models import (Food, Pet, HousePet, DirectFood, DirectPet,
DirectHousePet, TaggedPet, CustomPKFood, CustomPKPet, CustomPKHousePet, DirectHousePet, TaggedPet, CustomPKFood, CustomPKPet, CustomPKHousePet,
TaggedCustomPKPet) TaggedCustomPKPet, OfficialFood, OfficialPet, OfficialHousePet,
OfficialThroughModel)
from taggit.utils import parse_tags, edit_string_for_tags from taggit.utils import parse_tags, edit_string_for_tags
...@@ -213,6 +214,13 @@ class TaggableManagerCustomPKTestCase(TaggableManagerTestCase): ...@@ -213,6 +214,13 @@ class TaggableManagerCustomPKTestCase(TaggableManagerTestCase):
# tell if the instance is saved or not # tell if the instance is saved or not
pass pass
class TaggableManagerOfficialTestCase(TaggableManagerTestCase):
food_model = OfficialFood
pet_model = OfficialPet
housepet_model = OfficialHousePet
taggeditem_model = OfficialThroughModel
class TaggableFormTestCase(BaseTaggingTestCase): class TaggableFormTestCase(BaseTaggingTestCase):
form_class = FoodForm form_class = FoodForm
food_model = Food food_model = Food
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment