Code

Ticket #2229: m2m_syncdb.patch

File m2m_syncdb.patch, 5.3 KB (added by SmileyChris, 7 years ago)
  • django/core/management.py

     
    238238    return final_output 
    239239 
    240240def _get_many_to_many_sql_for_model(model): 
    241     from django.db import backend, get_creation_module 
    242241    from django.db.models import GenericRel 
    243242 
    244     data_types = get_creation_module().DATA_TYPES 
    245  
    246243    opts = model._meta 
    247244    final_output = [] 
    248245    for f in opts.many_to_many: 
    249246        if not isinstance(f.rel, GenericRel): 
    250             table_output = [style.SQL_KEYWORD('CREATE TABLE') + ' ' + \ 
    251                 style.SQL_TABLE(backend.quote_name(f.m2m_db_table())) + ' ('] 
    252             table_output.append('    %s %s %s,' % \ 
    253                 (style.SQL_FIELD(backend.quote_name('id')), 
    254                 style.SQL_COLTYPE(data_types['AutoField']), 
    255                 style.SQL_KEYWORD('NOT NULL PRIMARY KEY'))) 
    256             table_output.append('    %s %s %s %s (%s)%s,' % \ 
    257                 (style.SQL_FIELD(backend.quote_name(f.m2m_column_name())), 
    258                 style.SQL_COLTYPE(data_types[get_rel_data_type(opts.pk)] % opts.pk.__dict__), 
    259                 style.SQL_KEYWORD('NOT NULL REFERENCES'), 
    260                 style.SQL_TABLE(backend.quote_name(opts.db_table)), 
    261                 style.SQL_FIELD(backend.quote_name(opts.pk.column)), 
    262                 backend.get_deferrable_sql())) 
    263             table_output.append('    %s %s %s %s (%s)%s,' % \ 
    264                 (style.SQL_FIELD(backend.quote_name(f.m2m_reverse_name())), 
    265                 style.SQL_COLTYPE(data_types[get_rel_data_type(f.rel.to._meta.pk)] % f.rel.to._meta.pk.__dict__), 
    266                 style.SQL_KEYWORD('NOT NULL REFERENCES'), 
    267                 style.SQL_TABLE(backend.quote_name(f.rel.to._meta.db_table)), 
    268                 style.SQL_FIELD(backend.quote_name(f.rel.to._meta.pk.column)), 
    269                 backend.get_deferrable_sql())) 
    270             table_output.append('    %s (%s, %s)' % \ 
    271                 (style.SQL_KEYWORD('UNIQUE'), 
    272                 style.SQL_FIELD(backend.quote_name(f.m2m_column_name())), 
    273                 style.SQL_FIELD(backend.quote_name(f.m2m_reverse_name())))) 
    274             table_output.append(');') 
    275             final_output.append('\n'.join(table_output)) 
     247            final_output.append(_get_many_to_many_sql_for_field(f, opts)) 
    276248    return final_output 
    277249 
     250def _get_many_to_many_sql_for_field(f, opts): 
     251    """ 
     252    Returns the SQL for creating a many-to-many table. 
     253    Takes a many-to-many field and opts for the model it belongs to. 
     254    """ 
     255    from django.db import backend, get_creation_module 
     256    data_types = get_creation_module().DATA_TYPES 
     257 
     258    table_output = [style.SQL_KEYWORD('CREATE TABLE') + ' ' + \ 
     259        style.SQL_TABLE(backend.quote_name(f.m2m_db_table())) + ' ('] 
     260    table_output.append('    %s %s %s,' % \ 
     261        (style.SQL_FIELD(backend.quote_name('id')), 
     262        style.SQL_COLTYPE(data_types['AutoField']), 
     263        style.SQL_KEYWORD('NOT NULL PRIMARY KEY'))) 
     264    table_output.append('    %s %s %s %s (%s)%s,' % \ 
     265        (style.SQL_FIELD(backend.quote_name(f.m2m_column_name())), 
     266        style.SQL_COLTYPE(data_types[get_rel_data_type(opts.pk)] % opts.pk.__dict__), 
     267        style.SQL_KEYWORD('NOT NULL REFERENCES'), 
     268        style.SQL_TABLE(backend.quote_name(opts.db_table)), 
     269        style.SQL_FIELD(backend.quote_name(opts.pk.column)), 
     270        backend.get_deferrable_sql())) 
     271    table_output.append('    %s %s %s %s (%s)%s,' % \ 
     272        (style.SQL_FIELD(backend.quote_name(f.m2m_reverse_name())), 
     273        style.SQL_COLTYPE(data_types[get_rel_data_type(f.rel.to._meta.pk)] % f.rel.to._meta.pk.__dict__), 
     274        style.SQL_KEYWORD('NOT NULL REFERENCES'), 
     275        style.SQL_TABLE(backend.quote_name(f.rel.to._meta.db_table)), 
     276        style.SQL_FIELD(backend.quote_name(f.rel.to._meta.pk.column)), 
     277        backend.get_deferrable_sql())) 
     278    table_output.append('    %s (%s, %s)' % \ 
     279        (style.SQL_KEYWORD('UNIQUE'), 
     280        style.SQL_FIELD(backend.quote_name(f.m2m_column_name())), 
     281        style.SQL_FIELD(backend.quote_name(f.m2m_reverse_name())))) 
     282    table_output.append(');') 
     283    return '\n'.join(table_output) 
     284 
    278285def get_sql_delete(app): 
    279286    "Returns a list of the DROP TABLE SQL statements for the given app." 
    280287    from django.db import backend, connection, models, get_introspection_module 
     
    534541            table_list.append(model._meta.db_table) 
    535542 
    536543        for model in model_list: 
    537             if model in created_models: 
    538                 sql = _get_many_to_many_sql_for_model(model) 
    539                 if sql: 
    540                     if verbosity >= 2: 
    541                         print "Creating many-to-many tables for %s.%s model" % (app_name, model._meta.object_name) 
    542                     for statement in sql: 
    543                         cursor.execute(statement) 
     544            opts = model._meta 
     545            for field in opts.many_to_many: 
     546                if isinstance(field.rel, models.GenericRel) or field.m2m_db_table() in table_list: 
     547                    continue 
     548                sql = _get_many_to_many_sql_for_field(field, opts) 
     549                if verbosity >= 2: 
     550                    print "Creating many-to-many table %s for %s.%s model" % (field.m2m_db_table(), app_name, opts.object_name) 
     551                cursor.execute(sql) 
    544552 
    545553        transaction.commit_unless_managed() 
    546554