summaryrefslogtreecommitdiff
path: root/django/core
diff options
context:
space:
mode:
authorRobin Munn <robin.munn@gmail.com>2006-10-24 07:49:37 +0000
committerRobin Munn <robin.munn@gmail.com>2006-10-24 07:49:37 +0000
commit0b059aa4eadc1d95ceca3a32821b65a9fb2a53e8 (patch)
tree76f84c62e3ac5cd5172d43dd73a651bb8574e2d1 /django/core
parent1bb4fa2cb66269b1eff3b7d73f8c7864c0622368 (diff)
sqlalchemy: Merged revisions 3832 to 3917 from trunk.
git-svn-id: http://code.djangoproject.com/svn/django/branches/sqlalchemy@3918 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django/core')
-rw-r--r--django/core/handlers/base.py35
-rw-r--r--django/core/handlers/modpython.py37
-rw-r--r--django/core/handlers/wsgi.py8
-rw-r--r--django/core/management.py114
-rw-r--r--django/core/servers/basehttp.py2
-rw-r--r--django/core/urlresolvers.py3
-rw-r--r--django/core/validators.py4
7 files changed, 110 insertions, 93 deletions
diff --git a/django/core/handlers/base.py b/django/core/handlers/base.py
index 62217acdce..213c528952 100644
--- a/django/core/handlers/base.py
+++ b/django/core/handlers/base.py
@@ -48,7 +48,7 @@ class BaseHandler(object):
if hasattr(mw_instance, 'process_exception'):
self._exception_middleware.insert(0, mw_instance.process_exception)
- def get_response(self, path, request):
+ def get_response(self, request):
"Returns an HttpResponse object for the given HttpRequest"
from django.core import exceptions, urlresolvers
from django.core.mail import mail_admins
@@ -62,7 +62,7 @@ class BaseHandler(object):
resolver = urlresolvers.RegexURLResolver(r'^/', settings.ROOT_URLCONF)
try:
- callback, callback_args, callback_kwargs = resolver.resolve(path)
+ callback, callback_args, callback_kwargs = resolver.resolve(request.path)
# Apply view middleware
for middleware_method in self._view_middleware:
@@ -89,7 +89,8 @@ class BaseHandler(object):
return response
except http.Http404, e:
if settings.DEBUG:
- return self.get_technical_error_response(request, is404=True, exception=e)
+ from django.views import debug
+ return debug.technical_404_response(request, e)
else:
callback, param_dict = resolver.resolve404()
return callback(request, **param_dict)
@@ -99,39 +100,23 @@ class BaseHandler(object):
pass # See http://code.djangoproject.com/ticket/1023
except: # Handle everything else, including SuspiciousOperation, etc.
if settings.DEBUG:
- return self.get_technical_error_response(request)
+ from django.views import debug
+ return debug.technical_500_response(request, *sys.exc_info())
else:
# Get the exception info now, in case another exception is thrown later.
exc_info = sys.exc_info()
receivers = dispatcher.send(signal=signals.got_request_exception)
# When DEBUG is False, send an error message to the admins.
- subject = 'Error (%s IP): %s' % ((request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS and 'internal' or 'EXTERNAL'), getattr(request, 'path', ''))
+ subject = 'Error (%s IP): %s' % ((request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS and 'internal' or 'EXTERNAL'), request.path)
try:
request_repr = repr(request)
except:
request_repr = "Request repr() unavailable"
message = "%s\n\n%s" % (self._get_traceback(exc_info), request_repr)
mail_admins(subject, message, fail_silently=True)
- return self.get_friendly_error_response(request, resolver)
-
- def get_friendly_error_response(self, request, resolver):
- """
- Returns an HttpResponse that displays a PUBLIC error message for a
- fundamental error.
- """
- callback, param_dict = resolver.resolve500()
- return callback(request, **param_dict)
-
- def get_technical_error_response(self, request, is404=False, exception=None):
- """
- Returns an HttpResponse that displays a TECHNICAL error message for a
- fundamental error.
- """
- from django.views import debug
- if is404:
- return debug.technical_404_response(request, exception)
- else:
- return debug.technical_500_response(request, *sys.exc_info())
+ # Return an HttpResponse that displays a friendly error message.
+ callback, param_dict = resolver.resolve500()
+ return callback(request, **param_dict)
def _get_traceback(self, exc_info=None):
"Helper function to return the traceback as a string"
diff --git a/django/core/handlers/modpython.py b/django/core/handlers/modpython.py
index 41d9a578c5..bf759db068 100644
--- a/django/core/handlers/modpython.py
+++ b/django/core/handlers/modpython.py
@@ -102,7 +102,7 @@ class ModPythonRequest(http.HttpRequest):
'REQUEST_METHOD': self._req.method,
'SCRIPT_NAME': None, # Not supported
'SERVER_NAME': self._req.server.server_hostname,
- 'SERVER_PORT': self._req.server.port,
+ 'SERVER_PORT': str(self._req.connection.local_addr[1]),
'SERVER_PROTOCOL': self._req.protocol,
'SERVER_SOFTWARE': 'mod_python'
}
@@ -139,10 +139,6 @@ class ModPythonHandler(BaseHandler):
# that use settings now can work
from django.conf import settings
- if settings.ENABLE_PSYCO:
- import psyco
- psyco.profile()
-
# if we need to set up middleware, now that settings works we can do it now.
if self._request_middleware is None:
self.load_middleware()
@@ -150,7 +146,7 @@ class ModPythonHandler(BaseHandler):
dispatcher.send(signal=signals.request_started)
try:
request = ModPythonRequest(req)
- response = self.get_response(req.uri, request)
+ response = self.get_response(request)
# Apply response middleware
for middleware_method in self._response_middleware:
@@ -160,23 +156,20 @@ class ModPythonHandler(BaseHandler):
dispatcher.send(signal=signals.request_finished)
# Convert our custom HttpResponse object back into the mod_python req.
- populate_apache_request(response, req)
- return 0 # mod_python.apache.OK
+ req.content_type = response['Content-Type']
+ for key, value in response.headers.items():
+ if key != 'Content-Type':
+ req.headers_out[key] = value
+ for c in response.cookies.values():
+ req.headers_out.add('Set-Cookie', c.output(header=''))
+ req.status = response.status_code
+ try:
+ for chunk in response:
+ req.write(chunk)
+ finally:
+ response.close()
-def populate_apache_request(http_response, mod_python_req):
- "Populates the mod_python request object with an HttpResponse"
- mod_python_req.content_type = http_response['Content-Type']
- for key, value in http_response.headers.items():
- if key != 'Content-Type':
- mod_python_req.headers_out[key] = value
- for c in http_response.cookies.values():
- mod_python_req.headers_out.add('Set-Cookie', c.output(header=''))
- mod_python_req.status = http_response.status_code
- try:
- for chunk in http_response:
- mod_python_req.write(chunk)
- finally:
- http_response.close()
+ return 0 # mod_python.apache.OK
def handler(req):
# mod_python hooks into this function.
diff --git a/django/core/handlers/wsgi.py b/django/core/handlers/wsgi.py
index 85e234c8d2..2998bd31f6 100644
--- a/django/core/handlers/wsgi.py
+++ b/django/core/handlers/wsgi.py
@@ -74,7 +74,7 @@ class WSGIRequest(http.HttpRequest):
def __init__(self, environ):
self.environ = environ
self.path = environ['PATH_INFO']
- self.META = environ
+ self.META = environ
self.method = environ['REQUEST_METHOD'].upper()
def __repr__(self):
@@ -174,10 +174,6 @@ class WSGIHandler(BaseHandler):
def __call__(self, environ, start_response):
from django.conf import settings
- if settings.ENABLE_PSYCO:
- import psyco
- psyco.profile()
-
# Set up middleware if needed. We couldn't do this earlier, because
# settings weren't available.
if self._request_middleware is None:
@@ -186,7 +182,7 @@ class WSGIHandler(BaseHandler):
dispatcher.send(signal=signals.request_started)
try:
request = WSGIRequest(environ)
- response = self.get_response(request.path, request)
+ response = self.get_response(request)
# Apply response middleware
for middleware_method in self._response_middleware:
diff --git a/django/core/management.py b/django/core/management.py
index 87e5053791..5e709db6ac 100644
--- a/django/core/management.py
+++ b/django/core/management.py
@@ -103,7 +103,6 @@ def get_sql_create(app):
known_models = set([model for model in _get_installed_models(_get_table_list()) if model not in app_models])
pending_references = {}
-
for model in app_models:
output, references = _get_sql_model_create(model, known_models)
final_output.extend(output)
@@ -147,7 +146,7 @@ def _get_sql_model_create(model, known_models=set()):
table_output = []
pending_references = {}
for f in opts.fields:
- if isinstance(f, models.ForeignKey):
+ if isinstance(f, (models.ForeignKey, models.OneToOneField)):
rel_field = f.rel.get_related_field()
data_type = get_rel_data_type(rel_field)
else:
@@ -398,32 +397,39 @@ get_sql_sequence_reset.help_doc = "Prints the SQL statements for resetting Postg
get_sql_sequence_reset.args = APP_ARGS
def get_sql_indexes(app):
- "Returns a list of the CREATE INDEX SQL statements for the given app."
- from django.db import backend, models
+ "Returns a list of the CREATE INDEX SQL statements for all models in the given app."
+ from django.db import models
output = []
-
for model in models.get_models(app):
- for f in model._meta.fields:
- if f.db_index:
- unique = f.unique and 'UNIQUE ' or ''
- output.append(
- style.SQL_KEYWORD('CREATE %sINDEX' % unique) + ' ' + \
- style.SQL_TABLE('%s_%s' % (model._meta.db_table, f.column)) + ' ' + \
- style.SQL_KEYWORD('ON') + ' ' + \
- style.SQL_TABLE(backend.quote_name(model._meta.db_table)) + ' ' + \
- "(%s);" % style.SQL_FIELD(backend.quote_name(f.column))
- )
+ output.extend(get_sql_indexes_for_model(model))
return output
get_sql_indexes.help_doc = "Prints the CREATE INDEX SQL statements for the given model module name(s)."
get_sql_indexes.args = APP_ARGS
+def get_sql_indexes_for_model(model):
+ "Returns the CREATE INDEX SQL statements for a single model"
+ from django.db import backend
+ output = []
+
+ for f in model._meta.fields:
+ if f.db_index:
+ unique = f.unique and 'UNIQUE ' or ''
+ output.append(
+ style.SQL_KEYWORD('CREATE %sINDEX' % unique) + ' ' + \
+ style.SQL_TABLE('%s_%s' % (model._meta.db_table, f.column)) + ' ' + \
+ style.SQL_KEYWORD('ON') + ' ' + \
+ style.SQL_TABLE(backend.quote_name(model._meta.db_table)) + ' ' + \
+ "(%s);" % style.SQL_FIELD(backend.quote_name(f.column))
+ )
+ return output
+
def get_sql_all(app):
"Returns a list of CREATE TABLE SQL, initial-data inserts, and CREATE INDEX SQL for the given module."
return get_sql_create(app) + get_sql_initial_data(app) + get_sql_indexes(app)
get_sql_all.help_doc = "Prints the CREATE TABLE, initial-data and CREATE INDEX SQL statements for the given model module name(s)."
get_sql_all.args = APP_ARGS
-def syncdb(verbosity=2, interactive=True):
+def syncdb(verbosity=1, interactive=True):
"Creates the database tables for all apps in INSTALLED_APPS whose tables haven't already been created."
from django.db import connection, transaction, models, get_creation_module
from django.db.models import signals
@@ -457,21 +463,21 @@ def syncdb(verbosity=2, interactive=True):
pending_references = {}
for app in models.get_apps():
+ app_name = app.__name__.split('.')[-2]
model_list = models.get_models(app)
for model in model_list:
# Create the model's database table, if it doesn't already exist.
+ if verbosity >= 2:
+ print "Processing %s.%s model" % (app_name, model._meta.object_name)
if model._meta.db_table in table_list:
continue
sql, references = _get_sql_model_create(model, seen_models)
seen_models.add(model)
created_models.add(model)
for refto, refs in references.items():
- try:
- pending_references[refto].extend(refs)
- except KeyError:
- pending_references[refto] = refs
+ pending_references.setdefault(refto, []).extend(refs)
sql.extend(_get_sql_for_pending_references(model, pending_references))
- if verbosity >= 2:
+ if verbosity >= 1:
print "Creating table %s" % model._meta.db_table
for statement in sql:
cursor.execute(statement)
@@ -482,7 +488,7 @@ def syncdb(verbosity=2, interactive=True):
sql = _get_many_to_many_sql_for_model(model)
if sql:
if verbosity >= 2:
- print "Creating many-to-many tables for %s model" % model.__name__
+ print "Creating many-to-many tables for %s.%s model" % (app_name, model._meta.object_name)
for statement in sql:
cursor.execute(statement)
@@ -491,6 +497,9 @@ def syncdb(verbosity=2, interactive=True):
# Send the post_syncdb signal, so individual apps can do whatever they need
# to do at this point.
for app in models.get_apps():
+ app_name = app.__name__.split('.')[-2]
+ if verbosity >= 2:
+ print "Running post-sync handlers for application", app_name
dispatcher.send(signal=signals.post_syncdb, sender=app,
app=app, created_models=created_models,
verbosity=verbosity, interactive=interactive)
@@ -501,18 +510,37 @@ def syncdb(verbosity=2, interactive=True):
if model in created_models:
initial_sql = get_sql_initial_data_for_model(model)
if initial_sql:
- if verbosity >= 2:
- print "Installing initial data for %s model" % model._meta.object_name
+ if verbosity >= 1:
+ print "Installing initial data for %s.%s model" % (app_name, model._meta.object_name)
try:
for sql in initial_sql:
cursor.execute(sql)
except Exception, e:
- sys.stderr.write("Failed to install initial SQL data for %s model: %s" % \
- (model._meta.object_name, e))
+ sys.stderr.write("Failed to install initial SQL data for %s.%s model: %s" % \
+ (app_name, model._meta.object_name, e))
transaction.rollback_unless_managed()
else:
transaction.commit_unless_managed()
+ # Install SQL indicies for all newly created models
+ for app in models.get_apps():
+ app_name = app.__name__.split('.')[-2]
+ for model in models.get_models(app):
+ if model in created_models:
+ index_sql = get_sql_indexes_for_model(model)
+ if index_sql:
+ if verbosity >= 1:
+ print "Installing index for %s.%s model" % (app_name, model._meta.object_name)
+ try:
+ for sql in index_sql:
+ cursor.execute(sql)
+ except Exception, e:
+ sys.stderr.write("Failed to install index for %s.%s model: %s" % \
+ (app_name, model._meta.object_name, e))
+ transaction.rollback_unless_managed()
+ else:
+ transaction.commit_unless_managed()
+
syncdb.args = ''
def get_admin_index(app):
@@ -596,7 +624,7 @@ The full error: """ % (app_name, app_name)) + style.ERROR_OUTPUT(str(e)) + '\n')
install.help_doc = "Executes ``sqlall`` for the given app(s) in the current database."
install.args = APP_ARGS
-def reset(app):
+def reset(app, interactive=True):
"Executes the equivalent of 'get_sql_reset' in the current database."
from django.db import connection, transaction
app_name = app.__name__.split('.')[-2]
@@ -607,21 +635,25 @@ def reset(app):
_check_for_validation_errors(app)
sql_list = get_sql_reset(app)
- confirm = raw_input("""
+ if interactive:
+ confirm = raw_input("""
You have requested a database reset.
This will IRREVERSIBLY DESTROY any data in your database.
Are you sure you want to do this?
Type 'yes' to continue, or 'no' to cancel: """)
+ else:
+ confirm = 'yes'
+
if confirm == 'yes':
try:
cursor = connection.cursor()
for sql in sql_list:
cursor.execute(sql)
except Exception, e:
- sys.stderr.write(style.ERROR("""Error: %s couldn't be installed. Possible reasons:
+ sys.stderr.write(style.ERROR("""Error: %s couldn't be reset. Possible reasons:
* The database isn't running or isn't configured correctly.
- * At least one of the database tables already exists.
+ * At least one of the database tables doesn't exist.
* The SQL was invalid.
Hint: Look at the output of 'django-admin.py sqlreset %s'. That's the SQL this command wasn't able to run.
The full error: """ % (app_name, app_name)) + style.ERROR_OUTPUT(str(e)) + '\n')
@@ -820,7 +852,8 @@ def get_validation_errors(outfile, app=None):
validates all models of all installed apps. Writes errors, if any, to outfile.
Returns number of errors.
"""
- from django.db import models
+ from django.conf import settings
+ from django.db import models, connection
from django.db.models.loading import get_app_errors
from django.db.models.fields.related import RelatedObject
@@ -862,6 +895,12 @@ def get_validation_errors(outfile, app=None):
if f.db_index not in (None, True, False):
e.add(opts, '"%s": "db_index" should be either None, True or False.' % f.name)
+ # Check that maxlength <= 255 if using older MySQL versions.
+ if settings.DATABASE_ENGINE == 'mysql':
+ db_version = connection.get_server_version()
+ if db_version < (5, 0, 3) and isinstance(f, (models.CharField, models.CommaSeparatedIntegerField, models.SlugField)) and f.maxlength > 255:
+ e.add(opts, '"%s": %s cannot have a "maxlength" greater than 255 when you are using a version of MySQL prior to 5.0.3 (you are using %s).' % (f.name, f.__class__.__name__, '.'.join([str(n) for n in db_version[:3]])))
+
# Check to see if the related field will clash with any
# existing fields, m2m fields, m2m related objects or related objects
if f.rel:
@@ -1169,7 +1208,7 @@ def runfcgi(args):
runfastcgi(args)
runfcgi.args = '[various KEY=val options, use `runfcgi help` for help]'
-def test(verbosity, app_labels):
+def test(app_labels, verbosity=1):
"Runs the test suite for the specified applications"
from django.conf import settings
from django.db.models import get_app, get_apps
@@ -1271,10 +1310,10 @@ def execute_from_command_line(action_mapping=DEFAULT_ACTION_MAPPING, argv=None):
help='Tells Django to NOT prompt the user for input of any kind.')
parser.add_option('--noreload', action='store_false', dest='use_reloader', default=True,
help='Tells Django to NOT use the auto-reloader when running the development server.')
- parser.add_option('--verbosity', action='store', dest='verbosity', default='2',
+ parser.add_option('--verbosity', action='store', dest='verbosity', default='1',
type='choice', choices=['0', '1', '2'],
help='Verbosity level; 0=minimal output, 1=normal output, 2=all output'),
- parser.add_option('--adminmedia', dest='admin_media_path', default='', help='Lets you manually specify the directory to serve admin media from when running the development server.'),
+ parser.add_option('--adminmedia', dest='admin_media_path', default='', help='Specifies the directory from which to serve admin media for runserver.'),
options, args = parser.parse_args(argv[1:])
@@ -1320,7 +1359,7 @@ def execute_from_command_line(action_mapping=DEFAULT_ACTION_MAPPING, argv=None):
parser.print_usage_and_exit()
elif action == 'test':
try:
- action_mapping[action](int(options.verbosity), args[1:])
+ action_mapping[action](args[1:], int(options.verbosity))
except IndexError:
parser.print_usage_and_exit()
elif action in ('startapp', 'startproject'):
@@ -1354,7 +1393,10 @@ def execute_from_command_line(action_mapping=DEFAULT_ACTION_MAPPING, argv=None):
if action not in NO_SQL_TRANSACTION:
print style.SQL_KEYWORD("BEGIN;")
for mod in mod_list:
- output = action_mapping[action](mod)
+ if action == 'reset':
+ output = action_mapping[action](mod, options.interactive)
+ else:
+ output = action_mapping[action](mod)
if output:
print '\n'.join(output)
if action not in NO_SQL_TRANSACTION:
diff --git a/django/core/servers/basehttp.py b/django/core/servers/basehttp.py
index fe534d5da0..a16b8b675a 100644
--- a/django/core/servers/basehttp.py
+++ b/django/core/servers/basehttp.py
@@ -594,7 +594,7 @@ class AdminMediaHandler(object):
Use this ONLY LOCALLY, for development! This hasn't been tested for
security and is not super efficient.
"""
- def __init__(self, application, media_dir = None):
+ def __init__(self, application, media_dir=None):
from django.conf import settings
self.application = application
if not media_dir:
diff --git a/django/core/urlresolvers.py b/django/core/urlresolvers.py
index 2f557b90a6..45705cb223 100644
--- a/django/core/urlresolvers.py
+++ b/django/core/urlresolvers.py
@@ -15,7 +15,8 @@ class Resolver404(Http404):
pass
class NoReverseMatch(Exception):
- pass
+ # Don't make this raise an error when used in a template.
+ silent_variable_failure = True
def get_mod_func(callback):
# Converts 'django.views.news.stories.story_detail' to
diff --git a/django/core/validators.py b/django/core/validators.py
index f2f3f44914..4c3f59143e 100644
--- a/django/core/validators.py
+++ b/django/core/validators.py
@@ -249,7 +249,7 @@ def hasNoProfanities(field_data, all_data):
Watch your mouth! The words "f--k" and "s--t" are not allowed here.
"""
field_data = field_data.lower() # normalize
- words_seen = [w for w in settings.PROFANITIES_LIST if field_data.find(w) > -1]
+ words_seen = [w for w in settings.PROFANITIES_LIST if w in field_data]
if words_seen:
from django.utils.text import get_text_list
plural = len(words_seen) > 1
@@ -377,7 +377,7 @@ class IsValidFloat(object):
if len(data) > max_allowed_length:
raise ValidationError, ngettext("Please enter a valid decimal number with at most %s total digit.",
"Please enter a valid decimal number with at most %s total digits.", self.max_digits) % self.max_digits
- if (not '.' in data and len(data) > (max_allowed_length - self.decimal_places)) or ('.' in data and len(data) > (self.max_digits - (self.decimal_places - len(data.split('.')[1])) + 1)):
+ if (not '.' in data and len(data) > (max_allowed_length - self.decimal_places - 1)) or ('.' in data and len(data) > (max_allowed_length - (self.decimal_places - len(data.split('.')[1])))):
raise ValidationError, ngettext( "Please enter a valid decimal number with a whole part of at most %s digit.",
"Please enter a valid decimal number with a whole part of at most %s digits.", str(self.max_digits-self.decimal_places)) % str(self.max_digits-self.decimal_places)
if '.' in data and len(data.split('.')[1]) > self.decimal_places: