From 0cbb6ac00770d201b8f30a404d516b97fe41485d Mon Sep 17 00:00:00 2001 From: Claude Paroz Date: Sat, 9 Sep 2017 14:39:09 +0200 Subject: [PATCH] Refs #24928 -- Added introspection support for PostgreSQL JSONField Thanks Adam Johnson and Tim Graham for the reviews. --- django/contrib/postgres/apps.py | 8 +++++-- docs/ref/django-admin.txt | 4 +++- docs/releases/2.0.txt | 3 +++ tests/postgres_tests/test_introspection.py | 26 ++++++++++++++++++++++ 4 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 tests/postgres_tests/test_introspection.py diff --git a/django/contrib/postgres/apps.py b/django/contrib/postgres/apps.py index f298814f7dd..2ad6aaefc80 100644 --- a/django/contrib/postgres/apps.py +++ b/django/contrib/postgres/apps.py @@ -15,8 +15,12 @@ class PostgresConfig(AppConfig): def ready(self): # Connections may already exist before we are called. for conn in connections.all(): - if conn.connection is not None: - register_type_handlers(conn) + if conn.vendor == 'postgresql': + conn.introspection.data_types_reverse.update({ + 3802: 'django.contrib.postgresql.fields.JSONField', + }) + if conn.connection is not None: + register_type_handlers(conn) connection_created.connect(register_type_handlers) CharField.register_lookup(Unaccent) TextField.register_lookup(Unaccent) diff --git a/docs/ref/django-admin.txt b/docs/ref/django-admin.txt index 3a83bd2b7d6..7c8ac294739 100644 --- a/docs/ref/django-admin.txt +++ b/docs/ref/django-admin.txt @@ -366,7 +366,9 @@ output: * If ``inspectdb`` cannot map a column's type to a model field type, it'll use ``TextField`` and will insert the Python comment ``'This field type is a guess.'`` next to the field in the generated - model. + model. The recognized fields may depend on apps listed in + :setting:`INSTALLED_APPS`. For example, :mod:`django.contrib.postgres` adds + recognition for several PostgreSQL-specific field types. * If the database column name is a Python reserved word (such as ``'pass'``, ``'class'`` or ``'for'``), ``inspectdb`` will append diff --git a/docs/releases/2.0.txt b/docs/releases/2.0.txt index 7b2df87fcf0..46ff112dba1 100644 --- a/docs/releases/2.0.txt +++ b/docs/releases/2.0.txt @@ -123,6 +123,9 @@ Minor features operation installs the ``btree_gist`` extension to add support for operator classes that aren't built-in. +* :djadmin:`inspectdb` can now introspect ``JSONField`` + (``django.contrib.postgres`` must be in ``INSTALLED_APPS``). + :mod:`django.contrib.redirects` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/tests/postgres_tests/test_introspection.py b/tests/postgres_tests/test_introspection.py new file mode 100644 index 00000000000..1058a1656b6 --- /dev/null +++ b/tests/postgres_tests/test_introspection.py @@ -0,0 +1,26 @@ +from io import StringIO + +from django.core.management import call_command +from django.test.utils import modify_settings + +from . import PostgreSQLTestCase + + +@modify_settings(INSTALLED_APPS={'append': 'django.contrib.postgres'}) +class InspectDBTests(PostgreSQLTestCase): + def assertFieldsInModel(self, model, field_outputs): + out = StringIO() + call_command( + 'inspectdb', + table_name_filter=lambda tn: tn.startswith(model), + stdout=out, + ) + output = out.getvalue() + for field_output in field_outputs: + self.assertIn(field_output, output) + + def test_json_field(self): + self.assertFieldsInModel( + 'postgres_tests_jsonmodel', + ['field = django.contrib.postgresql.fields.JSONField(blank=True, null=True)'], + )