Commit 2b00049c by Alex Gaynor

Fixed #17. On django 1.2 support deleting objects with Tags. Also a lot of other fixers.

parent c5659072
...@@ -3,7 +3,15 @@ from django import forms ...@@ -3,7 +3,15 @@ from django import forms
from taggit.utils import parse_tags from taggit.utils import parse_tags
class TagWidget(forms.TextInput):
def render(self, name, value, attrs=None):
if not isinstance(value, basestring):
value = ", ".join(o.tag.name for o in value.select_related("tag"))
return super(TagWidget, self).render(name, value, attrs)
class TagField(forms.CharField): class TagField(forms.CharField):
widget = TagWidget
def clean(self, value): def clean(self, value):
try: try:
return parse_tags(value) return parse_tags(value)
......
...@@ -70,8 +70,9 @@ class TaggableManager(object): ...@@ -70,8 +70,9 @@ class TaggableManager(object):
else: else:
# Fucking flip-floppers. # Fucking flip-floppers.
raise ValueError("You can't combine Tag objects and strings. '%s' was provided." % value) raise ValueError("You can't combine Tag objects and strings. '%s' was provided." % value)
sql, params = qs.values_list("pk", flat=True).query.as_sql() if hasattr(models.Field, "get_prep_lookup"):
return QueryWrapper(("(%s)" % sql), params) return models.Field().get_prep_lookup(lookup_type, qs)
return models.Field().get_db_prep_lookup(lookup_type, qs)
if django.VERSION < (1, 2): if django.VERSION < (1, 2):
get_db_prep_lookup = get_prep_lookup get_db_prep_lookup = get_prep_lookup
...@@ -79,7 +80,7 @@ class TaggableManager(object): ...@@ -79,7 +80,7 @@ class TaggableManager(object):
def get_db_prep_lookup(self, lookup_type, value, connection, prepared=False): def get_db_prep_lookup(self, lookup_type, value, connection, prepared=False):
if not prepared: if not prepared:
return self.get_prep_lookup(lookup_type, value) return self.get_prep_lookup(lookup_type, value)
return value return models.Field().get_db_prep_lookup(lookup_type, value, connection=connection, prepared=True)
def formfield(self, form_class=TagField, **kwargs): def formfield(self, form_class=TagField, **kwargs):
defaults = { defaults = {
...@@ -91,8 +92,11 @@ class TaggableManager(object): ...@@ -91,8 +92,11 @@ class TaggableManager(object):
def value_from_object(self, instance): def value_from_object(self, instance):
if instance.pk: if instance.pk:
return ", ".join(map(unicode, getattr(instance, self.name).all())) return TaggedItem.objects.filter(
return "" object_id=instance.pk,
content_type=ContentType.objects.get_for_model(instance)
)
return TaggedItem.objects.none()
def related_query_name(self): def related_query_name(self):
return None return None
......
from taggit.tests.tests import AddTagTestCase, LookupByTagTestCase, TaggableFormTestCase, SimilarityByTagTestCase, TagReuseTestCase from taggit.tests.tests import (AddTagTestCase, DeleteObjecTestCase,
LookupByTagTestCase, TaggableFormTestCase, SimilarityByTagTestCase,
TagReuseTestCase)
...@@ -67,6 +67,17 @@ class AddTagTestCase(BaseTaggingTest): ...@@ -67,6 +67,17 @@ class AddTagTestCase(BaseTaggingTest):
apple.tags.add("Red", "red") apple.tags.add("Red", "red")
class DeleteObjecTestCase(BaseTaggingTest):
def test_delete_obj(self):
apple = Food.objects.create(name="apple")
apple.tags.add("red")
self.assert_tags_equal(apple.tags.all(), ["red"])
strawberry = Food.objects.create(name="strawberry")
strawberry.tags.add("red")
apple.delete()
self.assert_tags_equal(strawberry.tags.all(), ["red"])
class LookupByTagTestCase(BaseTaggingTest): class LookupByTagTestCase(BaseTaggingTest):
def test_lookup_by_tag(self): def test_lookup_by_tag(self):
apple = Food.objects.create(name="apple") apple = Food.objects.create(name="apple")
...@@ -100,6 +111,7 @@ class TaggableFormTestCase(BaseTaggingTest): ...@@ -100,6 +111,7 @@ class TaggableFormTestCase(BaseTaggingTest):
self.assertEqual(FoodForm.base_fields.keys(), ['name', 'tags']) self.assertEqual(FoodForm.base_fields.keys(), ['name', 'tags'])
f = FoodForm({'name': 'apple', 'tags': 'green, red, yummy'}) f = FoodForm({'name': 'apple', 'tags': 'green, red, yummy'})
self.assertEqual(str(f), """<tr><th><label for="id_name">Name:</label></th><td><input id="id_name" type="text" name="name" value="apple" maxlength="50" /></td></tr>\n<tr><th><label for="id_tags">Tags:</label></th><td><input type="text" name="tags" value="green, red, yummy" id="id_tags" /></td></tr>""")
f.save() f.save()
apple = Food.objects.get(name='apple') apple = Food.objects.get(name='apple')
self.assert_tags_equal(apple.tags.all(), ['green', 'red', 'yummy']) self.assert_tags_equal(apple.tags.all(), ['green', 'red', 'yummy'])
...@@ -114,6 +126,9 @@ class TaggableFormTestCase(BaseTaggingTest): ...@@ -114,6 +126,9 @@ class TaggableFormTestCase(BaseTaggingTest):
raspberry = f.save() raspberry = f.save()
self.assert_tags_equal(raspberry.tags.all(), []) self.assert_tags_equal(raspberry.tags.all(), [])
f = FoodForm(instance=apple)
self.assertEqual(str(f), """<tr><th><label for="id_name">Name:</label></th><td><input id="id_name" type="text" name="name" value="apple" maxlength="50" /></td></tr>\n<tr><th><label for="id_tags">Tags:</label></th><td><input type="text" name="tags" value="green, red, yummy, delicious" id="id_tags" /></td></tr>""")
class SimilarityByTagTestCase(BaseTaggingTest): class SimilarityByTagTestCase(BaseTaggingTest):
def test_similarity_by_tag(self): def test_similarity_by_tag(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