Commit b5fc5d93 by Alex Gaynor

Fixed #7. Corrected tags__in= lookups with inheritance.

parent 4eb17239
...@@ -3,6 +3,7 @@ from collections import defaultdict ...@@ -3,6 +3,7 @@ from collections import defaultdict
import django import django
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.db import models from django.db import models
from django.db.models.related import RelatedObject
from django.db.models.fields.related import ManyToManyRel from django.db.models.fields.related import ManyToManyRel
from django.db.models.query_utils import QueryWrapper from django.db.models.query_utils import QueryWrapper
...@@ -106,7 +107,10 @@ class TaggableManager(object): ...@@ -106,7 +107,10 @@ class TaggableManager(object):
if negate: if negate:
return [] return []
prefix = "__".join(pieces[:pos+1]) prefix = "__".join(pieces[:pos+1])
return [("%s__content_type" % prefix, ContentType.objects.get_for_model(self.model))] cts = map(ContentType.objects.get_for_model, _get_subclasses(self.model))
if len(cts) == 1:
return [("%s__content_type" % prefix, cts[0])]
return [("%s__content_type__in" % prefix, cts)]
class _TaggableManager(models.Manager): class _TaggableManager(models.Manager):
...@@ -175,3 +179,11 @@ class _TaggableManager(models.Manager): ...@@ -175,3 +179,11 @@ class _TaggableManager(models.Manager):
obj.similar_tags = result["n"] obj.similar_tags = result["n"]
results.append(obj) results.append(obj)
return results return results
def _get_subclasses(model):
subclasses = [model]
for f in model._meta.get_all_field_names():
field = model._meta.get_field_by_name(f)[0]
if isinstance(field, RelatedObject) and field.field.rel.parent_link:
subclasses.extend(_get_subclasses(field.model))
return subclasses
...@@ -16,3 +16,6 @@ class Pet(models.Model): ...@@ -16,3 +16,6 @@ class Pet(models.Model):
name = models.CharField(max_length=50) name = models.CharField(max_length=50)
tags = TaggableManager() tags = TaggableManager()
class HousePet(Pet):
trained = models.BooleanField()
\ No newline at end of file
...@@ -2,7 +2,7 @@ from django.test import TestCase ...@@ -2,7 +2,7 @@ from django.test import TestCase
from taggit.models import Tag from taggit.models import Tag
from taggit.tests.forms import FoodForm from taggit.tests.forms import FoodForm
from taggit.tests.models import Food, Pet from taggit.tests.models import Food, Pet, HousePet
class BaseTaggingTest(TestCase): class BaseTaggingTest(TestCase):
...@@ -65,6 +65,14 @@ class LookupByTagTestCase(BaseTaggingTest): ...@@ -65,6 +65,14 @@ class LookupByTagTestCase(BaseTaggingTest):
tag = Tag.objects.get(name="woof") tag = Tag.objects.get(name="woof")
self.assertEqual(list(Pet.objects.filter(tags__in=[tag])), [dog]) self.assertEqual(list(Pet.objects.filter(tags__in=[tag])), [dog])
cat = HousePet.objects.create(name="cat", trained=True)
cat.tags.add("fuzzy")
self.assertEqual(
map(lambda o: o.pk, Pet.objects.filter(tags__in=["fuzzy"])),
[kitty.pk, cat.pk]
)
class TaggableFormTestCase(BaseTaggingTest): class TaggableFormTestCase(BaseTaggingTest):
def test_form(self): def test_form(self):
......
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