Răsfoiți Sursa

Used a database feature to prevent the jsonb test model from being migrated.

Thanks Tim for the review.
Simon Charette 8 ani în urmă
părinte
comite
32c0d823e5

+ 4 - 0
django/db/backends/postgresql/features.py

@@ -36,3 +36,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
     @cached_property
     def has_select_for_update_skip_locked(self):
         return self.connection.pg_version >= 90500
+
+    @cached_property
+    def has_jsonb_datatype(self):
+        return self.connection.pg_version >= 90400

+ 1 - 13
tests/postgres_tests/migrations/0002_create_test_models.py

@@ -216,9 +216,6 @@ class Migration(migrations.Migration):
             },
             bases=(models.Model,),
         ),
-    ]
-
-    pg_94_operations = [
         migrations.CreateModel(
             name='JSONModel',
             fields=[
@@ -227,17 +224,8 @@ class Migration(migrations.Migration):
                 ('field_custom', JSONField(null=True, blank=True, encoder=DjangoJSONEncoder)),
             ],
             options={
+                'required_db_features': {'has_jsonb_datatype'},
             },
             bases=(models.Model,),
         ),
     ]
-
-    def apply(self, project_state, schema_editor, collect_sql=False):
-        try:
-            PG_VERSION = schema_editor.connection.pg_version
-        except AttributeError:
-            pass  # We are probably not on PostgreSQL
-        else:
-            if PG_VERSION >= 90400:
-                self.operations = self.operations + self.pg_94_operations
-        return super(Migration, self).apply(project_state, schema_editor, collect_sql)

+ 7 - 10
tests/postgres_tests/models.py

@@ -1,5 +1,5 @@
 from django.core.serializers.json import DjangoJSONEncoder
-from django.db import connection, models
+from django.db import models
 
 from .fields import (
     ArrayField, BigIntegerRangeField, DateRangeField, DateTimeRangeField,
@@ -129,15 +129,12 @@ class RangeLookupsModel(PostgreSQLModel):
     date = models.DateField(blank=True, null=True)
 
 
-# Only create this model for postgres >= 9.4
-if connection.vendor == 'postgresql' and connection.pg_version >= 90400:
-    class JSONModel(models.Model):
-        field = JSONField(blank=True, null=True)
-        field_custom = JSONField(blank=True, null=True, encoder=DjangoJSONEncoder)
-else:
-    # create an object with this name so we don't have failing imports
-    class JSONModel(object):
-        pass
+class JSONModel(models.Model):
+    field = JSONField(blank=True, null=True)
+    field_custom = JSONField(blank=True, null=True, encoder=DjangoJSONEncoder)
+
+    class Meta:
+        required_db_features = ['has_jsonb_datatype']
 
 
 class ArrayFieldSubclass(ArrayField):

+ 7 - 19
tests/postgres_tests/test_json.py

@@ -1,15 +1,13 @@
 from __future__ import unicode_literals
 
 import datetime
-import unittest
 import uuid
 from decimal import Decimal
 
 from django.core import exceptions, serializers
 from django.core.serializers.json import DjangoJSONEncoder
-from django.db import connection
 from django.forms import CharField, Form, widgets
-from django.test import TestCase
+from django.test import skipUnlessDBFeature
 from django.utils.html import escape
 
 from . import PostgreSQLTestCase
@@ -22,18 +20,8 @@ except ImportError:
     pass
 
 
-def skipUnlessPG94(test):
-    try:
-        PG_VERSION = connection.pg_version
-    except AttributeError:
-        PG_VERSION = 0
-    if PG_VERSION < 90400:
-        return unittest.skip('PostgreSQL >= 9.4 required')(test)
-    return test
-
-
-@skipUnlessPG94
-class TestSaveLoad(TestCase):
+@skipUnlessDBFeature('has_jsonb_datatype')
+class TestSaveLoad(PostgreSQLTestCase):
     def test_null(self):
         instance = JSONModel()
         instance.save()
@@ -106,8 +94,8 @@ class TestSaveLoad(TestCase):
         self.assertEqual(loaded.field_custom, obj_after)
 
 
-@skipUnlessPG94
-class TestQuerying(TestCase):
+@skipUnlessDBFeature('has_jsonb_datatype')
+class TestQuerying(PostgreSQLTestCase):
     @classmethod
     def setUpTestData(cls):
         cls.objs = [
@@ -250,8 +238,8 @@ class TestQuerying(TestCase):
         )
 
 
-@skipUnlessPG94
-class TestSerialization(TestCase):
+@skipUnlessDBFeature('has_jsonb_datatype')
+class TestSerialization(PostgreSQLTestCase):
     test_data = (
         '[{"fields": {"field": {"a": "b", "c": null}, "field_custom": null}, '
         '"model": "postgres_tests.jsonmodel", "pk": null}]'