Django

Code

Changeset 1224

Show
Ignore:
Timestamp:
11/13/05 19:44:35 (3 years ago)
Author:
adrian
Message:

Fixed #121 -- Django now quotes all names in SQL queries. Also added unit tests to confirm. Thanks, Robin Munn and Sune.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/bin/daily_cleanup.py

    r518 r1224  
    88    # Clean up old database records 
    99    cursor = db.cursor() 
    10     cursor.execute("DELETE FROM core_sessions WHERE expire_date < NOW()") 
    11     cursor.execute("DELETE FROM registration_challenges WHERE request_date < NOW() - INTERVAL '1 week'") 
     10    cursor.execute("DELETE FROM %s WHERE %s < NOW()" % \ 
     11        (db.quote_name('core_sessions'), db.quote_name('expire_date'))) 
     12    cursor.execute("DELETE FROM %s WHERE %s < NOW() - INTERVAL '1 week'" % \ 
     13        (db.quote_name('registration_challenges'), db.quote_name('request_date'))) 
    1214    db.commit() 
    1315 
  • django/trunk/django/core/db/backends/ado_mssql.py

    r1213 r1224  
    150150    'OneToOneField':     'int', 
    151151    'PhoneNumberField':  'varchar(20)', 
    152     'PositiveIntegerField': 'int CONSTRAINT [CK_int_pos_%(name)s] CHECK ([%(name)s] > 0)', 
    153     'PositiveSmallIntegerField': 'smallint CONSTRAINT [CK_smallint_pos_%(name)s] CHECK ([%(name)s] > 0)', 
     152    'PositiveIntegerField': 'int CONSTRAINT [CK_int_pos_%(column)s] CHECK ([%(column)s] > 0)', 
     153    'PositiveSmallIntegerField': 'smallint CONSTRAINT [CK_smallint_pos_%(column)s] CHECK ([%(column)s] > 0)', 
    154154    'SlugField':         'varchar(50)', 
    155155    'SmallIntegerField': 'smallint', 
  • django/trunk/django/core/db/backends/postgresql.py

    r1213 r1224  
    171171    'OneToOneField':     'integer', 
    172172    'PhoneNumberField':  'varchar(20)', 
    173     'PositiveIntegerField': 'integer CHECK (%(name)s >= 0)', 
    174     'PositiveSmallIntegerField': 'smallint CHECK (%(name)s >= 0)', 
     173    'PositiveIntegerField': 'integer CHECK (%(column)s >= 0)', 
     174    'PositiveSmallIntegerField': 'smallint CHECK (%(column)s >= 0)', 
    175175    'SlugField':         'varchar(50)', 
    176176    'SmallIntegerField': 'smallint', 
  • django/trunk/django/core/management.py

    r1151 r1224  
    2020 
    2121def _get_packages_insert(app_label): 
    22     return "INSERT INTO packages (label, name) VALUES ('%s', '%s');" % (app_label, app_label) 
     22    from django.core.db import db 
     23    return "INSERT INTO %s (%s, %s) VALUES ('%s', '%s');" % \ 
     24        (db.quote_name('packages'), db.quote_name('label'), db.quote_name('name'), 
     25        app_label, app_label) 
    2326 
    2427def _get_permission_codename(action, opts): 
     
    3437 
    3538def _get_permission_insert(name, codename, opts): 
    36     return "INSERT INTO auth_permissions (name, package, codename) VALUES ('%s', '%s', '%s');" % \ 
    37         (name.replace("'", "''"), opts.app_label, codename) 
     39    from django.core.db import db 
     40    return "INSERT INTO %s (%s, %s, %s) VALUES ('%s', '%s', '%s');" % \ 
     41        (db.quote_name('auth_permissions'), db.quote_name('name'), db.quote_name('package'), 
     42        db.quote_name('codename'), name.replace("'", "''"), opts.app_label, codename) 
    3843 
    3944def _get_contenttype_insert(opts): 
    40     return "INSERT INTO content_types (name, package, python_module_name) VALUES ('%s', '%s', '%s');" % \ 
    41         (opts.verbose_name, opts.app_label, opts.module_name) 
     45    from django.core.db import db 
     46    return "INSERT INTO %s (%s, %s, %s) VALUES ('%s', '%s', '%s');" % \ 
     47        (db.quote_name('content_types'), db.quote_name('name'), db.quote_name('package'), 
     48        db.quote_name('python_module_name'), opts.verbose_name, opts.app_label, opts.module_name) 
    4249 
    4350def _is_valid_dir_name(s): 
     
    6572            col_type = db.DATA_TYPES[data_type] 
    6673            if col_type is not None: 
    67                 field_output = [f.column, col_type % rel_field.__dict__] 
     74                field_output = [db.db.quote_name(f.column), col_type % rel_field.__dict__] 
    6875                field_output.append('%sNULL' % (not f.null and 'NOT ' or '')) 
    6976                if f.unique: 
     
    7380                if f.rel: 
    7481                    field_output.append('REFERENCES %s (%s)' % \ 
    75                         (f.rel.to.db_table, f.rel.to.get_field(f.rel.field_name).column)) 
     82                        (db.db.quote_name(f.rel.to.db_table), 
     83                        db.db.quote_name(f.rel.to.get_field(f.rel.field_name).column))) 
    7684                table_output.append(' '.join(field_output)) 
    7785        if opts.order_with_respect_to: 
    78             table_output.append('_order %s NULL' % db.DATA_TYPES['IntegerField']
     86            table_output.append('%s %s NULL' % (db.db.quote_name('_order'), db.DATA_TYPES['IntegerField'])
    7987        for field_constraints in opts.unique_together: 
    80             table_output.append('UNIQUE (%s)' % ", ".join([opts.get_field(f).column for f in field_constraints])) 
    81  
    82         full_statement = ['CREATE TABLE %s (' % opts.db_table] 
     88            table_output.append('UNIQUE (%s)' % \ 
     89                ", ".join([db.db.quote_name(opts.get_field(f).column) for f in field_constraints])) 
     90 
     91        full_statement = ['CREATE TABLE %s (' % db.db.quote_name(opts.db_table)] 
    8392        for i, line in enumerate(table_output): # Combine and add commas. 
    8493            full_statement.append('    %s%s' % (line, i < len(table_output)-1 and ',' or '')) 
     
    8998        opts = klass._meta 
    9099        for f in opts.many_to_many: 
    91             table_output = ['CREATE TABLE %s (' % f.get_m2m_db_table(opts)] 
    92             table_output.append('    id %s NOT NULL PRIMARY KEY,' % db.DATA_TYPES['AutoField']) 
    93             table_output.append('    %s_id %s NOT NULL REFERENCES %s (%s),' % \ 
    94                 (opts.object_name.lower(), db.DATA_TYPES[get_rel_data_type(opts.pk)] % opts.pk.__dict__, opts.db_table, opts.pk.column)) 
    95             table_output.append('    %s_id %s NOT NULL REFERENCES %s (%s),' % \ 
    96                 (f.rel.to.object_name.lower(), db.DATA_TYPES[get_rel_data_type(f.rel.to.pk)] % f.rel.to.pk.__dict__, f.rel.to.db_table, f.rel.to.pk.column)) 
    97             table_output.append('    UNIQUE (%s_id, %s_id)' % (opts.object_name.lower(), f.rel.to.object_name.lower())) 
     100            table_output = ['CREATE TABLE %s (' % db.db.quote_name(f.get_m2m_db_table(opts))] 
     101            table_output.append('    %s %s NOT NULL PRIMARY KEY,' % (db.db.quote_name('id'), db.DATA_TYPES['AutoField'])) 
     102            table_output.append('    %s %s NOT NULL REFERENCES %s (%s),' % \ 
     103                (db.db.quote_name(opts.object_name.lower() + '_id'), 
     104                db.DATA_TYPES[get_rel_data_type(opts.pk)] % opts.pk.__dict__, 
     105                db.db.quote_name(opts.db_table), 
     106                db.db.quote_name(opts.pk.column))) 
     107            table_output.append('    %s %s NOT NULL REFERENCES %s (%s),' % \ 
     108                (db.db.quote_name(f.rel.to.object_name.lower() + '_id'), 
     109                db.DATA_TYPES[get_rel_data_type(f.rel.to.pk)] % f.rel.to.pk.__dict__, 
     110                db.db.quote_name(f.rel.to.db_table), 
     111                db.db.quote_name(f.rel.to.pk.column))) 
     112            table_output.append('    UNIQUE (%s, %s)' % \ 
     113                (db.db.quote_name(opts.object_name.lower() + '_id'), 
     114                db.db.quote_name(f.rel.to.object_name.lower() + '_id'))) 
    98115            table_output.append(');') 
    99116            final_output.append('\n'.join(table_output)) 
     
    115132        if cursor is not None: 
    116133            # Check whether the table exists. 
    117             cursor.execute("SELECT 1 FROM django_admin_log LIMIT 1"
     134            cursor.execute("SELECT 1 FROM %s LIMIT 1" % db.db.quote_name('django_admin_log')
    118135    except: 
    119136        # The table doesn't exist, so it doesn't need to be dropped. 
     
    130147            if cursor is not None: 
    131148                # Check whether the table exists. 
    132                 cursor.execute("SELECT 1 FROM %s LIMIT 1" % klass._meta.db_table
     149                cursor.execute("SELECT 1 FROM %s LIMIT 1" % db.db.quote_name(klass._meta.db_table)
    133150        except: 
    134151            # The table doesn't exist, so it doesn't need to be dropped. 
    135152            db.db.rollback() 
    136153        else: 
    137             output.append("DROP TABLE %s;" % klass._meta.db_table
     154            output.append("DROP TABLE %s;" % db.db.quote_name(klass._meta.db_table)
    138155 
    139156    # Output DROP TABLE statements for many-to-many tables. 
     
    143160            try: 
    144161                if cursor is not None: 
    145                     cursor.execute("SELECT 1 FROM %s LIMIT 1" % f.get_m2m_db_table(opts)) 
     162                    cursor.execute("SELECT 1 FROM %s LIMIT 1" % db.db.quote_name(f.get_m2m_db_table(opts))) 
    146163            except: 
    147164                db.db.rollback() 
    148165            else: 
    149                 output.append("DROP TABLE %s;" % f.get_m2m_db_table(opts)) 
     166                output.append("DROP TABLE %s;" % db.db.quote_name(f.get_m2m_db_table(opts))) 
    150167 
    151168    app_label = mod._MODELS[0]._meta.app_label 
    152169 
    153170    # Delete from packages, auth_permissions, content_types. 
    154     output.append("DELETE FROM packages WHERE label = '%s';" % app_label) 
    155     output.append("DELETE FROM auth_permissions WHERE package = '%s';" % app_label) 
    156     output.append("DELETE FROM content_types WHERE package = '%s';" % app_label) 
     171    output.append("DELETE FROM %s WHERE %s = '%s';" % \ 
     172        (db.db.quote_name('packages'), db.db.quote_name('label'), app_label)) 
     173    output.append("DELETE FROM %s WHERE %s = '%s';" % \ 
     174        (db.db.quote_name('auth_permissions'), db.db.quote_name('package'), app_label)) 
     175    output.append("DELETE FROM %s WHERE %s = '%s';" % \ 
     176        (db.db.quote_name('content_types'), db.db.quote_name('package'), app_label)) 
    157177 
    158178    # Delete from the admin log. 
    159179    if cursor is not None: 
    160         cursor.execute("SELECT id FROM content_types WHERE package = %s", [app_label]) 
     180        cursor.execute("SELECT %s FROM %s WHERE %s = %%s" % \ 
     181            (db.db.quote_name('id'), db.db.quote_name('content_types'), 
     182            db.db.quote_name('package')), [app_label]) 
    161183        if admin_log_exists: 
    162184            for row in cursor.fetchall(): 
    163                 output.append("DELETE FROM django_admin_log WHERE content_type_id = %s;" % row[0]) 
     185                output.append("DELETE FROM %s WHERE %s = %s;" % \ 
     186                    (db.db.quote_name('django_admin_log'), db.db.quote_name('content_type_id'), row[0])) 
    164187 
    165188    # Close database connection explicitly, in case this output is being piped 
     
    207230def get_sql_sequence_reset(mod): 
    208231    "Returns a list of the SQL statements to reset PostgreSQL sequences for the given module." 
    209     from django.core import meta 
     232    from django.core import db, meta 
    210233    output = [] 
    211234    for klass in mod._MODELS: 
    212235        for f in klass._meta.fields: 
    213236            if isinstance(f, meta.AutoField): 
    214                 output.append("SELECT setval('%s_%s_seq', (SELECT max(%s) FROM %s));" % (klass._meta.db_table, f.column, f.column, klass._meta.db_table)) 
     237                output.append("SELECT setval('%s_%s_seq', (SELECT max(%s) FROM %s));" % \ 
     238                    (klass._meta.db_table, f.column, db.db.quote_name(f.column), 
     239                    db.db.quote_name(klass._meta.db_table))) 
    215240    return output 
    216241get_sql_sequence_reset.help_doc = "Prints the SQL statements for resetting PostgreSQL sequences for the given model module name(s)." 
     
    219244def get_sql_indexes(mod): 
    220245    "Returns a list of the CREATE INDEX SQL statements for the given module." 
     246    from django.core.db import db 
    221247    output = [] 
    222248    for klass in mod._MODELS: 
     
    225251                unique = f.unique and "UNIQUE " or "" 
    226252                output.append("CREATE %sINDEX %s_%s ON %s (%s);" % \ 
    227                     (unique, klass._meta.db_table, f.column, klass._meta.db_table, f.column)) 
     253                    (unique, klass._meta.db_table, f.column, 
     254                    db.quote_name(klass._meta.db_table), db.quote_name(f.column))) 
    228255    return output 
    229256get_sql_indexes.help_doc = "Prints the CREATE INDEX SQL statements for the given model module name(s)." 
     
    243270 
    244271    # Check that the package exists in the database. 
    245     cursor.execute("SELECT 1 FROM packages WHERE label = %s", [app_label]) 
     272    cursor.execute("SELECT 1 FROM %s WHERE %s = %%s" % \ 
     273        (db.db.quote_name('packages'), db.db.quote_name('label')), [app_label]) 
    246274    if cursor.rowcount < 1: 
    247275#         sys.stderr.write("The '%s' package isn't installed.\n" % app_label) 
     
    257285        contenttypes_seen[opts.module_name] = 1 
    258286        for codename, name in perms: 
    259             cursor.execute("SELECT 1 FROM auth_permissions WHERE package = %s AND codename = %s", (app_label, codename)) 
     287            cursor.execute("SELECT 1 FROM %s WHERE %s = %%s AND %s = %%s" % \ 
     288                (db.db.quote_name('auth_permissions'), db.db.quote_name('package'), 
     289                db.db.quote_name('codename')), (app_label, codename)) 
    260290            if cursor.rowcount < 1: 
    261291#                 sys.stderr.write("The '%s.%s' permission doesn't exist.\n" % (app_label, codename)) 
    262292                print _get_permission_insert(name, codename, opts) 
    263         cursor.execute("SELECT 1 FROM content_types WHERE package = %s AND python_module_name = %s", (app_label, opts.module_name)) 
     293        cursor.execute("SELECT 1 FROM %s WHERE %s = %%s AND %s = %%s" % \ 
     294            (db.db.quote_name('content_types'), db.db.quote_name('package'), 
     295            db.db.quote_name('python_module_name')), (app_label, opts.module_name)) 
    264296        if cursor.rowcount < 1: 
    265297#             sys.stderr.write("The '%s.%s' content type doesn't exist.\n" % (app_label, opts.module_name)) 
     
    268300    # Check that there aren't any *extra* permissions in the DB that the model 
    269301    # doesn't know about. 
    270     cursor.execute("SELECT codename FROM auth_permissions WHERE package = %s", (app_label,)) 
     302    cursor.execute("SELECT %s FROM %s WHERE %s = %%s" % \ 
     303        (db.db.quote_name('codename'), db.db.quote_name('auth_permissions'), 
     304        db.db.quote_name('package')), (app_label,)) 
    271305    for row in cursor.fetchall(): 
    272306        try: 
     
    274308        except KeyError: 
    275309#             sys.stderr.write("A permission called '%s.%s' was found in the database but not in the model.\n" % (app_label, row[0])) 
    276             print "DELETE FROM auth_permissions WHERE package='%s' AND codename = '%s';" % (app_label, row[0]) 
     310            print "DELETE FROM %s WHERE %s='%s' AND %s = '%s';" % \ 
     311                (db.db.quote_name('auth_permissions'), db.db.quote_name('package'), 
     312                app_label, db.db.quote_name('codename'), row[0]) 
    277313 
    278314    # Check that there aren't any *extra* content types in the DB that the 
    279315    # model doesn't know about. 
    280     cursor.execute("SELECT python_module_name FROM content_types WHERE package = %s", (app_label,)) 
     316    cursor.execute("SELECT %s FROM %s WHERE %s = %%s" % \ 
     317        (db.db.quote_name('python_module_name'), db.db.quote_name('content_types'), 
     318        db.db.quote_name('package')), (app_label,)) 
    281319    for row in cursor.fetchall(): 
    282320        try: 
     
    284322        except KeyError: 
    285323#             sys.stderr.write("A content type called '%s.%s' was found in the database but not in the model.\n" % (app_label, row[0])) 
    286             print "DELETE FROM content_types WHERE package='%s' AND python_module_name = '%s';" % (app_label, row[0]) 
     324            print "DELETE FROM %s WHERE %s='%s' AND %s = '%s';" % \ 
     325                (db.db.quote_name('content_types'), db.db.quote_name('package'), 
     326                app_label, db.db.quote_name('python_module_name'), row[0]) 
    287327database_check.help_doc = "Checks that everything is installed in the database for the given model module name(s) and prints SQL statements if needed." 
    288328database_check.args = APP_ARGS 
     
    319359        for sql in get_sql_create(core) + get_sql_create(auth) + get_sql_initial_data(core) + get_sql_initial_data(auth): 
    320360            cursor.execute(sql) 
    321         cursor.execute("INSERT INTO %s (domain, name) VALUES ('example.com', 'Example site')" % core.Site._meta.db_table) 
     361        cursor.execute("INSERT INTO %s (%s, %s) VALUES ('example.com', 'Example site')" % \ 
     362            (db.db.quote_name(core.Site._meta.db_table), db.db.quote_name('domain'), 
     363            db.db.quote_name('name'))) 
    322364    except Exception, e: 
    323365        sys.stderr.write("Error: The database couldn't be initialized.\n%s\n" % e) 
     
    688730    index_output = [] 
    689731    for f in fields: 
    690         field_output = [f.column, db.DATA_TYPES[f.get_internal_type()] % f.__dict__] 
     732        field_output = [db.db.quote_name(f.column), db.DATA_TYPES[f.get_internal_type()] % f.__dict__] 
    691733        field_output.append("%sNULL" % (not f.null and "NOT " or "")) 
    692734        if f.unique: 
     
    696738        if f.db_index: 
    697739            unique = f.unique and "UNIQUE " or "" 
    698             index_output.append("CREATE %sINDEX %s_%s ON %s (%s);" % (unique, tablename, f.column, tablename, f.column)) 
     740            index_output.append("CREATE %sINDEX %s_%s ON %s (%s);" % \ 
     741                (unique, tablename, f.column, db.db.quote_name(tablename), 
     742                db.db.quote_name(f.column))) 
    699743        table_output.append(" ".join(field_output)) 
    700     full_statement = ["CREATE TABLE %s (" % tablename
     744    full_statement = ["CREATE TABLE %s (" % db.db.quote_name(tablename)
    701745    for i, line in enumerate(table_output): 
    702746        full_statement.append('    %s%s' % (line, i < len(table_output)-1 and ',' or '')) 
  • django/trunk/django/core/meta/__init__.py

    r1155 r1224  
    5858 
    5959def orderlist2sql(order_list, opts, prefix=''): 
     60    if prefix.endswith('.'): 
     61        prefix = db.db.quote_name(prefix[:-1]) + '.' 
    6062    output = [] 
    6163    for f in handle_legacy_orderlist(order_list): 
    6264        if f.startswith('-'): 
    63             output.append('%s%s DESC' % (prefix, orderfield2column(f[1:], opts))) 
     65            output.append('%s%s DESC' % (prefix, db.db.quote_name(orderfield2column(f[1:], opts)))) 
    6466        elif f == '?': 
    6567            output.append(db.get_random_function_sql()) 
    6668        else: 
    67             output.append('%s%s ASC' % (prefix, orderfield2column(f, opts))) 
     69            output.append('%s%s ASC' % (prefix, db.db.quote_name(orderfield2column(f, opts)))) 
    6870    return ', '.join(output) 
    6971 
     
    786788    if pk_set: 
    787789        # Determine whether a record with the primary key already exists. 
    788         cursor.execute("SELECT 1 FROM %s WHERE %s=%%s LIMIT 1" % (opts.db_table, opts.pk.column), [pk_val]) 
     790        cursor.execute("SELECT 1 FROM %s WHERE %s=%%s LIMIT 1" % \ 
     791            (db.db.quote_name(opts.db_table), db.db.quote_name(opts.pk.column)), [pk_val]) 
    789792        # If it does already exist, do an UPDATE. 
    790793        if cursor.fetchone(): 
    791794            db_values = [f.get_db_prep_save(f.pre_save(getattr(self, f.attname), False)) for f in non_pks] 
    792             cursor.execute("UPDATE %s SET %s WHERE %s=%%s" % (opts.db_table, 
    793                 ','.join(['%s=%%s' % f.column for f in non_pks]), opts.pk.attname), 
     795            cursor.execute("UPDATE %s SET %s WHERE %s=%%s" % \ 
     796                (db.db.quote_name(opts.db_table), 
     797                ','.join(['%s=%%s' % db.db.quote_name(f.column) for f in non_pks]), 
     798                db.db.quote_name(opts.pk.attname)), 
    794799                db_values + [pk_val]) 
    795800        else: 
    796801            record_exists = False 
    797802    if not pk_set or not record_exists: 
    798         field_names = [f.column for f in opts.fields if not isinstance(f, AutoField)] 
     803        field_names = [db.db.quote_name(f.column) for f in opts.fields if not isinstance(f, AutoField)] 
    799804        placeholders = ['%s'] * len(field_names) 
    800805        db_values = [f.get_db_prep_save(f.pre_save(getattr(self, f.attname), True)) for f in opts.fields if not isinstance(f, AutoField)] 
    801806        if opts.order_with_respect_to: 
    802             field_names.append('_order'
     807            field_names.append(db.db.quote_name('_order')
    803808            # TODO: This assumes the database supports subqueries. 
    804809            placeholders.append('(SELECT COUNT(*) FROM %s WHERE %s = %%s)' % \ 
    805                 (opts.db_table, opts.order_with_respect_to.column)) 
     810                (db.db.quote_name(opts.db_table), db.db.quote_name(opts.order_with_respect_to.column))) 
    806811            db_values.append(getattr(self, opts.order_with_respect_to.attname)) 
    807         cursor.execute("INSERT INTO %s (%s) VALUES (%s)" % (opts.db_table, 
    808             ','.join(field_names), ','.join(placeholders)), db_values) 
     812        cursor.execute("INSERT INTO %s (%s) VALUES (%s)" % \ 
     813            (db.db.quote_name(opts.db_table), ','.join(field_names), 
     814            ','.join(placeholders)), db_values) 
    809815        if opts.has_auto_field: 
    810816            setattr(self, opts.pk.attname, db.get_last_insert_id(cursor, opts.db_table, opts.pk.column)) 
     
    833839                sub_obj.delete() 
    834840    for rel_opts, rel_field in opts.get_all_related_many_to_many_objects(): 
    835         cursor.execute("DELETE FROM %s WHERE %s_id=%%s" % (rel_field.get_m2m_db_table(rel_opts), 
    836             self._meta.object_name.lower()), [getattr(self, opts.pk.attname)]) 
     841        cursor.execute("DELETE FROM %s WHERE %s=%%s" % \ 
     842            (db.db.quote_name(rel_field.get_m2m_db_table(rel_opts)), 
     843            db.db.quote_name(self._meta.object_name.lower() + '_id')), [getattr(self, opts.pk.attname)]) 
    837844    for f in opts.many_to_many: 
    838         cursor.execute("DELETE FROM %s WHERE %s_id=%%s" % (f.get_m2m_db_table(opts), self._meta.object_name.lower()), 
     845        cursor.execute("DELETE FROM %s WHERE %s=%%s" % \ 
     846            (db.db.quote_name(f.get_m2m_db_table(opts)), 
     847            db.db.quote_name(self._meta.object_name.lower() + '_id')), 
    839848            [getattr(self, opts.pk.attname)]) 
    840     cursor.execute("DELETE FROM %s WHERE %s=%%s" % (opts.db_table, opts.pk.column), [getattr(self, opts.pk.attname)]) 
     849    cursor.execute("DELETE FROM %s WHERE %s=%%s" % \ 
     850        (db.db.quote_name(opts.db_table), db.db.quote_name(opts.pk.column)), 
     851        [getattr(self, opts.pk.attname)]) 
    841852    db.db.commit() 
    842853    setattr(self, opts.pk.attname, None) 
     
    855866    if not hasattr(self, '_next_in_order_cache'): 
    856867        self._next_in_order_cache = opts.get_model_module().get_object(order_by=('_order',), 
    857             where=['_order > (SELECT _order FROM %s WHERE %s=%%s)' % (opts.db_table, opts.pk.column), 
    858                 '%s=%%s' % order_field.column], limit=1, 
     868            where=['%s > (SELECT %s FROM %s WHERE %s=%%s)' % \ 
     869                (db.db.quote_name('_order'), db.db.quote_name('_order'), 
     870                db.db.quote_name(opts.db_table), db.db.quote_name(opts.pk.column)), 
     871                '%s=%%s' % db.db.quote_name(order_field.column)], limit=1, 
    859872            params=[getattr(self, opts.pk.attname), getattr(self, order_field.attname)]) 
    860873    return self._next_in_order_cache 
     
    863876    if not hasattr(self, '_previous_in_order_cache'): 
    864877        self._previous_in_order_cache = opts.get_model_module().get_object(order_by=('-_order',), 
    865             where=['_order < (SELECT _order FROM %s WHERE %s=%%s)' % (opts.db_table, opts.pk.column), 
    866                 '%s=%%s' % order_field.column], limit=1, 
     878            where=['%s < (SELECT %s FROM %s WHERE %s=%%s)' % \ 
     879                (db.db.quote_name('_order'), db.db.quote_name('_order'), 
     880                db.db.quote_name(opts.db_table), db.db.quote_name(opts.pk.column)), 
     881                '%s=%%s' % db.db.quote_name(order_field.column)], limit=1, 
    867882            params=[getattr(self, opts.pk.attname), getattr(self, order_field.attname)]) 
    868883    return self._previous_in_order_cache 
     
    889904    if not hasattr(self, cache_var): 
    890905        mod = rel.get_model_module() 
    891         sql = "SELECT %s FROM %s a, %s b WHERE a.%s = b.%s_id AND b.%s_id = %%s %s" % \ 
    892             (','.join(['a.%s' % f.column for f in rel.fields]), rel.db_table, 
    893             field_with_rel.get_m2m_db_table(self._meta), rel.pk.column, 
    894             rel.object_name.lower(), self._meta.object_name.lower(), rel.get_order_sql('a')) 
     906        sql = "SELECT %s FROM %s a, %s b WHERE a.%s = b.%s AND b.%s = %%s %s" % \ 
     907            (','.join(['a.%s' % db.db.quote_name(f.column) for f in rel.fields]), 
     908            db.db.quote_name(rel.db_table), 
     909            db.db.quote_name(field_with_rel.get_m2m_db_table(self._meta)), 
     910            db.db.quote_name(rel.pk.column), 
     911            db.db.quote_name(rel.object_name.lower() + '_id'), 
     912            db.db.quote_name(self._meta.object_name.lower() + '_id'), rel.get_order_sql('a')) 
    895913        cursor = db.db.cursor() 
    896914        cursor.execute(sql, [getattr(self, self._meta.pk.attname)]) 
     
    917935    this_id = getattr(self, self._meta.pk.attname) 
    918936    if ids_to_delete: 
    919         sql = "DELETE FROM %s WHERE %s_id = %%s AND %s_id IN (%s)" % (m2m_table, self._meta.object_name.lower(), rel.object_name.lower(), ','.join(map(str, ids_to_delete))) 
     937        sql = "DELETE FROM %s WHERE %s = %%s AND %s IN (%s)" % \ 
     938            (db.db.quote_name(m2m_table), 
     939            db.db.quote_name(self._meta.object_name.lower() + '_id'), 
     940            db.db.quote_name(rel.object_name.lower() + '_id'), ','.join(map(str, ids_to_delete))) 
    920941        cursor.execute(sql, [this_id]) 
    921942    if ids_to_add: 
    922         sql = "INSERT INTO %s (%s_id, %s_id) VALUES (%%s, %%s)" % (m2m_table, self._meta.object_name.lower(), rel.object_name.lower()) 
     943        sql = "INSERT INTO %s (%s, %s) VALUES (%%s, %%s)" % \ 
     944            (db.db.quote_name(m2m_table), 
     945            db.db.quote_name(self._meta.object_name.lower() + '_id'), 
     946            db.db.quote_name(rel.object_name.lower() + '_id')) 
    923947        cursor.executemany(sql, [(this_id, i) for i in ids_to_add]) 
    924948    db.db.commit() 
     
    966990    this_id = getattr(self, self._meta.pk.attname) 
    967991    cursor = db.db.cursor() 
    968     cursor.execute("DELETE FROM %s WHERE %s_id = %%s" % (m2m_table, rel.object_name.lower()), [this_id]) 
    969     sql = "INSERT INTO %s (%s_id, %s_id) VALUES (%%s, %%s)" % (m2m_table, rel.object_name.lower(), rel_opts.object_name.lower()) 
     992    cursor.execute("DELETE FROM %s WHERE %s = %%s" % \ 
     993        (db.db.quote_name(m2m_table), 
     994        db.db.quote_name(rel.object_name.lower() + '_id')), [this_id]) 
     995    sql = "INSERT INTO %s (%s, %s) VALUES (%%s, %%s)" % \ 
     996        (db.db.quote_name(m2m_table), 
     997        db.db.quote_name(rel.object_name.lower() + '_id'), 
     998        db.db.quote_name(rel_opts.object_name.lower() + '_id')) 
    970999    cursor.executemany(sql, [(this_id, i) for i in id_list]) 
    9711000    db.db.commit() 
     
    9761005    cursor = db.db.cursor() 
    9771006    # Example: "UPDATE poll_choices SET _order = %s WHERE poll_id = %s AND id = %s" 
    978     sql = "UPDATE %s SET _order = %%s WHERE %s = %%s AND %s = %%s" % (ordered_obj.db_table, ordered_obj.order_with_respect_to.column, ordered_obj.pk.column) 
     1007    sql = "UPDATE %s SET %s = %%s WHERE %s = %%s AND %s = %%s" % \ 
     1008        (db.db.quote_name(ordered_obj.db_table), db.db.quote_name('_order'), 
     1009        db.db.quote_name(ordered_obj.order_with_respect_to.column), 
     1010        db.db.quote_name(ordered_obj.pk.column)) 
    9791011    rel_val = getattr(self, ordered_obj.order_with_respect_to.rel.field_name) 
    9801012    cursor.executemany(sql, [(i, rel_val, j) for i, j in enumerate(id_list)]) 
     
    9841016    cursor = db.db.cursor() 
    9851017    # Example: "SELECT id FROM poll_choices WHERE poll_id = %s ORDER BY _order" 
    986     sql = "SELECT %s FROM %s WHERE %s = %%s ORDER BY _order" % (ordered_obj.pk.column, ordered_obj.db_table, ordered_obj.order_with_respect_to.column) 
     1018    sql = "SELECT %s FROM %s WHERE %s = %%s ORDER BY %s" % \ 
     1019        (db.db.quote_name(ordered_obj.pk.column), 
     1020        db.db.quote_name(ordered_obj.db_table), 
     1021        db.db.quote_name(ordered_obj.order_with_respect_to.column), 
     1022        db.db.quote_name('_order')) 
    9871023    rel_val = getattr(self, ordered_obj.order_with_respect_to.rel.field_name) 
    9881024    cursor.execute(sql, [rel_val]) 
     
    9941030    op = is_next and '>' or '<' 
    9951031    kwargs.setdefault('where', []).append('(%s %s %%s OR (%s = %%s AND %s %s %%s))' % \ 
    996         (field.column, op, field.column, opts.pk.column, op)) 
     1032        (db.db.quote_name(field.column), op, db.db.quote_name(field.column), 
     1033        db.db.quote_name(opts.pk.column), op)) 
    9971034    param = str(getattr(self, field.attname)) 
    9981035    kwargs.setdefault('params', []).extend([param, param, getattr(self, opts.pk.attname)]) 
     
    10811118 
    10821119def _get_where_clause(lookup_type, table_prefix, field_name, value): 
     1120    if table_prefix.endswith('.'): 
     1121        table_prefix = db.db.quote_name(table_prefix[:-1])+'.' 
     1122    field_name = db.db.quote_name(field_name) 
    10831123    try: 
    10841124        return '%s%s %s %%s' % (table_prefix, field_name, db.OPERATOR_MAPPING[lookup_type]) 
     
    11611201    cursor = db.db.cursor() 
    11621202    _, sql, params = function_get_sql_clause(opts, **kwargs) 
    1163     select = ['%s.%s' % (opts.db_table, f) for f in fields] 
     1203    select = ['%s.%s' % (db.db.quote_name(opts.db_table), db.db.quote_name(f)) for f in fields] 
    11641204    cursor.execute("SELECT " + (kwargs.get('distinct') and "DISTINCT " or "") + ",".join(select) + sql, params) 
    11651205    while 1: 
     
    11821222            db_table = f.rel.to.db_table 
    11831223            if db_table not in cache_tables_seen: 
    1184                 tables.append(db_table
     1224                tables.append(db.db.quote_name(db_table)
    11851225            else: # The table was already seen, so give it a table alias. 
    11861226                new_prefix = '%s%s' % (db_table, len(cache_tables_seen)) 
    1187                 tables.append('%s %s' % (db_table, new_prefix)) 
     1227                tables.append('%s %s' % (db.db.quote_name(db_table), db.db.quote_name(new_prefix))) 
    11881228                db_table = new_prefix 
    11891229            cache_tables_seen.append(db_table) 
    1190             where.append('%s.%s = %s.%s' % (old_prefix, f.column, db_table, f.rel.get_related_field().column)) 
    1191             select.extend(['%s.%s' % (db_table, f2.column) for f2 in f.rel.to.fields]) 
     1230            where.append('%s.%s = %s.%s' % \ 
     1231                (db.db.quote_name(old_prefix), db.db.quote_name(f.column), 
     1232                db.db.quote_name(db_table), db.db.quote_name(f.rel.get_related_field().column))) 
     1233            select.extend(['%s.%s' % (db.db.quote_name(db_table), db.db.quote_name(f2.column)) for f2 in f.rel.to.fields]) 
    11921234            _fill_table_cache(f.rel.to, select, tables, where, db_table, cache_tables_seen) 
    11931235 
     
    12481290                for f in current_opts.many_to_many: 
    12491291                    if f.name == current: 
    1250                         rel_table_alias = 't%s' % table_count 
     1292                        rel_table_alias = db.db.quote_name('t%s' % table_count) 
    12511293                        table_count += 1 
    1252                         tables.append('%s %s' % (f.get_m2m_db_table(current_opts), rel_table_alias)) 
    1253                         join_where.append('%s.%s = %s.%s_id' % (current_table_alias, current_opts.pk.column, 
    1254                             rel_table_alias, current_opts.object_name.lower())) 
     1294                        tables.append('%s %s' % \ 
     1295                            (db.db.quote_name(f.get_m2m_db_table(current_opts)), rel_table_alias)) 
     1296                        join_where.append('%s.%s = %s.%s' % \ 
     1297                            (db.db.quote_name(current_table_alias), 
     1298                            db.db.quote_name(current_opts.pk.column), 
     1299                            rel_table_alias, 
     1300                            db.db.quote_name(current_opts.object_name.lower() + '_id'))) 
    12551301                        # Optimization: In the case of primary-key lookups, we 
    12561302                        # don't have to do an extra join. 
     
    12631309                        else: 
    12641310                            new_table_alias = 't%s' % table_count 
    1265                             tables.append('%s %s' % (f.rel.to.db_table, new_table_alias)) 
    1266                             join_where.append('%s.%s_id = %s.%s' % (rel_table_alias, f.rel.to.object_name.lower(), 
    1267                                 new_table_alias, f.rel.to.pk.column)) 
     1311                            tables.append('%s %s' % (db.db.quote_name(f.rel.to.db_table), 
     1312                                db.db.quote_name(new_table_alias))) 
     1313                            join_where.append('%s.%s = %s.%s' % \ 
     1314                                (db.db.quote_name(rel_table_alias), 
     1315                                db.db.quote_name(f.rel.to.object_name.lower() + '_id'), 
     1316                                db.db.quote_name(new_table_alias), 
     1317                                db.db.quote_name(f.rel.to.pk.column))) 
    12681318                            current_table_alias = new_table_alias 
    12691319                            param_required = True 
     
    12881338                        else: 
    12891339                            new_table_alias = 't%s' % table_count 
    1290                             tables.append('%s %s' % (f.rel.to.db_table, new_table_alias)) 
    1291                             join_where.append('%s.%s = %s.%s' % (current_table_alias, f.column, \ 
    1292                                 new_table_alias, f.rel.to.pk.column)) 
     1340                            tables.append('%s %s' % \ 
     1341                                (db.db.quote_name(f.rel.to.db_table), db.db.quote_name(new_table_alias))) 
     1342                            join_where.append('%s.%s = %s.%s' % \ 
     1343                                (db.db.quote_name(current_table_alias), db.db.quote_name(f.column), 
     1344                                db.db.quote_name(new_table_alias), db.db.quote_name(f.rel.to.pk.column))) 
    12931345                            current_table_alias = new_table_alias 
    12941346                            param_required = True 
     
    13091361 
    13101362def function_get_sql_clause(opts, **kwargs): 
    1311     select = ["%s.%s" % (opts.db_table, f.column) for f in opts.fields] 
     1363    select = ["%s.%s" % (db.db.quote_name(opts.db_table), db.db.quote_name(f.column)) for f in opts.fields] 
    13121364    tables = [opts.db_table] + (kwargs.get('tables') and kwargs['tables'][:] or []) 
     1365    tables = [db.db.quote_name(t) for t in tables] 
    13131366    where = kwargs.get('where') and kwargs['where'][:] or [] 
    13141367    params = kwargs.get('params') and kwargs['params'][:] or [] 
     
    13291382    # Add any additional SELECTs passed in via kwargs. 
    13301383    if kwargs.get('select'): 
    1331         select.extend(['(%s) AS %s' % (s[1], s[0]) for s in kwargs['select']]) 
     1384        select.extend(['(%s) AS %s' % (db.db.quote_name(s[1]), db.db.quote_name(s[0])) for s in kwargs['select']]) 
    13321385 
    13331386    # ORDER BY clause 
     
    13431396                col_name = f 
    13441397                order = "ASC" 
    1345             # Use the database table as a column prefix if it wasn't given, 
    1346             # and if the requested column isn't a custom SELECT. 
    1347             if "." not in col_name and col_name not in [k[0] for k in kwargs.get('select', [])]: 
    1348                 table_prefix = opts.db_table + '.' 
     1398            if "." in col_name: 
     1399                table_prefix, col_name = col_name.split('.', 1) 
     1400                table_prefix = db.db.quote_name(table_prefix) + '.' 
    13491401            else: 
    1350                 table_prefix = '' 
    1351             order_by.append('%s%s %s' % (table_prefix, orderfield2column(col_name, opts), order)) 
     1402                # Use the database table as a column prefix if it wasn't given, 
     1403                # and if the requested column isn't a custom SELECT. 
     1404                if "." not in col_name and col_name not in [k[0] for k in kwargs.get('select', [])]: 
     1405                    table_prefix = db.db.quote_name(opts.db_table) + '.' 
     1406                else: 
     1407                    table_prefix = '' 
     1408            order_by.append('%s%s %s' % (table_prefix, db.db.quote_name(orderfield2column(col_name, opts)), order)) 
    13521409    order_by = ", ".join(order_by) 
    13531410 
     
    13641421    id_list = args and args[0] or kwargs['id_list'] 
    13651422    assert id_list != [], "get_in_bulk() cannot be passed an empty list." 
    1366     kwargs['where'] = ["%s.%s IN (%s)" % (opts.db_table, opts.pk.column, ",".join(['%s'] * len(id_list)))] 
     1423    kwargs['where'] = ["%s.%s IN (%s)" % (db.db.quote_name(opts.db_table), db.db.quote_name(opts.pk.column), ",".join(['%s'] * len(id_list)))] 
    13671424    kwargs['params'] = id_list 
    13681425    obj_list = function_get_list(opts, klass, **kwargs) 
     
    13851442    kwargs['order_by'] = [] # Clear this because it'll mess things up otherwise. 
    13861443    if field.null: 
    1387         kwargs.setdefault('where', []).append('%s.%s IS NOT NULL' % (opts.db_table, field.column)) 
     1444        kwargs.setdefault('where', []).append('%s.%s IS NOT NULL' % \ 
     1445            (db.db.quote_name(opts.db_table), db.db.quote_name(field.column))) 
    13881446    select, sql, params = function_get_sql_clause(opts, **kwargs) 
    1389     sql = 'SELECT %s %s GROUP BY 1 ORDER BY 1' % (db.get_date_trunc_sql(kind, '%s.%s' % (opts.db_table, field.column)), sql) 
     1447    sql = 'SELECT %s %s GROUP BY 1 ORDER BY 1' % (db.get_date_trunc_sql(kind, '%s.%s' % (db.db.quote_name(opts.db_table), db.db.quote_name(field.column))), sql) 
    13901448    cursor = db.db.cursor() 
    13911449    cursor.execute(sql, params) 
  • django/trunk/django/models/auth.py

    r1150 r1224  
    9292            import sets 
    9393            cursor = db.cursor() 
    94             cursor.execute(""" 
    95                 SELECT p.package, p.codename 
    96                 FROM auth_permissions p, auth_groups_permissions gp, auth_users_groups ug 
    97                 WHERE p.id = gp.permission_id 
    98                     AND gp.group_id = ug.group_id 
    99                     AND ug.user_id = %s""", [self.id]) 
     94            # The SQL below works out to the following, after DB quoting: 
     95            # cursor.execute(""" 
     96            #     SELECT p.package, p.codename 
     97            #     FROM auth_permissions p, auth_groups_permissions gp, auth_users_groups ug 
     98            #     WHERE p.id = gp.permission_id 
     99            #         AND gp.group_id = ug.group_id 
     100            #         AND ug.user_id = %s""", [self.id]) 
     101            sql = """ 
     102                SELECT p.%s, p.%s 
     103                FROM %s p, %s gp, %s ug 
     104                WHERE p.%s = gp.%s 
     105                    AND gp.%s = ug.%s 
     106                    AND ug.%s = %%s""" % ( 
     107                db.quote_name('package'), db.quote_name('codename'), 
     108                db.quote_name('auth_permissions'), db.quote_name('auth_groups_permissions'), 
     109                db.quote_name('auth_users_groups'), db.quote_name('id'), 
     110                db.quote_name('permission_id'), db.quote_name('group_id'), 
     111                db.quote_name('group_id'), db.quote_name('user_id')) 
     112            cursor.execute(sql, [self.id]) 
    100113            self._group_perm_cache = sets.Set(["%s.%s" % (row[0], row[1]) for row in cursor.fetchall()]) 
    101114        return self._group_perm_cache 
  • django/trunk/docs/model-api.txt

    r1166 r1224  
    3535Each field type, except for ``ForeignKey``, ``ManyToManyField`` and 
    3636``OneToOneField``, takes an optional first positional argument -- a 
    37 human-readable name. If the human-readable name isn't given, Django will use 
    38 the machine-readable name, converting underscores to spaces. 
    39  
    40 Example:: 
     37human-readable name. If the human-readable name isn't given, Django will 
     38automatically create the human-readable name by using the machine-readable 
     39name, converting underscores to spaces. 
     40 
     41In this example, the human-readable name is ``"Person's first name"``:: 
    4142 
    4243    first_name = meta.CharField("Person's first name", maxlength=30) 
    4344 
    44 For ``ForeignKey``, ``ManyToManyField`` and ``OneToOneField``, use the 
    45 ``verbose_name`` keyword argument:: 
     45In this example, the human-readable name is ``"first name"``:: 
     46 
     47    first_name = meta.CharField(maxlength=30) 
     48 
     49``ForeignKey``, ``ManyToManyField`` and ``OneToOneField`` require the first 
     50argument to be a model class, so use the ``verbose_name`` keyword argument to 
     51specify the human-readable name:: 
    4652 
    4753    poll = meta.ForeignKey(Poll, verbose_name="the related poll") 
     
    111117    The name of the database column to use for this field. If this isn't given, 
    112118    Django will use the field's name. 
     119 
     120    If your database column name is an SQL reserved word, or contains 
     121    characters that aren't allowed in Python variable names -- notably, the 
     122    hyphen -- that's OK. Django quotes column and table names behind the 
     123    scenes. 
    113124 
    114125``db_index`` 
     
    701712    If this isn't given, Django will use ``app_label + '_' + module_name``. 
    702713 
     714    If your database table name is an SQL reserved word, or contains characters 
     715    that aren't allowed in Python variable names -- notably, the hyphen -- 
     716    that's OK. Django quotes column and table names behind the scenes. 
     717 
    703718``exceptions`` 
    704719    Names of extra exception subclasses to include in the generated module. 
     
    733748 
    734749    If this isn't given, Django will use a lowercased version of the class 
    735     name, plus "s". This "poor man's pluralization" is intentional: Any other 
    736     level of magic pluralization would get confusing. 
     750    name, plus ``"s"``. This "poor man's pluralization" is intentional: Any 
     751    other level of magic pluralization would get confusing. 
    737752 
    738753``order_with_respect_to`` 
  • django/trunk/tests/testapp/models/__init__.py

    r1147 r1224  
    22           'ordering', 'lookup', 'get_latest', 'm2m_intermediary', 'one_to_one', 
    33           'm2o_recursive', 'm2o_recursive2', 'save_delete_hooks', 'custom_pk', 
    4            'subclassing', 'many_to_one_null', 'custom_columns'
     4           'subclassing', 'many_to_one_null', 'custom_columns', 'reserved_names'