Changeset 1224
- Timestamp:
- 11/13/05 19:44:35 (3 years ago)
- Files:
-
- django/trunk/django/bin/daily_cleanup.py (modified) (1 diff)
- django/trunk/django/core/db/backends/ado_mssql.py (modified) (1 diff)
- django/trunk/django/core/db/backends/postgresql.py (modified) (1 diff)
- django/trunk/django/core/management.py (modified) (19 diffs)
- django/trunk/django/core/meta/__init__.py (modified) (22 diffs)
- django/trunk/django/models/auth.py (modified) (1 diff)
- django/trunk/docs/model-api.txt (modified) (4 diffs)
- django/trunk/tests/testapp/models/__init__.py (modified) (1 diff)
- django/trunk/tests/testapp/models/reserved_names.py (added)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/trunk/django/bin/daily_cleanup.py
r518 r1224 8 8 # Clean up old database records 9 9 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'))) 12 14 db.commit() 13 15 django/trunk/django/core/db/backends/ado_mssql.py
r1213 r1224 150 150 'OneToOneField': 'int', 151 151 '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)', 154 154 'SlugField': 'varchar(50)', 155 155 'SmallIntegerField': 'smallint', django/trunk/django/core/db/backends/postgresql.py
r1213 r1224 171 171 'OneToOneField': 'integer', 172 172 '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)', 175 175 'SlugField': 'varchar(50)', 176 176 'SmallIntegerField': 'smallint', django/trunk/django/core/management.py
r1151 r1224 20 20 21 21 def _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) 23 26 24 27 def _get_permission_codename(action, opts): … … 34 37 35 38 def _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) 38 43 39 44 def _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) 42 49 43 50 def _is_valid_dir_name(s): … … 65 72 col_type = db.DATA_TYPES[data_type] 66 73 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__] 68 75 field_output.append('%sNULL' % (not f.null and 'NOT ' or '')) 69 76 if f.unique: … … 73 80 if f.rel: 74 81 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))) 76 84 table_output.append(' '.join(field_output)) 77 85 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'])) 79 87 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)] 83 92 for i, line in enumerate(table_output): # Combine and add commas. 84 93 full_statement.append(' %s%s' % (line, i < len(table_output)-1 and ',' or '')) … … 89 98 opts = klass._meta 90 99 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'))) 98 115 table_output.append(');') 99 116 final_output.append('\n'.join(table_output)) … … 115 132 if cursor is not None: 116 133 # 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')) 118 135 except: 119 136 # The table doesn't exist, so it doesn't need to be dropped. … … 130 147 if cursor is not None: 131 148 # 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)) 133 150 except: 134 151 # The table doesn't exist, so it doesn't need to be dropped. 135 152 db.db.rollback() 136 153 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)) 138 155 139 156 # Output DROP TABLE statements for many-to-many tables. … … 143 160 try: 144 161 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))) 146 163 except: 147 164 db.db.rollback() 148 165 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))) 150 167 151 168 app_label = mod._MODELS[0]._meta.app_label 152 169 153 170 # 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)) 157 177 158 178 # Delete from the admin log. 159 179 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]) 161 183 if admin_log_exists: 162 184 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])) 164 187 165 188 # Close database connection explicitly, in case this output is being piped … … 207 230 def get_sql_sequence_reset(mod): 208 231 "Returns a list of the SQL statements to reset PostgreSQL sequences for the given module." 209 from django.core import meta232 from django.core import db, meta 210 233 output = [] 211 234 for klass in mod._MODELS: 212 235 for f in klass._meta.fields: 213 236 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))) 215 240 return output 216 241 get_sql_sequence_reset.help_doc = "Prints the SQL statements for resetting PostgreSQL sequences for the given model module name(s)." … … 219 244 def get_sql_indexes(mod): 220 245 "Returns a list of the CREATE INDEX SQL statements for the given module." 246 from django.core.db import db 221 247 output = [] 222 248 for klass in mod._MODELS: … … 225 251 unique = f.unique and "UNIQUE " or "" 226 252 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))) 228 255 return output 229 256 get_sql_indexes.help_doc = "Prints the CREATE INDEX SQL statements for the given model module name(s)." … … 243 270 244 271 # 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]) 246 274 if cursor.rowcount < 1: 247 275 # sys.stderr.write("The '%s' package isn't installed.\n" % app_label) … … 257 285 contenttypes_seen[opts.module_name] = 1 258 286 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)) 260 290 if cursor.rowcount < 1: 261 291 # sys.stderr.write("The '%s.%s' permission doesn't exist.\n" % (app_label, codename)) 262 292 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)) 264 296 if cursor.rowcount < 1: 265 297 # sys.stderr.write("The '%s.%s' content type doesn't exist.\n" % (app_label, opts.module_name)) … … 268 300 # Check that there aren't any *extra* permissions in the DB that the model 269 301 # 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,)) 271 305 for row in cursor.fetchall(): 272 306 try: … … 274 308 except KeyError: 275 309 # 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]) 277 313 278 314 # Check that there aren't any *extra* content types in the DB that the 279 315 # 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,)) 281 319 for row in cursor.fetchall(): 282 320 try: … … 284 322 except KeyError: 285 323 # 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]) 287 327 database_check.help_doc = "Checks that everything is installed in the database for the given model module name(s) and prints SQL statements if needed." 288 328 database_check.args = APP_ARGS … … 319 359 for sql in get_sql_create(core) + get_sql_create(auth) + get_sql_initial_data(core) + get_sql_initial_data(auth): 320 360 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'))) 322 364 except Exception, e: 323 365 sys.stderr.write("Error: The database couldn't be initialized.\n%s\n" % e) … … 688 730 index_output = [] 689 731 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__] 691 733 field_output.append("%sNULL" % (not f.null and "NOT " or "")) 692 734 if f.unique: … … 696 738 if f.db_index: 697 739 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))) 699 743 table_output.append(" ".join(field_output)) 700 full_statement = ["CREATE TABLE %s (" % tablename]744 full_statement = ["CREATE TABLE %s (" % db.db.quote_name(tablename)] 701 745 for i, line in enumerate(table_output): 702 746 full_statement.append(' %s%s' % (line, i < len(table_output)-1 and ',' or '')) django/trunk/django/core/meta/__init__.py
r1155 r1224 58 58 59 59 def orderlist2sql(order_list, opts, prefix=''): 60 if prefix.endswith('.'): 61 prefix = db.db.quote_name(prefix[:-1]) + '.' 60 62 output = [] 61 63 for f in handle_legacy_orderlist(order_list): 62 64 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)))) 64 66 elif f == '?': 65 67 output.append(db.get_random_function_sql()) 66 68 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)))) 68 70 return ', '.join(output) 69 71 … … 786 788 if pk_set: 787 789 # 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]) 789 792 # If it does already exist, do an UPDATE. 790 793 if cursor.fetchone(): 791 794 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)), 794 799 db_values + [pk_val]) 795 800 else: 796 801 record_exists = False 797 802 if not pk_set or not record_exists: 798 field_names = [ f.columnfor 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)] 799 804 placeholders = ['%s'] * len(field_names) 800 805 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)] 801 806 if opts.order_with_respect_to: 802 field_names.append( '_order')807 field_names.append(db.db.quote_name('_order')) 803 808 # TODO: This assumes the database supports subqueries. 804 809 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))) 806 811 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) 809 815 if opts.has_auto_field: 810 816 setattr(self, opts.pk.attname, db.get_last_insert_id(cursor, opts.db_table, opts.pk.column)) … … 833 839 sub_obj.delete() 834 840 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)]) 837 844 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')), 839 848 [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)]) 841 852 db.db.commit() 842 853 setattr(self, opts.pk.attname, None) … … 855 866 if not hasattr(self, '_next_in_order_cache'): 856 867 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, 859 872 params=[getattr(self, opts.pk.attname), getattr(self, order_field.attname)]) 860 873 return self._next_in_order_cache … … 863 876 if not hasattr(self, '_previous_in_order_cache'): 864 877 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, 867 882 params=[getattr(self, opts.pk.attname), getattr(self, order_field.attname)]) 868 883 return self._previous_in_order_cache … … 889 904 if not hasattr(self, cache_var): 890 905 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')) 895 913 cursor = db.db.cursor() 896 914 cursor.execute(sql, [getattr(self, self._meta.pk.attname)]) … … 917 935 this_id = getattr(self, self._meta.pk.attname) 918 936 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))) 920 941 cursor.execute(sql, [this_id]) 921 942 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')) 923 947 cursor.executemany(sql, [(this_id, i) for i in ids_to_add]) 924 948 db.db.commit() … … 966 990 this_id = getattr(self, self._meta.pk.attname) 967 991 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')) 970 999 cursor.executemany(sql, [(this_id, i) for i in id_list]) 971 1000 db.db.commit() … … 976 1005 cursor = db.db.cursor() 977 1006 # 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)) 979 1011 rel_val = getattr(self, ordered_obj.order_with_respect_to.rel.field_name) 980 1012 cursor.executemany(sql, [(i, rel_val, j) for i, j in enumerate(id_list)]) … … 984 1016 cursor = db.db.cursor() 985 1017 # 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')) 987 1023 rel_val = getattr(self, ordered_obj.order_with_respect_to.rel.field_name) 988 1024 cursor.execute(sql, [rel_val]) … … 994 1030 op = is_next and '>' or '<' 995 1031 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)) 997 1034 param = str(getattr(self, field.attname)) 998 1035 kwargs.setdefault('params', []).extend([param, param, getattr(self, opts.pk.attname)]) … … 1081 1118 1082 1119 def _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) 1083 1123 try: 1084 1124 return '%s%s %s %%s' % (table_prefix, field_name, db.OPERATOR_MAPPING[lookup_type]) … … 1161 1201 cursor = db.db.cursor() 1162 1202 _, 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] 1164 1204 cursor.execute("SELECT " + (kwargs.get('distinct') and "DISTINCT " or "") + ",".join(select) + sql, params) 1165 1205 while 1: … … 1182 1222 db_table = f.rel.to.db_table 1183 1223 if db_table not in cache_tables_seen: 1184 tables.append(db _table)1224 tables.append(db.db.quote_name(db_table)) 1185 1225 else: # The table was already seen, so give it a table alias. 1186 1226 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))) 1188 1228 db_table = new_prefix 1189 1229 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]) 1192 1234 _fill_table_cache(f.rel.to, select, tables, where, db_table, cache_tables_seen) 1193 1235 … … 1248 1290 for f in current_opts.many_to_many: 1249 1291 if f.name == current: 1250 rel_table_alias = 't%s' % table_count1292 rel_table_alias = db.db.quote_name('t%s' % table_count) 1251 1293 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'))) 1255 1301 # Optimization: In the case of primary-key lookups, we 1256 1302 # don't have to do an extra join. … … 1263 1309 else: 1264 1310 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))) 1268 1318 current_table_alias = new_table_alias 1269 1319 param_required = True … … 1288 1338 else: 1289 1339 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))) 1293 1345 current_table_alias = new_table_alias 1294 1346 param_required = True … … 1309 1361 1310 1362 def 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] 1312 1364 tables = [opts.db_table] + (kwargs.get('tables') and kwargs['tables'][:] or []) 1365 tables = [db.db.quote_name(t) for t in tables] 1313 1366 where = kwargs.get('where') and kwargs['where'][:] or [] 1314 1367 params = kwargs.get('params') and kwargs['params'][:] or [] … … 1329 1382 # Add any additional SELECTs passed in via kwargs. 1330 1383 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']]) 1332 1385 1333 1386 # ORDER BY clause … … 1343 1396 col_name = f 1344 1397 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) + '.' 1349 1401 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)) 1352 1409 order_by = ", ".join(order_by) 1353 1410 … … 1364 1421 id_list = args and args[0] or kwargs['id_list'] 1365 1422 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)))] 1367 1424 kwargs['params'] = id_list 1368 1425 obj_list = function_get_list(opts, klass, **kwargs) … … 1385 1442 kwargs['order_by'] = [] # Clear this because it'll mess things up otherwise. 1386 1443 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))) 1388 1446 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) 1390 1448 cursor = db.db.cursor() 1391 1449 cursor.execute(sql, params) django/trunk/django/models/auth.py
r1150 r1224 92 92 import sets 93 93 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]) 100 113 self._group_perm_cache = sets.Set(["%s.%s" % (row[0], row[1]) for row in cursor.fetchall()]) 101 114 return self._group_perm_cache django/trunk/docs/model-api.txt
r1166 r1224 35 35 Each field type, except for ``ForeignKey``, ``ManyToManyField`` and 36 36 ``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:: 37 human-readable name. If the human-readable name isn't given, Django will 38 automatically create the human-readable name by using the machine-readable 39 name, converting underscores to spaces. 40 41 In this example, the human-readable name is ``"Person's first name"``:: 41 42 42 43 first_name = meta.CharField("Person's first name", maxlength=30) 43 44 44 For ``ForeignKey``, ``ManyToManyField`` and ``OneToOneField``, use the 45 ``verbose_name`` keyword argument:: 45 In 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 50 argument to be a model class, so use the ``verbose_name`` keyword argument to 51 specify the human-readable name:: 46 52 47 53 poll = meta.ForeignKey(Poll, verbose_name="the related poll") … … 111 117 The name of the database column to use for this field. If this isn't given, 112 118 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. 113 124 114 125 ``db_index`` … … 701 712 If this isn't given, Django will use ``app_label + '_' + module_name``. 702 713 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 703 718 ``exceptions`` 704 719 Names of extra exception subclasses to include in the generated module. … … 733 748 734 749 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 other736 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. 737 752 738 753 ``order_with_respect_to`` django/trunk/tests/testapp/models/__init__.py
r1147 r1224 2 2 'ordering', 'lookup', 'get_latest', 'm2m_intermediary', 'one_to_one', 3 3 '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']
