summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorAdrian Holovaty <adrian@holovaty.com>2007-08-25 23:31:05 +0000
committerAdrian Holovaty <adrian@holovaty.com>2007-08-25 23:31:05 +0000
commit22e160945a38f82c7e30f7137b3fcac9dd778fba (patch)
tree7344005e5e8d752db077fe9c0017b7a660995602 /django
parenta6784e6821b284c2f9e7b0def4fdb8cbe1b832fd (diff)
newforms-admin: Merged to [6013]
git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@6014 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django')
-rw-r--r--django/__init__.py3
-rw-r--r--django/contrib/auth/views.py2
-rw-r--r--django/contrib/humanize/templatetags/humanize.py27
-rw-r--r--django/core/management/commands/flush.py2
-rw-r--r--django/core/management/commands/runserver.py4
-rw-r--r--django/core/management/commands/sqlflush.py2
-rw-r--r--django/core/management/sql.py34
-rw-r--r--django/db/backends/dummy/base.py10
-rw-r--r--django/db/backends/oracle/base.py2
-rw-r--r--django/db/backends/postgresql/base.py3
-rw-r--r--django/db/backends/postgresql/operations.py43
-rw-r--r--django/db/backends/postgresql_psycopg2/base.py3
-rw-r--r--django/utils/version.py39
13 files changed, 129 insertions, 45 deletions
diff --git a/django/__init__.py b/django/__init__.py
index b6540949f8..9c5fda133d 100644
--- a/django/__init__.py
+++ b/django/__init__.py
@@ -4,5 +4,6 @@ def get_version():
"Returns the version as a human-format string."
v = '.'.join([str(i) for i in VERSION[:-1]])
if VERSION[-1]:
- v += '-' + VERSION[-1]
+ from django.utils.version import get_svn_revision
+ v = '%s-%s-%s' % (v, VERSION[-1], get_svn_revision())
return v
diff --git a/django/contrib/auth/views.py b/django/contrib/auth/views.py
index 6c40228fab..f1129379d6 100644
--- a/django/contrib/auth/views.py
+++ b/django/contrib/auth/views.py
@@ -17,7 +17,7 @@ def login(request, template_name='registration/login.html'):
errors = manipulator.get_validation_errors(request.POST)
if not errors:
# Light security check -- make sure redirect_to isn't garbage.
- if not redirect_to or '://' in redirect_to or ' ' in redirect_to:
+ if not redirect_to or '//' in redirect_to or ' ' in redirect_to:
from django.conf import settings
redirect_to = settings.LOGIN_REDIRECT_URL
from django.contrib.auth import login
diff --git a/django/contrib/humanize/templatetags/humanize.py b/django/contrib/humanize/templatetags/humanize.py
index 699d9300b8..19591606f9 100644
--- a/django/contrib/humanize/templatetags/humanize.py
+++ b/django/contrib/humanize/templatetags/humanize.py
@@ -1,6 +1,9 @@
from django.utils.translation import ungettext, ugettext as _
from django.utils.encoding import force_unicode
from django import template
+from django.template import defaultfilters
+from django.conf import settings
+from datetime import date, timedelta
import re
register = template.Library()
@@ -67,3 +70,27 @@ def apnumber(value):
return value
return (_('one'), _('two'), _('three'), _('four'), _('five'), _('six'), _('seven'), _('eight'), _('nine'))[value-1]
register.filter(apnumber)
+
+def naturalday(value, arg=None):
+ """
+ For date values that are tomorrow, today or yesterday compared to
+ present day returns representing string. Otherwise, returns a string
+ formatted according to settings.DATE_FORMAT.
+ """
+ try:
+ value = date(value.year, value.month, value.day)
+ except AttributeError:
+ # Passed value wasn't a date object
+ return value
+ except ValueError:
+ # Date arguments out of range
+ return value
+ delta = value - date.today()
+ if delta.days == 0:
+ return _(u'today')
+ elif delta.days == 1:
+ return _(u'tomorrow')
+ elif delta.days == -1:
+ return _(u'yesterday')
+ return defaultfilters.date(value, arg)
+register.filter(naturalday)
diff --git a/django/core/management/commands/flush.py b/django/core/management/commands/flush.py
index bd1dc204d2..395359d269 100644
--- a/django/core/management/commands/flush.py
+++ b/django/core/management/commands/flush.py
@@ -24,7 +24,7 @@ class Command(NoArgsCommand):
except ImportError:
pass
- sql_list = sql_flush(self.style)
+ sql_list = sql_flush(self.style, only_django=True)
if interactive:
confirm = raw_input("""You have requested a flush of the database.
diff --git a/django/core/management/commands/runserver.py b/django/core/management/commands/runserver.py
index f089e80b16..d06744e9fa 100644
--- a/django/core/management/commands/runserver.py
+++ b/django/core/management/commands/runserver.py
@@ -30,7 +30,7 @@ class Command(BaseCommand):
raise CommandError("%r is not a valid port number." % port)
use_reloader = options.get('use_reloader', True)
- admin_media_dir = options.get('admin_media_dir', '')
+ admin_media_path = options.get('admin_media_path', '')
shutdown_message = options.get('shutdown_message', '')
quit_command = (sys.platform == 'win32') and 'CTRL-BREAK' or 'CONTROL-C'
@@ -42,7 +42,7 @@ class Command(BaseCommand):
print "Development server is running at http://%s:%s/" % (addr, port)
print "Quit the server with %s." % quit_command
try:
- path = admin_media_dir or django.__path__[0] + '/contrib/admin/media'
+ path = admin_media_path or django.__path__[0] + '/contrib/admin/media'
handler = AdminMediaHandler(WSGIHandler(), path)
run(addr, int(port), handler)
except WSGIServerException, e:
diff --git a/django/core/management/commands/sqlflush.py b/django/core/management/commands/sqlflush.py
index 7d14fe61e1..261aa0d423 100644
--- a/django/core/management/commands/sqlflush.py
+++ b/django/core/management/commands/sqlflush.py
@@ -7,4 +7,4 @@ class Command(NoArgsCommand):
def handle_noargs(self, **options):
from django.core.management.sql import sql_flush
- return '\n'.join(sql_flush(self.style))
+ return '\n'.join(sql_flush(self.style, only_django=True))
diff --git a/django/core/management/sql.py b/django/core/management/sql.py
index 11056bbf3b..8f7f6a023a 100644
--- a/django/core/management/sql.py
+++ b/django/core/management/sql.py
@@ -13,6 +13,25 @@ def table_list():
cursor = connection.cursor()
return get_introspection_module().get_table_list(cursor)
+def django_table_list(only_existing=False):
+ """
+ Returns a list of all table names that have associated Django models and
+ are in INSTALLED_APPS.
+
+ If only_existing is True, the resulting list will only include the tables
+ that actually exist in the database.
+ """
+ from django.db import models
+ tables = []
+ for app in models.get_apps():
+ for model in models.get_models(app):
+ tables.append(model._meta.db_table)
+ tables.extend([f.m2m_db_table() for f in model._meta.many_to_many])
+ if only_existing:
+ existing = table_list()
+ tables = [t for t in tables if t in existing]
+ return tables
+
def installed_models(table_list):
"Returns a set of all models that are installed, given a list of existing table names."
from django.db import connection, models
@@ -181,10 +200,19 @@ def sql_reset(app, style):
"Returns a list of the DROP TABLE SQL, then the CREATE TABLE SQL, for the given module."
return sql_delete(app, style) + sql_all(app, style)
-def sql_flush(style):
- "Returns a list of the SQL statements used to flush the database."
+def sql_flush(style, only_django=False):
+ """
+ Returns a list of the SQL statements used to flush the database.
+
+ If only_django is True, then only table names that have associated Django
+ models and are in INSTALLED_APPS will be included.
+ """
from django.db import connection
- statements = connection.ops.sql_flush(style, table_list(), sequence_list())
+ if only_django:
+ tables = django_table_list()
+ else:
+ tables = table_list()
+ statements = connection.ops.sql_flush(style, tables, sequence_list())
return statements
def sql_custom(app):
diff --git a/django/db/backends/dummy/base.py b/django/db/backends/dummy/base.py
index 50191f88fe..fd25d3038f 100644
--- a/django/db/backends/dummy/base.py
+++ b/django/db/backends/dummy/base.py
@@ -8,6 +8,7 @@ ImproperlyConfigured.
"""
from django.core.exceptions import ImproperlyConfigured
+from django.db.backends import BaseDatabaseFeatures, BaseDatabaseOperations
def complain(*args, **kwargs):
raise ImproperlyConfigured, "You haven't set the DATABASE_ENGINE setting yet."
@@ -21,13 +22,12 @@ class DatabaseError(Exception):
class IntegrityError(DatabaseError):
pass
-class ComplainOnGetattr(object):
- def __getattr__(self, *args, **kwargs):
- complain()
+class DatabaseOperations(BaseDatabaseOperations):
+ quote_name = complain
class DatabaseWrapper(object):
- features = ComplainOnGetattr()
- ops = ComplainOnGetattr()
+ features = BaseDatabaseFeatures()
+ ops = DatabaseOperations()
operators = {}
cursor = complain
_commit = complain
diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py
index 37cfd85282..23ce30f37e 100644
--- a/django/db/backends/oracle/base.py
+++ b/django/db/backends/oracle/base.py
@@ -70,7 +70,7 @@ class DatabaseOperations(BaseDatabaseOperations):
return "DROP SEQUENCE %s;" % self.quote_name(get_sequence_name(table))
def field_cast_sql(self, db_type):
- if db_type.endswith('LOB'):
+ if db_type and db_type.endswith('LOB'):
return "DBMS_LOB.SUBSTR(%s)"
else:
return "%s"
diff --git a/django/db/backends/postgresql/base.py b/django/db/backends/postgresql/base.py
index ca07ae21d9..c8b87c2dd1 100644
--- a/django/db/backends/postgresql/base.py
+++ b/django/db/backends/postgresql/base.py
@@ -102,9 +102,6 @@ class DatabaseWrapper(BaseDatabaseWrapper):
cursor.execute("SET TIME ZONE %s", [settings.TIME_ZONE])
cursor.execute("SET client_encoding to 'UNICODE'")
cursor = UnicodeCursorWrapper(cursor, 'utf-8')
- if self.ops.postgres_version is None:
- cursor.execute("SELECT version()")
- self.ops.postgres_version = [int(val) for val in cursor.fetchone()[0].split()[1].split('.')]
return cursor
def typecast_string(s):
diff --git a/django/db/backends/postgresql/operations.py b/django/db/backends/postgresql/operations.py
index 21c017038f..9f36596ace 100644
--- a/django/db/backends/postgresql/operations.py
+++ b/django/db/backends/postgresql/operations.py
@@ -4,8 +4,17 @@ from django.db.backends import BaseDatabaseOperations
# used by both the 'postgresql' and 'postgresql_psycopg2' backends.
class DatabaseOperations(BaseDatabaseOperations):
- def __init__(self, postgres_version=None):
- self.postgres_version = postgres_version
+ def __init__(self):
+ self._postgres_version = None
+
+ def _get_postgres_version(self):
+ if self._postgres_version is None:
+ from django.db import connection
+ cursor = connection.cursor()
+ cursor.execute("SELECT version()")
+ self._postgres_version = [int(val) for val in cursor.fetchone()[0].split()[1].split('.')]
+ return self._postgres_version
+ postgres_version = property(_get_postgres_version)
def date_extract_sql(self, lookup_type, field_name):
# http://www.postgresql.org/docs/8.0/static/functions-datetime.html#FUNCTIONS-DATETIME-EXTRACT
@@ -52,28 +61,14 @@ class DatabaseOperations(BaseDatabaseOperations):
for sequence_info in sequences:
table_name = sequence_info['table']
column_name = sequence_info['column']
- if column_name and len(column_name)>0:
- # sequence name in this case will be <table>_<column>_seq
- sql.append("%s %s %s %s %s %s;" % \
- (style.SQL_KEYWORD('ALTER'),
- style.SQL_KEYWORD('SEQUENCE'),
- style.SQL_FIELD(self.quote_name('%s_%s_seq' % (table_name, column_name))),
- style.SQL_KEYWORD('RESTART'),
- style.SQL_KEYWORD('WITH'),
- style.SQL_FIELD('1')
- )
- )
+ if column_name and len(column_name) > 0:
+ sequence_name = '%s_%s_seq' % (table_name, column_name)
else:
- # sequence name in this case will be <table>_id_seq
- sql.append("%s %s %s %s %s %s;" % \
- (style.SQL_KEYWORD('ALTER'),
- style.SQL_KEYWORD('SEQUENCE'),
- style.SQL_FIELD(self.quote_name('%s_id_seq' % table_name)),
- style.SQL_KEYWORD('RESTART'),
- style.SQL_KEYWORD('WITH'),
- style.SQL_FIELD('1')
- )
- )
+ sequence_name = '%s_id_seq' % table_name
+ sql.append("%s setval('%s', 1, false);" % \
+ (style.SQL_KEYWORD('SELECT'),
+ style.SQL_FIELD(self.quote_name(sequence_name)))
+ )
return sql
else:
return []
@@ -106,4 +101,4 @@ class DatabaseOperations(BaseDatabaseOperations):
style.SQL_KEYWORD('IS NOT'),
style.SQL_KEYWORD('FROM'),
style.SQL_TABLE(f.m2m_db_table())))
- return output \ No newline at end of file
+ return output
diff --git a/django/db/backends/postgresql_psycopg2/base.py b/django/db/backends/postgresql_psycopg2/base.py
index 43ca7a1ec5..a7b080d505 100644
--- a/django/db/backends/postgresql_psycopg2/base.py
+++ b/django/db/backends/postgresql_psycopg2/base.py
@@ -64,7 +64,4 @@ class DatabaseWrapper(BaseDatabaseWrapper):
cursor.tzinfo_factory = None
if set_tz:
cursor.execute("SET TIME ZONE %s", [settings.TIME_ZONE])
- if self.ops.postgres_version is None:
- cursor.execute("SELECT version()")
- self.ops.postgres_version = [int(val) for val in cursor.fetchone()[0].split()[1].split('.')]
return cursor
diff --git a/django/utils/version.py b/django/utils/version.py
new file mode 100644
index 0000000000..cf8085653f
--- /dev/null
+++ b/django/utils/version.py
@@ -0,0 +1,39 @@
+import django
+import os.path
+import re
+
+def get_svn_revision(path=None):
+ """
+ Returns the SVN revision in the form SVN-XXXX,
+ where XXXX is the revision number.
+
+ Returns SVN-unknown if anything goes wrong, such as an unexpected
+ format of internal SVN files.
+
+ If path is provided, it should be a directory whose SVN info you want to
+ inspect. If it's not provided, this will use the root django/ package
+ directory.
+ """
+ rev = None
+ if path is None:
+ path = django.__path__[0]
+ entries_path = '%s/.svn/entries' % path
+
+ if os.path.exists(entries_path):
+ entries = open(entries_path, 'r').read()
+ # Versions >= 7 of the entries file are flat text. The first line is
+ # the version number. The next set of digits after 'dir' is the revision.
+ if re.match('(\d+)', entries):
+ rev_match = re.search('\d+\s+dir\s+(\d+)', entries)
+ if rev_match:
+ rev = rev_match.groups()[0]
+ # Older XML versions of the file specify revision as an attribute of
+ # the first entries node.
+ else:
+ from xml.dom import minidom
+ dom = minidom.parse(entries_path)
+ rev = dom.getElementsByTagName('entry')[0].getAttribute('revision')
+
+ if rev:
+ return u'SVN-%s' % rev
+ return u'SVN-unknown'