Skip to content

Commit 75901a0

Browse files
author
Andrey Antukh
committedApr 17, 2014
Major refactor from djorm-ext-pgjson
1 parent 11e3b04 commit 75901a0

20 files changed

+147
-644
lines changed
 

‎CHANGES.txt

-16
Original file line numberDiff line numberDiff line change
@@ -1,17 +1 @@
1-
Changelog
2-
=========
31

4-
Version 0.3
5-
-----------
6-
7-
- Minor fixes.
8-
9-
Version 0.2
10-
-----------
11-
12-
- Fix wrong handling the default value.
13-
14-
Version 0.1
15-
-----------
16-
17-
- Initial version

‎LICENSE

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Copyright (c) 2013 Andrey Antukh <niwi@niwi.be>
1+
Copyright (c) 2014 Andrey Antukh <niwi@niwi.be>
22

33
All rights reserved.
44

‎README.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# djorm-ext-pgjson
2+
3+
PostgreSQL json support for Django.

‎README.rst

-6
This file was deleted.
File renamed without changes.

‎django_pgjson/fields.py

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# -*- coding: utf-8 -*-
2+
3+
import json
4+
import re
5+
import django
6+
7+
from django.db.backends.postgresql_psycopg2.version import get_version
8+
from django.core.serializers.json import DjangoJSONEncoder
9+
from django.db import models
10+
from django import forms
11+
from django.utils import six
12+
13+
import psycopg2
14+
import psycopg2.extensions
15+
import psycopg2.extras
16+
17+
18+
class JsonAdapter(psycopg2.extras.Json):
19+
def dumps(self, obj):
20+
return json.dumps(obj, cls=DjangoJSONEncoder)
21+
22+
23+
psycopg2.extensions.register_adapter(dict, JsonAdapter)
24+
psycopg2.extras.register_default_json(loads=json.loads)
25+
26+
27+
class JsonField(six.with_metaclass(models.SubfieldBase, models.Field)):
28+
def db_type(self, connection):
29+
if get_version(connection) < 90200:
30+
raise RuntimeError("django_pgjson does not supports postgresql version < 9.2")
31+
return "json"
32+
33+
def value_to_string(self, obj):
34+
value = self._get_val_from_obj(obj)
35+
return json.dumps(self.get_prep_value(value), cls=DjangoJSONEncoder)
36+
37+
def formfield(self, **kwargs):
38+
defaults = {'form_class': JsonFormField}
39+
defaults.update(kwargs)
40+
return super(JsonField, self).formfield(**defaults)
41+
42+
# if django.get_version() >= '1.7':
43+
# def get_transform(self, name):
44+
# from .lookups import KeyTransformFactory
45+
# transform = super(JsonField, self).get_transform(name)
46+
# if transform:
47+
# return transform
48+
# if not re.match("field_\w+", name):
49+
# return None
50+
# _, key = name.rsplit("_", 1)
51+
# return KeyTransformFactory(key, self)
52+
53+
54+
class JsonFormField(forms.CharField):
55+
widget = forms.Textarea
56+
57+
def prepare_value(self, value):
58+
if isinstance(value, six.string_types):
59+
return value
60+
return json.dumps(value, cls=DjangoJSONEncoder)
61+
62+
63+
# South compatibility
64+
try:
65+
from south.modelsinspector import add_introspection_rules
66+
add_introspection_rules([(
67+
(JSONField,),
68+
[],
69+
{
70+
'blank': ['blank', { 'default': True }],
71+
'null': ['null', { 'default': True }],
72+
},
73+
)], (r'^django_pgjson\.fields\.JsonField',))
74+
except ImportError:
75+
pass

‎django_pgjson/lookups.py

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# -*- coding: utf-8 -*-
2+
3+
from django.utils.functional import cached_property
4+
from django.db.models import Transform
5+
6+
7+
class KeyTransform(Transform):
8+
def __init__(self, key, base_field, *args, **kwargs):
9+
super(KeyTransform, self).__init__(*args, **kwargs)
10+
self.key = key
11+
self.base_field = base_field
12+
13+
def as_sql(self, qn, connection):
14+
lhs, params = qn.compile(self.lhs)
15+
import pdb; pdb.set_trace()
16+
17+
return "%s->>'%s'" % (lhs, self.key), params
18+
19+
@cached_property
20+
def output_type(self):
21+
return self.base_field
22+
23+
24+
class KeyTransformFactory(object):
25+
def __init__(self, key, base_field):
26+
self.key = key
27+
self.base_field = base_field
28+
29+
def __call__(self, *args, **kwargs):
30+
return KeyTransform(self.key, self.base_field, *args, **kwargs)
31+

‎djorm_pgjson/fields.py

-75
This file was deleted.

‎docs/Makefile

-177
This file was deleted.

‎docs/conf.py

-249
This file was deleted.

‎docs/index.rst

-66
This file was deleted.

‎runtests.py

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# -*- coding: utf-8 -*-
2+
3+
import os, sys
4+
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
5+
sys.path.insert(0, 'tests')
6+
7+
if __name__ == "__main__":
8+
from django.core.management import execute_from_command_line
9+
args = sys.argv
10+
args.insert(1, "test")
11+
12+
execute_from_command_line(args)

