Ticket #25172: multi_db_checks.diff

File multi_db_checks.diff, 6.0 KB (added by Ion Scerbatiuc, 9 years ago)

Fix the issue and add regression tests

  • django/db/models/fields/__init__.py

    diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
    index fe5ff67..0dee058 100644
    a b from django.core import checks, exceptions, validators  
    1919# django.core.exceptions. It is retained here for backwards compatibility
    2020# purposes.
    2121from django.core.exceptions import FieldDoesNotExist  # NOQA
    22 from django.db import connection
     22from django.db import connection, connections, router
    2323from django.db.models.lookups import (
    2424    Lookup, RegisterLookupMixin, Transform, default_lookups,
    2525)
    class Field(RegisterLookupMixin):  
    315315            return []
    316316
    317317    def _check_backend_specific_checks(self, **kwargs):
    318         return connection.validation.check_field(self, **kwargs)
     318        app_label = self.model._meta.app_label
     319        for db in connections:
     320            if router.allow_migrate(db, app_label, model=self.model):
     321                return connections[db].validation.check_field(self, **kwargs)
    319322
    320323    def _check_deprecation_details(self):
    321324        if self.system_check_removed_details is not None:
  • new file tests/check_framework/test_multi_db.py

    diff --git a/tests/check_framework/test_multi_db.py b/tests/check_framework/test_multi_db.py
    new file mode 100644
    index 0000000..38f73db
    - +  
     1from django.db import connections, models
     2from django.test import TestCase, mock
     3from django.test.utils import override_settings
     4
     5from .tests import IsolateModelsMixin
     6
     7
     8class TestRouter(object):
     9    """
     10    Dummy router that would route to the 'other' database
     11    if the model name starts with 'Other'.
     12    """
     13    def db_for_read(self, model, **hints):
     14        return self._route(model)
     15
     16    def db_for_write(self, model, **hints):
     17        return self._route(model)
     18
     19    def allow_relation(self, obj1, obj2, **hints):
     20        return obj1._state.db == obj2._state.db
     21
     22    def allow_migrate(self, db, app_label, **hints):
     23        model = hints.get('model')
     24        return db == self._route(model)
     25
     26    def _route(self, model):
     27        if model._meta.verbose_name.startswith('other'):
     28            return 'other'
     29
     30        return 'default'
     31
     32
     33@override_settings(DATABASE_ROUTERS=[TestRouter()])
     34class TestMultiDBChecks(IsolateModelsMixin, TestCase):
     35    multi_db = True
     36
     37    def test_checks_called_on_the_default_database(self):
     38        class Model(models.Model):
     39            field = models.CharField(max_length=100)
     40
     41        model = Model()
     42        with mock.patch.object(connections['default'].validation, 'check_field') as mock_check_field:
     43            model.check()
     44            self.assertTrue(mock_check_field.called)
     45
     46    def test_checks_called_on_the_other_database(self):
     47        class OtherModel(models.Model):
     48            field = models.CharField(max_length=100)
     49
     50        model = OtherModel()
     51        with mock.patch.object(connections['other'].validation, 'check_field') as mock_check_field:
     52            model.check()
     53            self.assertTrue(mock_check_field.called)
  • tests/invalid_models_tests/test_backend_specific.py

    diff --git a/tests/invalid_models_tests/test_backend_specific.py b/tests/invalid_models_tests/test_backend_specific.py
    index 2d3ea7e..71bc629 100644
    a b from types import MethodType  
    55
    66from django.core.checks import Error
    77from django.db import connection, models
     8from django.test import mock
    89
    910from .base import IsolatedModelsTestCase
    1011
    1112
     13def dummy_allow_migrate(db, app_label, **hints):
     14    # Only allow_migrate on default so we can mock the check_field
     15    # on the proper validation instance
     16    return db == 'default'
     17
     18
    1219class BackendSpecificChecksTests(IsolatedModelsTestCase):
    1320
     21    @mock.patch('django.db.models.fields.router.allow_migrate',
     22                new=dummy_allow_migrate)
    1423    def test_check_field(self):
    1524        """ Test if backend specific checks are performed. """
    1625
    1726        error = Error('an error', hint=None)
    1827
    19         def mock(self, field, **kwargs):
     28        def mock_check_field(self, field, **kwargs):
    2029            return [error]
    2130
    2231        class Model(models.Model):
    class BackendSpecificChecksTests(IsolatedModelsTestCase):  
    2736        # Mock connection.validation.check_field method.
    2837        v = connection.validation
    2938        old_check_field = v.check_field
    30         v.check_field = MethodType(mock, v)
     39        v.check_field = MethodType(mock_check_field, v)
    3140        try:
    3241            errors = field.check()
    3342        finally:
  • tests/postgres_tests/test_array.py

    diff --git a/tests/postgres_tests/test_array.py b/tests/postgres_tests/test_array.py
    index 0a41bf1..626a879 100644
    a b from . import PostgreSQLTestCase  
    1414from .models import (
    1515    ArrayFieldSubclass, CharArrayModel, DateTimeArrayModel, IntegerArrayModel,
    1616    NestedIntegerArrayModel, NullableIntegerArrayModel, OtherTypesArrayModel,
     17    PostgreSQLModel,
    1718)
    1819
    1920try:
    class TestQuerying(PostgreSQLTestCase):  
    246247class TestChecks(PostgreSQLTestCase):
    247248
    248249    def test_field_checks(self):
    249         field = ArrayField(models.CharField())
    250         field.set_attributes_from_name('field')
    251         errors = field.check()
     250        class MyModel(PostgreSQLModel):
     251            field = ArrayField(models.CharField())
     252
     253        model = MyModel()
     254        errors = model.check()
    252255        self.assertEqual(len(errors), 1)
    253256        self.assertEqual(errors[0].id, 'postgres.E001')
    254257
    255258    def test_invalid_base_fields(self):
    256         field = ArrayField(models.ManyToManyField('postgres_tests.IntegerArrayModel'))
    257         field.set_attributes_from_name('field')
    258         errors = field.check()
     259        class MyModel(PostgreSQLModel):
     260            field = ArrayField(models.ManyToManyField('postgres_tests.IntegerArrayModel'))
     261
     262        model = MyModel()
     263        errors = model.check()
    259264        self.assertEqual(len(errors), 1)
    260265        self.assertEqual(errors[0].id, 'postgres.E002')
    261266
Back to Top