Commit cd097f7f by Alex Gaynor

Forms are better

parent daaf93d3
...@@ -3,16 +3,9 @@ from django import forms ...@@ -3,16 +3,9 @@ from django import forms
from taggit.utils import parse_tags from taggit.utils import parse_tags
class TaggableForm(forms.ModelForm): class TagField(forms.CharField):
tags = forms.CharField(help_text="A comma seperated list of tags.") def clean(self, value):
try:
def save(self, commit=True): return parse_tags(value)
obj = super(TaggableForm, self).save(commit=commit) except ValueError:
def save_tags(): raise forms.ValidationError("Please provide a comma seperate list of tags.")
# TODO: Remove the assumption that the manager is named 'tags'
obj.tags.set(*parse_tags(self.cleaned_data['tags']))
if commit:
save_tags()
else:
obj.save_tags = save_tags
return obj
...@@ -3,6 +3,7 @@ from django.db import models ...@@ -3,6 +3,7 @@ from django.db import models
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
from taggit.forms import TagField
from taggit.models import Tag, TaggedItem from taggit.models import Tag, TaggedItem
from taggit.utils import require_instance_manager from taggit.utils import require_instance_manager
...@@ -20,7 +21,7 @@ class TaggableRel(ManyToManyRel): ...@@ -20,7 +21,7 @@ class TaggableRel(ManyToManyRel):
class TaggableManager(object): class TaggableManager(object):
def __init__(self): def __init__(self):
self.rel = TaggableRel() self.rel = TaggableRel()
self.editable = False self.editable = True
self.unique = False self.unique = False
self.creates_table = False self.creates_table = False
self.db_column = None self.db_column = None
...@@ -41,7 +42,7 @@ class TaggableManager(object): ...@@ -41,7 +42,7 @@ class TaggableManager(object):
setattr(cls, name, self) setattr(cls, name, self)
def save_form_data(self, instance, value): def save_form_data(self, instance, value):
pass getattr(instance, self.name).set(*value)
def get_db_prep_lookup(self, lookup_type, value): def get_db_prep_lookup(self, lookup_type, value):
if lookup_type not in ("in", "exact"): if lookup_type not in ("in", "exact"):
...@@ -62,6 +63,14 @@ class TaggableManager(object): ...@@ -62,6 +63,14 @@ class TaggableManager(object):
sql, params = qs.values_list("pk", flat=True).query.as_sql() sql, params = qs.values_list("pk", flat=True).query.as_sql()
return QueryWrapper(("(%s)" % sql), params) return QueryWrapper(("(%s)" % sql), params)
def formfield(self, form_class=TagField, **kwargs):
defaults = {
"label": "Tags",
"help_text": "A comma seperated list of tags."
}
defaults.update(kwargs)
return form_class(**kwargs)
def related_query_name(self): def related_query_name(self):
return None return None
......
from taggit.forms import TaggableForm from django import forms
from taggit.tests.models import Food from taggit.tests.models import Food
class FoodForm(TaggableForm): class FoodForm(forms.ModelForm):
class Meta: class Meta:
model = Food model = Food
...@@ -7,8 +7,7 @@ from taggit.tests.models import Food, Pet ...@@ -7,8 +7,7 @@ from taggit.tests.models import Food, Pet
class BaseTaggingTest(TestCase): class BaseTaggingTest(TestCase):
def assert_tags_equal(self, qs, tags): def assert_tags_equal(self, qs, tags):
tags = Tag.objects.filter(name__in=tags) self.assertEqual(map(lambda tag: tag.name, qs), list(tags))
self.assertEqual(list(qs), list(tags))
class AddTagTestCase(BaseTaggingTest): class AddTagTestCase(BaseTaggingTest):
...@@ -65,6 +64,5 @@ class TaggableFormTestCase(BaseTaggingTest): ...@@ -65,6 +64,5 @@ class TaggableFormTestCase(BaseTaggingTest):
f = FoodForm({'name': 'apple', 'tags': 'green, red, yummy'}) f = FoodForm({'name': 'apple', 'tags': 'green, red, yummy'})
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'])
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