‎setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"""
66

77
setup(
8-
name = "djorm-ext-pgjson",
8+
name = "django-pgjson",
99
version = '0.3',
1010
url = 'https://github.com/niwibe/djorm-ext-pgjson',
1111
license = 'BSD',

‎testing/pg_json_fields/models.py

-10
This file was deleted.

‎testing/runtests.py

-10
This file was deleted.
File renamed without changes.
File renamed without changes.

‎tests/pg_json_fields/models.py

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# -*- coding: utf-8 -*-
2+
3+
from django.db import models
4+
from django_pgjson.fields import JsonField
5+
6+
7+
class TextModel(models.Model):
8+
data = JsonField()

‎testing/pg_json_fields/tests.py ‎tests/pg_json_fields/tests.py

+16-32
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
# -*- coding: utf-8 -*-
22

3+
from __future__ import unicode_literals
4+
35
from django.contrib.admin import AdminSite, ModelAdmin
46

57
from django.test import TestCase
68
from django.core.serializers import serialize, deserialize
7-
8-
from djorm_expressions.base import SqlExpression
9-
from djorm_pgjson.fields import JSONField
9+
from django_pgjson.fields import JsonField
1010

1111
from .models import TextModel
1212

1313

14-
class JSONFieldTests(TestCase):
14+
class JsonFieldTests(TestCase):
1515
def setUp(self):
1616
TextModel.objects.all().delete()
1717

@@ -21,38 +21,20 @@ def test_empty_create(self):
2121
self.assertEqual(instance.data, {})
2222

2323
def test_unicode(self):
24-
obj = TextModel.objects.create(data=[u"Fóö", u"Пример", u"test"])
25-
obj = TextModel.objects.get(pk=obj.pk)
26-
27-
self.assertEqual(obj.data[1], u"Пример")
28-
29-
def test_correct_behavior_with_text(self):
30-
obj = TextModel.objects.create(data="hello")
24+
obj = TextModel.objects.create(data={"list": ["Fóö", "Пример", "test"]})
3125
obj = TextModel.objects.get(pk=obj.pk)
32-
self.assertEqual(obj.data, "hello")
3326

34-
def test_correct_behavior_with_bool(self):
35-
obj = TextModel.objects.create(data=True)
36-
obj = TextModel.objects.get(pk=obj.pk)
37-
self.assertEqual(obj.data, True)
27+
self.assertEqual(obj.data["list"][1], "Пример")
3828

39-
def test_correct_behavior_with_int(self):
40-
obj = TextModel.objects.create(data=1)
41-
obj = TextModel.objects.get(pk=obj.pk)
42-
self.assertEqual(obj.data, 1)
29+
# def test_key_lookup(self):
30+
# obj1 = TextModel.objects.create(data={"name": "foo"})
31+
# obj2 = TextModel.objects.create(data={"name": "bar"})
4332

44-
def test_correct_behavior_with_float_01(self):
45-
obj = TextModel.objects.create(data=1.4)
46-
obj = TextModel.objects.get(pk=obj.pk)
47-
self.assertEqual(obj.data, 1.4)
48-
49-
def test_correct_behavior_with_float_02(self):
50-
obj = TextModel.objects.create(data=0.4)
51-
obj = TextModel.objects.get(pk=obj.pk)
52-
self.assertEqual(obj.data, 0.4)
33+
# qs = TextModel.objects.filter(data__field_name="foo")
34+
# self.assertEqual(qs.count(), 1)
5335

5436
def test_value_to_string_serializes_correctly(self):
55-
obj = TextModel.objects.create(data=[1,2,3])
37+
obj = TextModel.objects.create(data={"a": 1})
5638

5739
serialized_obj = serialize('json', TextModel.objects.filter(pk=obj.pk))
5840
obj.delete()
@@ -61,8 +43,9 @@ def test_value_to_string_serializes_correctly(self):
6143

6244
obj = deserialized_obj.object
6345
obj.save()
46+
obj = obj.__class__.objects.get(pk=obj.pk)
6447

65-
self.assertEqual(obj.data, [1,2,3])
48+
self.assertEqual(obj.data, {"a": 1})
6649

6750
def test_to_python_serializes_xml_correctly(self):
6851
obj = TextModel.objects.create(data={"a": 0.2})
@@ -74,11 +57,12 @@ def test_to_python_serializes_xml_correctly(self):
7457

7558
obj = deserialized_obj.object
7659
obj.save()
60+
obj = obj.__class__.objects.get(pk=obj.pk)
7761

7862
self.assertEqual(obj.data, {"a": 0.2})
7963

8064
def test_can_override_formfield(self):
81-
model_field = JSONField()
65+
model_field = JsonField()
8266
class FakeFieldClass(object):
8367
def __init__(self, *args, **kwargs):
8468
pass

‎testing/settings.py ‎tests/settings.py

-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import os, sys
22

33
sys.path.insert(0, '..')
4-
sys.path.insert(0, '/home/niwi/devel/djorm-ext-expressions')
54

65
PROJECT_ROOT = os.path.dirname(__file__)
76
DEBUG = True

0 commit comments

Comments
 (0)
Please sign in to comment.