Code

Ticket #20098: 20098.2.patch

File 20098.2.patch, 3.6 KB (added by carsten.klein@…, 16 months ago)

Correct handling of unmanaged models and duplicate db_table declaration

  • django/db/models/options.py

    diff --git a/django/db/models/options.py b/django/db/models/options.py
    index d471bba..284a67d 100644
    a b DEFAULT_NAMES = ('verbose_name', 'verbose_name_plural', 'db_table', 'ordering', 
    2323                 'order_with_respect_to', 'app_label', 'db_tablespace', 
    2424                 'abstract', 'managed', 'proxy', 'swappable', 'auto_created') 
    2525 
     26# Lookup table for table names introduced in order to prevent that users from declaring the same table twice 
     27db_table_lookup = {} 
     28 
    2629 
    2730@python_2_unicode_compatible 
    2831class Options(object): 
    class Options(object): 
    121124            self.db_table = "%s_%s" % (self.app_label, self.module_name) 
    122125            self.db_table = truncate_name(self.db_table, connection.ops.max_name_length()) 
    123126 
     127        # Prevent users from declaring the same table twice, ISSUE #20098 
     128        if self.managed: 
     129            qname = '%s.%s' % (cls.__module__, cls.__name__) 
     130            if self.db_table in db_table_lookup: 
     131 
     132                raise Exception('db_table "%s" was already declared by "%s" and was redeclared by "%s".' 
     133                                % (self.db_table, db_table_lookup[self.db_table], qname)) 
     134 
     135            db_table_lookup[self.db_table] = qname 
     136 
    124137    def _prepare(self, model): 
    125138        if self.order_with_respect_to: 
    126139            self.order_with_respect_to = self.get_field(self.order_with_respect_to) 
  • tests/regressiontests/admin_scripts/tests.py

    diff --git a/tests/regressiontests/admin_scripts/tests.py b/tests/regressiontests/admin_scripts/tests.py
    index 3bb8bb0..82a512a 100644
    a b class ManageValidate(AdminScriptTestCase): 
    10691069        self.assertNoOutput(err) 
    10701070        self.assertOutput(out, '0 errors found') 
    10711071 
     1072    def test_unmanaged_duplicate_db_table_declaration(self): 
     1073        """ISSUE #20098 
     1074        manage.py validate must not not raise errors when a project or an app 
     1075        declares the same db_table twice using unmanaged model classes. 
     1076        """ 
     1077        self.write_settings('settings.py', 
     1078            apps=['admin_scripts.unmanaged_duplicate_db_table_declaration'], 
     1079            sdict={'DEBUG': True} 
     1080        ) 
     1081        args = ['validate'] 
     1082        out, err = self.run_manage(args) 
     1083        self.assertNoOutput(err) 
     1084        self.assertOutput(out, '0 errors found') 
     1085 
     1086    def test_duplicate_db_table_declaration_single_app(self): 
     1087        """ISSUE #20098 
     1088        manage.py validate does not raise errors when a project or an app 
     1089        declares the same db_table twice or multiple times for different models 
     1090        declared by a single app. 
     1091        """ 
     1092        self.write_settings('settings.py', 
     1093            apps=['admin_scripts.duplicate_db_table_declaration_single_app'], 
     1094            sdict={'DEBUG': True} 
     1095        ) 
     1096        args = ['validate'] 
     1097        out, err = self.run_manage(args) 
     1098        self.assertOutput(err, 'was redeclared') 
     1099 
     1100    def test_duplicate_db_table_declaration_multiple_app(self): 
     1101        """ISSUE #20098 
     1102        manage.py validate does not raise errors when a project or an app 
     1103        declares the same db_table twice or multiple times for different models 
     1104        declared by different apps. 
     1105        """ 
     1106        self.write_settings('settings.py', 
     1107            apps=['admin_scripts.duplicate_db_table_declaration_multiple_app.app1', 
     1108                  'admin_scripts.duplicate_db_table_declaration_multiple_app.app2'], 
     1109            sdict={'DEBUG': True} 
     1110        ) 
     1111        args = ['validate'] 
     1112        out, err = self.run_manage(args) 
     1113        self.assertOutput(err, 'was redeclared') 
     1114 
    10721115 
    10731116class CustomTestRunner(DjangoTestSuiteRunner): 
    10741117