Skip to content

Commit

Permalink
Fix form field has_changed
Browse files Browse the repository at this point in the history
refs #185
  • Loading branch information
radiac committed Aug 15, 2024
1 parent 0cba987 commit 5133f81
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 41 deletions.
13 changes: 13 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,19 @@ Changes for upcoming releases will be listed without a release date - these
are available by installing the develop branch from github.


2.1.0, TBC
----------

Bugfix:

* Form field ``has_changed`` now correctly detects if a TagField has changed (#185)

Thanks to:

* Christian Schneider (cnschn) for help fixing ``has_changed`` (#185)



2.0.0, 2024-08-13
-----------------

Expand Down
13 changes: 13 additions & 0 deletions tagulous/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

from . import settings
from .models import options
from .models.fields import FakeQuerySet
from .models.models import BaseTagModel, TagModelQuerySet
from .utils import parse_tags, render_tags

Expand Down Expand Up @@ -324,6 +325,18 @@ def prepare_value(self, value):
# Deal with it as normal
return super(TagField, self).prepare_value(value)

def _coerce(self, value):
"""
Standardise the value - it could be a fake queryset from the database object, or
a tag string from the form field. Split and sort the tags.
"""
if isinstance(value, FakeQuerySet):
tag_string = value[0]
else:
tag_string = value
tags = parse_tags(tag_string)
return render_tags(sorted(tags))


# ##############################################################################
# ###### Inline tagged formset
Expand Down
81 changes: 41 additions & 40 deletions tagulous/models/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,47 @@ def formfield(self, form_class=None, **kwargs):
# ##############################################################################


class FakeObject(object):
"""
FakeObject so m2d can check obj.pk
"""

def __init__(self, value):
self.pk = value

def __str__(self):
return self.pk


class FakeQuerySet(object):
"""
FakeQuerySet so m2d can call qs.values_list()
Only contains one FakeObject instance
"""

def __init__(self, obj):
self.obj = obj
self._result_cache = None

def __iter__(self):
"""
Iterable so m2d can use in list comprehension
"""
yield self.obj

def __len__(self):
return 1

def __getitem__(self, key):
return self.obj

def values_list(self, *fields, **kwargs):
"""
Ignores arguments and returns an empty list with the object.pk
"""
return [self.obj.pk]


class TagField(BaseTagField, models.ManyToManyField):
"""
Build the tag model and register the TagManyToManyField
Expand Down Expand Up @@ -464,46 +505,6 @@ def value_from_object(self, obj):
where the pk attribute is the tag string - a bit of a hack, but avoids
monkey-patching Django.
"""

class FakeObject(object):
"""
FakeObject so m2d can check obj.pk
"""

def __init__(self, value):
self.pk = value

def __str__(self):
return self.pk

class FakeQuerySet(object):
"""
FakeQuerySet so m2d can call qs.values_list()
Only contains one FakeObject instance
"""

def __init__(self, obj):
self.obj = obj
self._result_cache = None

def __iter__(self):
"""
Iterable so m2d can use in list comprehension
"""
yield self.obj

def __len__(self):
return 1

def __getitem__(self, key):
return self.obj

def values_list(self, *fields, **kwargs):
"""
Ignores arguments and returns an empty list with the object.pk
"""
return [self.obj.pk]

return FakeQuerySet(FakeObject(getattr(obj, self.attname).get_tag_string()))

def formfield(self, form_class=None, **kwargs):
Expand Down
2 changes: 1 addition & 1 deletion tagulous/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# ##############################################################################


def parse_tags(tag_string, max_count=0, space_delimiter=True):
def parse_tags(tag_string: str, max_count=0, space_delimiter=True) -> list[str]:
"""
Tag parser
Expand Down

0 comments on commit 5133f81

Please sign in to comment.