From d29c457ad108ddc52e990b582b36cacc5eb0bb68 Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Sat, 15 Sep 2007 21:35:33 +0000 Subject: [PATCH] queryset-refactor: Merged to [6197] git-svn-id: http://code.djangoproject.com/svn/django/branches/queryset-refactor@6335 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- AUTHORS | 1 + django/contrib/admin/media/css/null.css | 1 + django/core/management/sql.py | 5 ++-- django/db/backends/__init__.py | 2 +- django/db/backends/creation.py | 7 ++++++ django/db/backends/oracle/base.py | 15 +++++++----- django/db/models/fields/__init__.py | 8 ++++++- django/db/models/options.py | 2 +- django/test/_doctest.py | 10 +++++++- docs/newforms.txt | 2 +- docs/settings.txt | 24 ++++++++++--------- tests/regressiontests/model_regress/models.py | 5 ++++ 12 files changed, 58 insertions(+), 24 deletions(-) create mode 100644 django/contrib/admin/media/css/null.css create mode 100644 django/db/backends/creation.py diff --git a/AUTHORS b/AUTHORS index cb69ebd0b0..1e56bd3412 100644 --- a/AUTHORS +++ b/AUTHORS @@ -278,6 +278,7 @@ answer newbie questions, and generally made Django that much better: Frank Tegtmeyer thebjorn Zach Thompson + Deepak Thukral tibimicu@gmax.net tobias@neuyork.de Tom Tobin diff --git a/django/contrib/admin/media/css/null.css b/django/contrib/admin/media/css/null.css new file mode 100644 index 0000000000..1a93f22058 --- /dev/null +++ b/django/contrib/admin/media/css/null.css @@ -0,0 +1 @@ +/* Nothing to see here. Dummy file to feed to the high pass filter which hides CSS from IE5/win. Details: http://tantek.com/CSS/Examples/highpass.html */ \ No newline at end of file diff --git a/django/core/management/sql.py b/django/core/management/sql.py index 8f7f6a023a..ed76bc4e35 100644 --- a/django/core/management/sql.py +++ b/django/core/management/sql.py @@ -302,7 +302,8 @@ def sql_model_create(model, style, known_models=set()): if opts.has_auto_field: # Add any extra SQL needed to support auto-incrementing primary keys. - autoinc_sql = connection.ops.autoinc_sql(opts.db_table) + auto_column = opts.auto_field.db_column or opts.auto_field.name + autoinc_sql = connection.ops.autoinc_sql(opts.db_table, auto_column) if autoinc_sql: for stmt in autoinc_sql: final_output.append(stmt) @@ -385,7 +386,7 @@ def many_to_many_sql_for_model(model, style): final_output.append('\n'.join(table_output)) # Add any extra SQL needed to support auto-incrementing PKs - autoinc_sql = connection.ops.autoinc_sql(f.m2m_db_table()) + autoinc_sql = connection.ops.autoinc_sql(f.m2m_db_table(), 'id') if autoinc_sql: for stmt in autoinc_sql: final_output.append(stmt) diff --git a/django/db/backends/__init__.py b/django/db/backends/__init__.py index f3c6f59258..1b6ba07f24 100644 --- a/django/db/backends/__init__.py +++ b/django/db/backends/__init__.py @@ -56,7 +56,7 @@ class BaseDatabaseOperations(object): a backend performs ordering or calculates the ID of a recently-inserted row. """ - def autoinc_sql(self, table): + def autoinc_sql(self, table, column): """ Returns any SQL needed to support auto-incrementing primary keys, or None if no SQL is necessary. diff --git a/django/db/backends/creation.py b/django/db/backends/creation.py new file mode 100644 index 0000000000..4071cef6aa --- /dev/null +++ b/django/db/backends/creation.py @@ -0,0 +1,7 @@ +class BaseCreation(object): + """ + This class encapsulates all backend-specific differences that pertain to + database *creation*, such as the column types to use for particular Django + Fields. + """ + pass diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py index 23ce30f37e..4093b69be6 100644 --- a/django/db/backends/oracle/base.py +++ b/django/db/backends/oracle/base.py @@ -31,20 +31,23 @@ class DatabaseFeatures(BaseDatabaseFeatures): uses_custom_queryset = True class DatabaseOperations(BaseDatabaseOperations): - def autoinc_sql(self, table): + def autoinc_sql(self, table, column): # To simulate auto-incrementing primary keys in Oracle, we have to # create a sequence and a trigger. sq_name = get_sequence_name(table) tr_name = get_trigger_name(table) + tbl_name = self.quote_name(table) + col_name = self.quote_name(column) sequence_sql = 'CREATE SEQUENCE %s;' % sq_name trigger_sql = """ - CREATE OR REPLACE TRIGGER %s - BEFORE INSERT ON %s + CREATE OR REPLACE TRIGGER %(tr_name)s + BEFORE INSERT ON %(tbl_name)s FOR EACH ROW - WHEN (new.id IS NULL) + WHEN (new.%(col_name)s IS NULL) BEGIN - SELECT %s.nextval INTO :new.id FROM dual; - END;/""" % (tr_name, self.quote_name(table), sq_name) + SELECT %(sq_name)s.nextval + INTO :new.%(col_name)s FROM dual; + END;/""" % locals() return sequence_sql, trigger_sql def date_extract_sql(self, lookup_type, field_name): diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index af28e5f441..7e6a7cd258 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -440,6 +440,7 @@ class AutoField(Field): assert not cls._meta.has_auto_field, "A model can't have more than one AutoField." super(AutoField, self).contribute_to_class(cls, name) cls._meta.has_auto_field = True + cls._meta.auto_field = self def formfield(self, **kwargs): return None @@ -545,7 +546,12 @@ class DateField(Field): def get_db_prep_save(self, value): # Casts dates into string format for entry into database. if value is not None: - value = value.strftime('%Y-%m-%d') + try: + value = value.strftime('%Y-%m-%d') + except AttributeError: + # If value is already a string it won't have a strftime method, + # so we'll just let it pass through. + pass return Field.get_db_prep_save(self, value) def get_manipulator_field_objs(self): diff --git a/django/db/models/options.py b/django/db/models/options.py index ad813ae0f7..502cbc4a65 100644 --- a/django/db/models/options.py +++ b/django/db/models/options.py @@ -33,7 +33,7 @@ class Options(object): self.admin = None self.meta = meta self.pk = None - self.has_auto_field = False + self.has_auto_field, self.auto_field = False, None self.one_to_one_field = None self.parents = [] diff --git a/django/test/_doctest.py b/django/test/_doctest.py index 8777a2cbba..3589e16225 100644 --- a/django/test/_doctest.py +++ b/django/test/_doctest.py @@ -1,5 +1,5 @@ # This is a slightly modified version of the doctest.py that shipped with Python 2.4 -# It incorporates changes that have been submitted the the Python ticket tracker +# It incorporates changes that have been submitted the the Python ticket tracker # as ticket #1521051. These changes allow for a DoctestRunner and Doctest base # class to be specified when constructing a DoctestSuite. @@ -105,6 +105,14 @@ import unittest, difflib, pdb, tempfile import warnings from StringIO import StringIO +if sys.platform.startswith('java'): + # On Jython, isclass() reports some modules as classes. Patch it. + def patch_isclass(isclass): + def patched_isclass(obj): + return isclass(obj) and hasattr(obj, '__module__') + return patched_isclass + inspect.isclass = patch_isclass(inspect.isclass) + # Don't whine about the deprecated is_private function in this # module's tests. warnings.filterwarnings("ignore", "is_private", DeprecationWarning, diff --git a/docs/newforms.txt b/docs/newforms.txt index 10fa15a1c4..e9e98944a0 100644 --- a/docs/newforms.txt +++ b/docs/newforms.txt @@ -985,7 +985,7 @@ validation if a particular field's value is not given. ``initial`` values are ~~~~~~~~~~ The ``widget`` argument lets you specify a ``Widget`` class to use when -rendering this ``Field``. See "Widgets"_ below for more information. +rendering this ``Field``. See `Widgets`_ below for more information. ``help_text`` ~~~~~~~~~~~~~ diff --git a/docs/settings.txt b/docs/settings.txt index 3f98296778..97fc985175 100644 --- a/docs/settings.txt +++ b/docs/settings.txt @@ -325,7 +325,8 @@ The default formatting to use for date fields on Django admin change-list pages -- and, possibly, by other parts of the system. See `allowed date format strings`_. -See also DATETIME_FORMAT, TIME_FORMAT, YEAR_MONTH_FORMAT and MONTH_DAY_FORMAT. +See also ``DATETIME_FORMAT``, ``TIME_FORMAT``, ``YEAR_MONTH_FORMAT`` +and ``MONTH_DAY_FORMAT``. .. _allowed date format strings: ../templates/#now @@ -338,7 +339,8 @@ The default formatting to use for datetime fields on Django admin change-list pages -- and, possibly, by other parts of the system. See `allowed date format strings`_. -See also DATE_FORMAT, DATETIME_FORMAT, TIME_FORMAT, YEAR_MONTH_FORMAT and MONTH_DAY_FORMAT. +See also ``DATE_FORMAT``, ``DATETIME_FORMAT``, ``TIME_FORMAT``, +``YEAR_MONTH_FORMAT`` and ``MONTH_DAY_FORMAT``. .. _allowed date format strings: ../templates/#now @@ -350,8 +352,8 @@ Default: ``False`` A boolean that turns on/off debug mode. If you define custom settings, django/views/debug.py has a ``HIDDEN_SETTINGS`` -regular expression which will hide from the DEBUG view anything that contins -``'SECRET``, ``PASSWORD``, or ``PROFANITIES'``. This allows untrusted users to +regular expression which will hide from the DEBUG view anything that contains +``'SECRET'``, ``'PASSWORD'``, or ``'PROFANITIES'``. This allows untrusted users to be able to give backtraces without seeing sensitive (or offensive) settings. Still, note that there are always going to be sections of your debug output that @@ -656,8 +658,8 @@ drilldown, the header for a given day displays the day and month. Different locales have different formats. For example, U.S. English would say "January 1," whereas Spanish might say "1 Enero." -See `allowed date format strings`_. See also DATE_FORMAT, DATETIME_FORMAT, -TIME_FORMAT and YEAR_MONTH_FORMAT. +See `allowed date format strings`_. See also ``DATE_FORMAT``, +``DATETIME_FORMAT``, ``TIME_FORMAT`` and ``YEAR_MONTH_FORMAT``. PREPEND_WWW ----------- @@ -815,7 +817,7 @@ highlighted. Note that Django only displays fancy error pages if ``DEBUG`` is ``True``, so you'll want to set that to take advantage of this setting. -See also DEBUG. +See also ``DEBUG``. TEMPLATE_DIRS ------------- @@ -905,8 +907,8 @@ The default formatting to use for time fields on Django admin change-list pages -- and, possibly, by other parts of the system. See `allowed date format strings`_. -See also DATE_FORMAT, DATETIME_FORMAT, TIME_FORMAT, YEAR_MONTH_FORMAT and -MONTH_DAY_FORMAT. +See also ``DATE_FORMAT``, ``DATETIME_FORMAT``, ``TIME_FORMAT``, +``YEAR_MONTH_FORMAT`` and ``MONTH_DAY_FORMAT``. .. _allowed date format strings: ../templates/#now @@ -980,8 +982,8 @@ drilldown, the header for a given month displays the month and the year. Different locales have different formats. For example, U.S. English would say "January 2006," whereas another locale might say "2006/January." -See `allowed date format strings`_. See also DATE_FORMAT, DATETIME_FORMAT, -TIME_FORMAT and MONTH_DAY_FORMAT. +See `allowed date format strings`_. See also ``DATE_FORMAT``, +``DATETIME_FORMAT``, ``TIME_FORMAT`` and ``MONTH_DAY_FORMAT``. .. _cache docs: ../cache/ .. _middleware docs: ../middleware/ diff --git a/tests/regressiontests/model_regress/models.py b/tests/regressiontests/model_regress/models.py index 7aa9e2a7c4..00c3bc96f0 100644 --- a/tests/regressiontests/model_regress/models.py +++ b/tests/regressiontests/model_regress/models.py @@ -20,6 +20,11 @@ class Article(models.Model): def __unicode__(self): return self.headline +class Movie(models.Model): + #5218: Test models with non-default primary keys / AutoFields + movie_id = models.AutoField(primary_key=True) + name = models.CharField(max_length=60) + __test__ = {'API_TESTS': """ (NOTE: Part of the regression test here is merely parsing the model declaration. The verbose_name, in particular, did not always work.)