Skip to content

Commit

Permalink
Adding TagField.has_changed method
Browse files Browse the repository at this point in the history
  • Loading branch information
gassan authored and jdufresne committed Feb 23, 2019
1 parent 558cc2c commit fa36187
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 5 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
Changelog
=========

UNRELEASED
----------
* Added ``has_changed()`` method to ``taggit.forms.TagField``.

0.24.0 (2019-02-19)
~~~~~~~~~~~~~~~~~~~
* The project has moved to `Jazzband <https://jazzband.co/>`_. This is the
Expand Down
11 changes: 10 additions & 1 deletion taggit/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
class TagWidget(forms.TextInput):
def format_value(self, value):
if value is not None and not isinstance(value, six.string_types):
value = edit_string_for_tags([o.tag for o in value.select_related("tag")])
value = edit_string_for_tags(value)

return super(TagWidget, self).format_value(value)

Expand All @@ -26,3 +26,12 @@ def clean(self, value):
raise forms.ValidationError(
_("Please provide a comma-separated list of tags.")
)

def has_changed(self, initial_value, data_value):
initial_value = [tag.name for tag in initial_value]
initial_value.sort()
try:
data_value = self.clean(data_value)
except forms.ValidationError:
pass
return initial_value != data_value
11 changes: 7 additions & 4 deletions taggit/managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -531,10 +531,13 @@ def formfield(self, form_class=TagField, **kwargs):
defaults.update(kwargs)
return form_class(**defaults)

def value_from_object(self, instance):
if instance.pk:
return self.through.objects.filter(**self.through.lookup_kwargs(instance))
return self.through.objects.none()
def value_from_object(self, obj):
if obj.pk is None:
return []
qs = self.through.objects.select_related("tag").filter(
**self.through.lookup_kwargs(obj)
)
return [ti.tag for ti in qs]

def related_query_name(self):
return self.model._meta.model_name
Expand Down
61 changes: 61 additions & 0 deletions tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -885,6 +885,67 @@ def test_formfield(self):
ff = tm.formfield()
self.assertRaises(ValidationError, ff.clean, "")

def test_form_changed_data(self):
# new food, blank tag
pear = self.food_model()
request = {"name": "pear", "tags": ""}
fff = self.form_class(request, instance=pear)
self.assertFalse(fff.is_valid())

pear = self.food_model()
request = {"name": "pear", "tags": "sweat"}
fff = self.form_class(request, instance=pear)
self.assertTrue(fff.is_valid())
self.assertIn("tags", fff.changed_data)
self.assertIn("name", fff.changed_data)
fff.save()

request = {"name": "pear", "tags": "yellow"}
fff = self.form_class(request, instance=pear)
self.assertTrue(fff.is_valid())
self.assertIn("tags", fff.changed_data)
self.assertNotIn("name", fff.changed_data)
fff.save()

# same object nothing changed
fff = self.form_class(request, instance=pear)
self.assertTrue(fff.is_valid())
self.assertFalse(fff.changed_data)

# delete tag
request = {"name": "pear", "tags": ""}
fff = self.form_class(request, instance=pear)
self.assertFalse(fff.is_valid()) # tag not blank

# change name, tags are the same
request = {"name": "apple", "tags": "yellow"}
fff = self.form_class(request, instance=pear)
self.assertTrue(fff.is_valid())
self.assertIn("name", fff.changed_data)
self.assertNotIn("tags", fff.changed_data)
fff.save()

# tags changed
apple = self.food_model.objects.get(name="apple")
request = {"name": "apple", "tags": "yellow, delicious"}
fff = self.form_class(request, instance=apple)
self.assertTrue(fff.is_valid())
self.assertNotIn("name", fff.changed_data)
self.assertIn("tags", fff.changed_data)
fff.save()

# only tags order changed
apple = self.food_model.objects.get(name="apple")
request = {"name": "apple", "tags": "delicious, yellow"}
fff = self.form_class(request, instance=apple)
self.assertTrue(fff.is_valid())
self.assertFalse(fff.changed_data)

# and nothing changed
fff = self.form_class(request, instance=apple)
self.assertTrue(fff.is_valid())
self.assertFalse(fff.changed_data)


class TaggableFormDirectTestCase(TaggableFormTestCase):
form_class = DirectFoodForm
Expand Down

0 comments on commit fa36187

Please sign in to comment.