Fixed #23028: Added unique_togther support to inspectdb.
This commit is contained in:
parent
b8d255071e
commit
70c54a3694
|
@ -21,8 +21,8 @@ class Command(InspectDBCommand):
|
||||||
self.gis_tables[table_name] = [geo_col]
|
self.gis_tables[table_name] = [geo_col]
|
||||||
return field_type, field_params, field_notes
|
return field_type, field_params, field_notes
|
||||||
|
|
||||||
def get_meta(self, table_name):
|
def get_meta(self, table_name, constraints):
|
||||||
meta_lines = super(Command, self).get_meta(table_name)
|
meta_lines = super(Command, self).get_meta(table_name, constraints)
|
||||||
if table_name in self.gis_tables:
|
if table_name in self.gis_tables:
|
||||||
# If the table is a geographic one, then we need make
|
# If the table is a geographic one, then we need make
|
||||||
# GeoManager the default manager for the model.
|
# GeoManager the default manager for the model.
|
||||||
|
|
|
@ -65,6 +65,10 @@ class Command(BaseCommand):
|
||||||
indexes = connection.introspection.get_indexes(cursor, table_name)
|
indexes = connection.introspection.get_indexes(cursor, table_name)
|
||||||
except NotImplementedError:
|
except NotImplementedError:
|
||||||
indexes = {}
|
indexes = {}
|
||||||
|
try:
|
||||||
|
constraints = connection.introspection.get_constraints(cursor, table_name)
|
||||||
|
except NotImplementedError:
|
||||||
|
constraints = {}
|
||||||
used_column_names = [] # Holds column names used in the table so far
|
used_column_names = [] # Holds column names used in the table so far
|
||||||
for i, row in enumerate(connection.introspection.get_table_description(cursor, table_name)):
|
for i, row in enumerate(connection.introspection.get_table_description(cursor, table_name)):
|
||||||
comment_notes = [] # Holds Field notes, to be displayed in a Python comment.
|
comment_notes = [] # Holds Field notes, to be displayed in a Python comment.
|
||||||
|
@ -135,7 +139,7 @@ class Command(BaseCommand):
|
||||||
if comment_notes:
|
if comment_notes:
|
||||||
field_desc += ' # ' + ' '.join(comment_notes)
|
field_desc += ' # ' + ' '.join(comment_notes)
|
||||||
yield ' %s' % field_desc
|
yield ' %s' % field_desc
|
||||||
for meta_line in self.get_meta(table_name):
|
for meta_line in self.get_meta(table_name, constraints):
|
||||||
yield meta_line
|
yield meta_line
|
||||||
|
|
||||||
def normalize_col_name(self, col_name, used_column_names, is_relation):
|
def normalize_col_name(self, col_name, used_column_names, is_relation):
|
||||||
|
@ -232,13 +236,26 @@ class Command(BaseCommand):
|
||||||
|
|
||||||
return field_type, field_params, field_notes
|
return field_type, field_params, field_notes
|
||||||
|
|
||||||
def get_meta(self, table_name):
|
def get_meta(self, table_name, constraints):
|
||||||
"""
|
"""
|
||||||
Return a sequence comprising the lines of code necessary
|
Return a sequence comprising the lines of code necessary
|
||||||
to construct the inner Meta class for the model corresponding
|
to construct the inner Meta class for the model corresponding
|
||||||
to the given database table name.
|
to the given database table name.
|
||||||
"""
|
"""
|
||||||
return ["",
|
unique_together = []
|
||||||
|
for index, params in constraints.items():
|
||||||
|
if params['unique']:
|
||||||
|
columns = params['columns']
|
||||||
|
if len(columns) > 1:
|
||||||
|
# we do not want to include the u"" or u'' prefix
|
||||||
|
# so we build the string rather than interpolate the tuple
|
||||||
|
tup = '(' + ', '.join("'%s'" % c for c in columns) + ')'
|
||||||
|
unique_together.append(tup)
|
||||||
|
meta = ["",
|
||||||
" class Meta:",
|
" class Meta:",
|
||||||
" managed = False",
|
" managed = False",
|
||||||
" db_table = '%s'" % table_name]
|
" db_table = '%s'" % table_name]
|
||||||
|
if unique_together:
|
||||||
|
tup = '(' + ', '.join(unique_together) + ',)'
|
||||||
|
meta += [" unique_together = %s" % tup]
|
||||||
|
return meta
|
||||||
|
|
|
@ -179,6 +179,8 @@ Management Commands
|
||||||
|
|
||||||
* :djadmin:`runserver` now uses daemon threads for faster reloading.
|
* :djadmin:`runserver` now uses daemon threads for faster reloading.
|
||||||
|
|
||||||
|
* :djadmin:`inspectdb` now outputs ``Meta.unique_together``.
|
||||||
|
|
||||||
Models
|
Models
|
||||||
^^^^^^
|
^^^^^^
|
||||||
|
|
||||||
|
|
|
@ -70,3 +70,11 @@ class ColumnTypes(models.Model):
|
||||||
text_field = models.TextField()
|
text_field = models.TextField()
|
||||||
time_field = models.TimeField()
|
time_field = models.TimeField()
|
||||||
url_field = models.URLField()
|
url_field = models.URLField()
|
||||||
|
|
||||||
|
|
||||||
|
class UniqueTogether(models.Model):
|
||||||
|
field1 = models.IntegerField()
|
||||||
|
field2 = models.CharField(max_length=10)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
unique_together = ('field1', 'field2')
|
||||||
|
|
|
@ -217,6 +217,14 @@ class InspectDBTestCase(TestCase):
|
||||||
self.longMessage = False
|
self.longMessage = False
|
||||||
self.assertIn(" managed = False", output, msg='inspectdb should generate unmanaged models.')
|
self.assertIn(" managed = False", output, msg='inspectdb should generate unmanaged models.')
|
||||||
|
|
||||||
|
def test_unique_together_meta(self):
|
||||||
|
out = StringIO()
|
||||||
|
call_command('inspectdb',
|
||||||
|
table_name_filter=lambda tn: tn.startswith('inspectdb_uniquetogether'),
|
||||||
|
stdout=out)
|
||||||
|
output = out.getvalue()
|
||||||
|
self.assertIn(" unique_together = (('field1', 'field2'),)", output, msg='inspectdb should generate unique_together.')
|
||||||
|
|
||||||
@skipUnless(connection.vendor == 'sqlite',
|
@skipUnless(connection.vendor == 'sqlite',
|
||||||
"Only patched sqlite's DatabaseIntrospection.data_types_reverse for this test")
|
"Only patched sqlite's DatabaseIntrospection.data_types_reverse for this test")
|
||||||
def test_custom_fields(self):
|
def test_custom_fields(self):
|
||||||
|
|
Loading…
Reference in New Issue