From 26cae002ecace4600aaca5461ee65bba8dcab6a7 Mon Sep 17 00:00:00 2001 From: Anthony Lukach Date: Fri, 16 Feb 2018 07:57:54 -0700 Subject: [PATCH] Rm custom __getitem__ method (#30) --- jsonattrs/fields.py | 20 ++------------------ jsonattrs/signals.py | 4 ++++ tests/test_field.py | 12 ++++++++++++ 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/jsonattrs/fields.py b/jsonattrs/fields.py index 28f83950..23e6c4d5 100644 --- a/jsonattrs/fields.py +++ b/jsonattrs/fields.py @@ -67,7 +67,8 @@ def setup_schema(self, schemas=None): def _pre_save_selector_check(self, strict=False): if not self._setup: - self.setup_from_dict(self._db_val) + self.setup_from_dict(self._db_val if self._instance._state.adding + else self._get_from_instance()) old_selectors = self._saved_selectors new_selectors = Schema.objects._get_selectors(self._instance) self._saved_selectors = new_selectors @@ -127,12 +128,6 @@ def _check_key(self, key): if key not in self._attrs and key not in self: raise KeyError(key) - def __getitem__(self, key): - if not self._setup: - self.setup_from_dict(self._db_val) - self._check_key(key) - return super().__getitem__(key) - def __setitem__(self, key, value): if self._init_done: self._check_key(key) @@ -204,14 +199,3 @@ def get_prep_lookup(self, lookup_type, value): return (Json(dict(value), dumps=json_serialiser) if isinstance(value, dict) else super().get_prep_lookup(lookup_type, value)) - - # def validate(self, value, model_instance): - # super(JSONField, self).validate(value, model_instance) - # try: - # json.dumps(dict(value)) - # except TypeError: - # raise exceptions.ValidationError( - # self.error_messages['invalid'], - # code='invalid', - # params={'value': value}, - # ) diff --git a/jsonattrs/signals.py b/jsonattrs/signals.py index 1898b2f8..554e1600 100644 --- a/jsonattrs/signals.py +++ b/jsonattrs/signals.py @@ -1,3 +1,5 @@ +import functools + from django.core.exceptions import FieldError from .fields import JSONAttributes, JSONAttributeField @@ -31,6 +33,8 @@ def fixup_instance(sender, **kwargs): # Cache model instance on JSONAttributes instance and vice-versa attrs._instance = instance + attrs._get_from_instance = functools.partial( + getattr, instance, field_name) instance._attr_field = attrs if not hasattr(instance, '_attr_field'): diff --git a/tests/test_field.py b/tests/test_field.py index 700c2532..f604a328 100644 --- a/tests/test_field.py +++ b/tests/test_field.py @@ -4,6 +4,7 @@ from django.test import TestCase from django.core.exceptions import ValidationError +from .factories import OrganizationFactory from .fixtures import create_fixtures from .models import Organization, Project, Party, Parcel from jsonattrs.fields import convert @@ -187,6 +188,17 @@ def test_attributes_lookup_dict(self): assert Party.objects.count() == 45 assert Party.objects.filter(attrs={'homeowner': 'False'}).count() == 5 + def test_cast_to_dict_with_unknown_attr(self): + """ + Ensure that data with unknown attributes can still be cast to dict. + This is used by DRF's JSONRenderer to render models with a + JSONAttribute field to JSON. + """ + prj = Organization.objects.bulk_create([ # Skip validation on create + OrganizationFactory.build(attrs={'foo': 'bar'}) + ])[0] + assert dict(prj.attrs) == {'foo': 'bar'} + class FieldDbTest(FieldTestBase): def test_check_fixtures(self):