Here's the minimal test case:
{{{
>>> from django.contrib.postgres.forms import JSONField
>>> JSONField().has_changed({'a': True}, '{"a": 1}')
False
}}}
Let me know if there's any other information you need.
Thanks.
--
Ticket URL: <https://code.djangoproject.com/ticket/28534>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* type: Uncategorized => Bug
--
Ticket URL: <https://code.djangoproject.com/ticket/28534#comment:1>
* stage: Unreviewed => Accepted
--
Ticket URL: <https://code.djangoproject.com/ticket/28534#comment:2>
* status: new => assigned
* owner: nobody => hui shang
--
Ticket URL: <https://code.djangoproject.com/ticket/28534#comment:3>
Comment (by john-parton):
Here's some information that might be helpful:
[https://stackoverflow.com/questions/45888263/strict-comparison-of-
dictionaries-in-python]
It looks like there's two approaches:
1. Convert both the old value and new value to some string representation
and compare them. (Either using json.dumps or pprint.pformat)
2. Recursively compare the values
I think (1) with json.dumps would probably work best. pprint.pformat was
suggested to handle objects that can't be json-serialized, but obviously
everything that can go into a JSONField can be json-serialized.
--
Ticket URL: <https://code.djangoproject.com/ticket/28534#comment:4>
* has_patch: 0 => 1
Comment:
[https://github.com/django/django/pull/8989#### PR]
Hi, @john-partonm, for (1), json.dumps works well, but I think str() is a
good choice too, so I use it.
--
Ticket URL: <https://code.djangoproject.com/ticket/28534#comment:5>
Comment (by john-parton):
Replying to [comment:5 hui shang]:
> [https://github.com/django/django/pull/8989#### PR]
>
> Hi, @john-partonm, for (1), json.dumps works well, but I think str() is
a good choice too, so I use it.
Does str() always sort dictionary keys? I'm not totally sure, but under
certain circumstances I think your fix might flag {'a': 1, 'b': 2} as
being different from {'b': 2, 'a': 1}.
Thanks for the quick response and your hard work!
--
Ticket URL: <https://code.djangoproject.com/ticket/28534#comment:6>
* needs_better_patch: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/28534#comment:7>
Comment (by hui shang):
Replying to [comment:6 john-parton]:
> Replying to [comment:5 hui shang]:
> > [https://github.com/django/django/pull/8989#### PR]
> >
> > Hi, @john-partonm, for (1), json.dumps works well, but I think str()
is a good choice too, so I use it.
>
> Does str() always sort dictionary keys? I'm not totally sure, but under
certain circumstances I think your fix might flag {'a': 1, 'b': 2} as
being different from {'b': 2, 'a': 1}.
>
> Thanks for the quick response and your hard work!
>
> EDIT:
>
> At least with Python3.6, the string representation of two dicts can
differ:
>
> {{{
> Python 3.6.1 (default, Dec 2015, 13:05:11)
> [GCC 4.8.2] on linux
> left = {}
> left['a'] = 1
> left['b'] = 2
> right = {}
> right['b'] = 2
> right['a'] = 1
> str(left) == str(right)
> => False
> }}}
Yes, you are right, thank you for the explanation. I have changed the
comparison from str() to json.dumps
--
Ticket URL: <https://code.djangoproject.com/ticket/28534#comment:8>
* needs_better_patch: 1 => 0
--
Ticket URL: <https://code.djangoproject.com/ticket/28534#comment:9>
* status: assigned => closed
* resolution: => fixed
Comment:
In [changeset:"1907fc9b1292a55f1b8d54f4dbcdbda16bbb36c1" 1907fc9b]:
{{{
#!CommitTicketReference repository=""
revision="1907fc9b1292a55f1b8d54f4dbcdbda16bbb36c1"
Fixed #28534 -- Made JSONField.has_changed() ignore key order and consider
True/1 values as different.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/28534#comment:10>