Kaydet (Commit) 70c54a36 authored tarafından Damien Nozay's avatar Damien Nozay Kaydeden (comit) Tim Graham

Fixed #23028: Added unique_togther support to inspectdb.

üst b8d25507
...@@ -21,8 +21,8 @@ class Command(InspectDBCommand): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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 ...@@ -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): ...@@ -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): ...@@ -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):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment