mirror of
https://github.com/django/django.git
synced 2025-07-04 09:49:12 +00:00
[multi-db] Merged trunk to [3890]
git-svn-id: http://code.djangoproject.com/svn/django/branches/multiple-db-support@4152 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
261fb45ba8
commit
e07dae7b77
1
AUTHORS
1
AUTHORS
@ -75,6 +75,7 @@ answer newbie questions, and generally made Django that much better:
|
|||||||
Jeremy Dunck <http://dunck.us/>
|
Jeremy Dunck <http://dunck.us/>
|
||||||
Andy Dustman <farcepest@gmail.com>
|
Andy Dustman <farcepest@gmail.com>
|
||||||
Clint Ecker
|
Clint Ecker
|
||||||
|
Enrico <rico.bl@gmail.com>
|
||||||
favo@exoweb.net
|
favo@exoweb.net
|
||||||
gandalf@owca.info
|
gandalf@owca.info
|
||||||
Baishampayan Ghose
|
Baishampayan Ghose
|
||||||
|
@ -226,10 +226,6 @@ YEAR_MONTH_FORMAT = 'F Y'
|
|||||||
# http://www.djangoproject.com/documentation/templates/#now
|
# http://www.djangoproject.com/documentation/templates/#now
|
||||||
MONTH_DAY_FORMAT = 'F j'
|
MONTH_DAY_FORMAT = 'F j'
|
||||||
|
|
||||||
# Whether to enable Psyco, which optimizes Python code. Requires Psyco.
|
|
||||||
# http://psyco.sourceforge.net/
|
|
||||||
ENABLE_PSYCO = False
|
|
||||||
|
|
||||||
# Do you want to manage transactions manually?
|
# Do you want to manage transactions manually?
|
||||||
# Hint: you really don't!
|
# Hint: you really don't!
|
||||||
TRANSACTIONS_MANAGED = False
|
TRANSACTIONS_MANAGED = False
|
||||||
|
@ -87,7 +87,7 @@ def staff_member_required(view_func):
|
|||||||
|
|
||||||
# The user data is correct; log in the user in and continue.
|
# The user data is correct; log in the user in and continue.
|
||||||
else:
|
else:
|
||||||
if user.is_staff:
|
if user.is_active and user.is_staff:
|
||||||
login(request, user)
|
login(request, user)
|
||||||
# TODO: set last_login with an event.
|
# TODO: set last_login with an event.
|
||||||
user.last_login = datetime.datetime.now()
|
user.last_login = datetime.datetime.now()
|
||||||
|
@ -216,6 +216,8 @@ class User(models.Model):
|
|||||||
|
|
||||||
def has_module_perms(self, app_label):
|
def has_module_perms(self, app_label):
|
||||||
"Returns True if the user has any permissions in the given app label."
|
"Returns True if the user has any permissions in the given app label."
|
||||||
|
if not self.is_active:
|
||||||
|
return False
|
||||||
if self.is_superuser:
|
if self.is_superuser:
|
||||||
return True
|
return True
|
||||||
return bool(len([p for p in self.get_all_permissions() if p[:p.index('.')] == app_label]))
|
return bool(len([p for p in self.get_all_permissions() if p[:p.index('.')] == app_label]))
|
||||||
|
@ -89,7 +89,8 @@ class BaseHandler(object):
|
|||||||
return response
|
return response
|
||||||
except http.Http404, e:
|
except http.Http404, e:
|
||||||
if settings.DEBUG:
|
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:
|
else:
|
||||||
callback, param_dict = resolver.resolve404()
|
callback, param_dict = resolver.resolve404()
|
||||||
return callback(request, **param_dict)
|
return callback(request, **param_dict)
|
||||||
@ -99,7 +100,8 @@ class BaseHandler(object):
|
|||||||
pass # See http://code.djangoproject.com/ticket/1023
|
pass # See http://code.djangoproject.com/ticket/1023
|
||||||
except: # Handle everything else, including SuspiciousOperation, etc.
|
except: # Handle everything else, including SuspiciousOperation, etc.
|
||||||
if settings.DEBUG:
|
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:
|
else:
|
||||||
# Get the exception info now, in case another exception is thrown later.
|
# Get the exception info now, in case another exception is thrown later.
|
||||||
exc_info = sys.exc_info()
|
exc_info = sys.exc_info()
|
||||||
@ -112,26 +114,9 @@ class BaseHandler(object):
|
|||||||
request_repr = "Request repr() unavailable"
|
request_repr = "Request repr() unavailable"
|
||||||
message = "%s\n\n%s" % (self._get_traceback(exc_info), request_repr)
|
message = "%s\n\n%s" % (self._get_traceback(exc_info), request_repr)
|
||||||
mail_admins(subject, message, fail_silently=True)
|
mail_admins(subject, message, fail_silently=True)
|
||||||
return self.get_friendly_error_response(request, resolver)
|
# Return an HttpResponse that displays a friendly error message.
|
||||||
|
callback, param_dict = resolver.resolve500()
|
||||||
def get_friendly_error_response(self, request, resolver):
|
return callback(request, **param_dict)
|
||||||
"""
|
|
||||||
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())
|
|
||||||
|
|
||||||
def _get_traceback(self, exc_info=None):
|
def _get_traceback(self, exc_info=None):
|
||||||
"Helper function to return the traceback as a string"
|
"Helper function to return the traceback as a string"
|
||||||
|
@ -139,10 +139,6 @@ class ModPythonHandler(BaseHandler):
|
|||||||
# that use settings now can work
|
# that use settings now can work
|
||||||
from django.conf import settings
|
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 we need to set up middleware, now that settings works we can do it now.
|
||||||
if self._request_middleware is None:
|
if self._request_middleware is None:
|
||||||
self.load_middleware()
|
self.load_middleware()
|
||||||
@ -160,23 +156,20 @@ class ModPythonHandler(BaseHandler):
|
|||||||
dispatcher.send(signal=signals.request_finished)
|
dispatcher.send(signal=signals.request_finished)
|
||||||
|
|
||||||
# Convert our custom HttpResponse object back into the mod_python req.
|
# Convert our custom HttpResponse object back into the mod_python req.
|
||||||
populate_apache_request(response, req)
|
req.content_type = response['Content-Type']
|
||||||
return 0 # mod_python.apache.OK
|
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):
|
return 0 # mod_python.apache.OK
|
||||||
"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()
|
|
||||||
|
|
||||||
def handler(req):
|
def handler(req):
|
||||||
# mod_python hooks into this function.
|
# mod_python hooks into this function.
|
||||||
|
@ -174,10 +174,6 @@ class WSGIHandler(BaseHandler):
|
|||||||
def __call__(self, environ, start_response):
|
def __call__(self, environ, start_response):
|
||||||
from django.conf import settings
|
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
|
# Set up middleware if needed. We couldn't do this earlier, because
|
||||||
# settings weren't available.
|
# settings weren't available.
|
||||||
if self._request_middleware is None:
|
if self._request_middleware is None:
|
||||||
|
@ -230,7 +230,6 @@ def get_sql_indexes(app):
|
|||||||
from django.db import model_connection_name
|
from django.db import model_connection_name
|
||||||
from django.db.models import get_models
|
from django.db.models import get_models
|
||||||
connection_output = {}
|
connection_output = {}
|
||||||
|
|
||||||
for model in get_models(app):
|
for model in get_models(app):
|
||||||
opts = model._meta
|
opts = model._meta
|
||||||
connection_name = model_connection_name(model)
|
connection_name = model_connection_name(model)
|
||||||
@ -242,6 +241,23 @@ def get_sql_indexes(app):
|
|||||||
get_sql_indexes.help_doc = "Prints the CREATE INDEX SQL statements for the given model module name(s)."
|
get_sql_indexes.help_doc = "Prints the CREATE INDEX SQL statements for the given model module name(s)."
|
||||||
get_sql_indexes.args = APP_ARGS
|
get_sql_indexes.args = APP_ARGS
|
||||||
|
|
||||||
|
def _get_sql_index(model):
|
||||||
|
"Returns the CREATE INDEX SQL statements for a specific 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):
|
def get_sql_all(app):
|
||||||
"Returns a list of CREATE TABLE SQL, initial-data inserts, and CREATE INDEX SQL for the given module."
|
"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)
|
return get_sql_create(app) + get_sql_initial_data(app) + get_sql_indexes(app)
|
||||||
@ -269,7 +285,7 @@ def _collate(connection_output, reverse=False):
|
|||||||
connection_name)
|
connection_name)
|
||||||
return map(str, final_output)
|
return map(str, final_output)
|
||||||
|
|
||||||
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."
|
"Creates the database tables for all apps in INSTALLED_APPS whose tables haven't already been created."
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db import models, transaction
|
from django.db import models, transaction
|
||||||
@ -296,8 +312,9 @@ def syncdb(verbosity=2, interactive=True):
|
|||||||
for app in models.get_apps():
|
for app in models.get_apps():
|
||||||
# Install each application (models already installed will be skipped)
|
# Install each application (models already installed will be skipped)
|
||||||
created, pending = _install(app, commit=False, initial_data=False,
|
created, pending = _install(app, commit=False, initial_data=False,
|
||||||
pending_allowed=True, pending=pending)
|
pending_allowed=True, pending=pending,
|
||||||
if verbosity >= 2:
|
verbosity=verbosity)
|
||||||
|
if verbosity >= 1:
|
||||||
for model in created:
|
for model in created:
|
||||||
print "Created table %s" % model._meta.db_table
|
print "Created table %s" % model._meta.db_table
|
||||||
created_models.extend(created)
|
created_models.extend(created)
|
||||||
@ -311,6 +328,8 @@ def syncdb(verbosity=2, interactive=True):
|
|||||||
# Send the post_syncdb signal, so individual apps can do whatever they need
|
# Send the post_syncdb signal, so individual apps can do whatever they need
|
||||||
# to do at this point.
|
# to do at this point.
|
||||||
for app in models.get_apps():
|
for app in models.get_apps():
|
||||||
|
if verbosity >= 2:
|
||||||
|
print "Sending post-syncdb signal for application", app.__name__.split('.')[-2]
|
||||||
dispatcher.send(signal=signals.post_syncdb, sender=app,
|
dispatcher.send(signal=signals.post_syncdb, sender=app,
|
||||||
app=app, created_models=created_models,
|
app=app, created_models=created_models,
|
||||||
verbosity=verbosity, interactive=interactive)
|
verbosity=verbosity, interactive=interactive)
|
||||||
@ -322,7 +341,7 @@ def syncdb(verbosity=2, interactive=True):
|
|||||||
if model in created_models:
|
if model in created_models:
|
||||||
try:
|
try:
|
||||||
if (model._default_manager.load_initial_data()
|
if (model._default_manager.load_initial_data()
|
||||||
and verbosity >= 2):
|
and verbosity >= 1):
|
||||||
print "Installed initial data for %s model" % model._meta.object_name
|
print "Installed initial data for %s model" % model._meta.object_name
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
sys.stderr.write("Failed to install initial SQL data for %s model: %s" % \
|
sys.stderr.write("Failed to install initial SQL data for %s model: %s" % \
|
||||||
@ -391,7 +410,7 @@ def install(app):
|
|||||||
_install(app)
|
_install(app)
|
||||||
|
|
||||||
def _install(app, commit=True, initial_data=True, pending_allowed=False,
|
def _install(app, commit=True, initial_data=True, pending_allowed=False,
|
||||||
pending=None):
|
pending=None, verbosity=1):
|
||||||
from django.db import connection, models, transaction
|
from django.db import connection, models, transaction
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
@ -407,6 +426,9 @@ def _install(app, commit=True, initial_data=True, pending_allowed=False,
|
|||||||
if pending is None:
|
if pending is None:
|
||||||
pending = {}
|
pending = {}
|
||||||
for model in models.get_models(app, creation_order=True):
|
for model in models.get_models(app, creation_order=True):
|
||||||
|
if verbosity >= 2:
|
||||||
|
print "Processing %s.%s model" % (app_name,
|
||||||
|
model._meta.object_name)
|
||||||
manager = model._default_manager
|
manager = model._default_manager
|
||||||
tables = manager.get_table_list()
|
tables = manager.get_table_list()
|
||||||
models_installed = manager.get_installed_models(tables)
|
models_installed = manager.get_installed_models(tables)
|
||||||
@ -445,7 +467,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.help_doc = "Executes ``sqlall`` for the given app(s) in the current database."
|
||||||
install.args = APP_ARGS
|
install.args = APP_ARGS
|
||||||
|
|
||||||
def reset(app):
|
def reset(app, interactive=True):
|
||||||
"Executes the equivalent of 'get_sql_reset' in the current database."
|
"Executes the equivalent of 'get_sql_reset' in the current database."
|
||||||
from django.db import connection, transaction
|
from django.db import connection, transaction
|
||||||
app_name = app.__name__.split('.')[-2]
|
app_name = app.__name__.split('.')[-2]
|
||||||
@ -456,21 +478,25 @@ def reset(app):
|
|||||||
_check_for_validation_errors(app)
|
_check_for_validation_errors(app)
|
||||||
sql_list = get_sql_reset(app)
|
sql_list = get_sql_reset(app)
|
||||||
|
|
||||||
confirm = raw_input("""
|
if interactive:
|
||||||
|
confirm = raw_input("""
|
||||||
You have requested a database reset.
|
You have requested a database reset.
|
||||||
This will IRREVERSIBLY DESTROY any data in your database.
|
This will IRREVERSIBLY DESTROY any data in your database.
|
||||||
Are you sure you want to do this?
|
Are you sure you want to do this?
|
||||||
|
|
||||||
Type 'yes' to continue, or 'no' to cancel: """)
|
Type 'yes' to continue, or 'no' to cancel: """)
|
||||||
|
else:
|
||||||
|
confirm = 'yes'
|
||||||
|
|
||||||
if confirm == 'yes':
|
if confirm == 'yes':
|
||||||
try:
|
try:
|
||||||
cursor = connection.cursor()
|
cursor = connection.cursor()
|
||||||
for sql in sql_list:
|
for sql in sql_list:
|
||||||
cursor.execute(sql)
|
cursor.execute(sql)
|
||||||
except Exception, e:
|
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.
|
* 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.
|
* 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.
|
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')
|
The full error: """ % (app_name, app_name)) + style.ERROR_OUTPUT(str(e)) + '\n')
|
||||||
@ -1031,7 +1057,7 @@ def runfcgi(args):
|
|||||||
runfastcgi(args)
|
runfastcgi(args)
|
||||||
runfcgi.args = '[various KEY=val options, use `runfcgi help` for help]'
|
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"
|
"Runs the test suite for the specified applications"
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db.models import get_app, get_apps
|
from django.db.models import get_app, get_apps
|
||||||
@ -1133,7 +1159,7 @@ 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.')
|
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,
|
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.')
|
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'],
|
type='choice', choices=['0', '1', '2'],
|
||||||
help='Verbosity level; 0=minimal output, 1=normal output, 2=all output'),
|
help='Verbosity level; 0=minimal output, 1=normal output, 2=all output'),
|
||||||
parser.add_option('--adminmedia', dest='admin_media_path', default='', help='Specifies the directory from which to serve admin media for runserver.'),
|
parser.add_option('--adminmedia', dest='admin_media_path', default='', help='Specifies the directory from which to serve admin media for runserver.'),
|
||||||
@ -1182,7 +1208,7 @@ def execute_from_command_line(action_mapping=DEFAULT_ACTION_MAPPING, argv=None):
|
|||||||
parser.print_usage_and_exit()
|
parser.print_usage_and_exit()
|
||||||
elif action == 'test':
|
elif action == 'test':
|
||||||
try:
|
try:
|
||||||
action_mapping[action](int(options.verbosity), args[1:])
|
action_mapping[action](args[1:], int(options.verbosity))
|
||||||
except IndexError:
|
except IndexError:
|
||||||
parser.print_usage_and_exit()
|
parser.print_usage_and_exit()
|
||||||
elif action in ('startapp', 'startproject'):
|
elif action in ('startapp', 'startproject'):
|
||||||
@ -1216,7 +1242,10 @@ def execute_from_command_line(action_mapping=DEFAULT_ACTION_MAPPING, argv=None):
|
|||||||
if action not in NO_SQL_TRANSACTION:
|
if action not in NO_SQL_TRANSACTION:
|
||||||
print style.SQL_KEYWORD("BEGIN;")
|
print style.SQL_KEYWORD("BEGIN;")
|
||||||
for mod in mod_list:
|
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:
|
if output:
|
||||||
print '\n'.join(output)
|
print '\n'.join(output)
|
||||||
if action not in NO_SQL_TRANSACTION:
|
if action not in NO_SQL_TRANSACTION:
|
||||||
|
@ -82,7 +82,7 @@ There are also a few styles for styling text.
|
|||||||
.help
|
.help
|
||||||
This is a custom class for blocks of inline help text explaining the
|
This is a custom class for blocks of inline help text explaining the
|
||||||
function of form elements. It makes text smaller and gray, and when applied
|
function of form elements. It makes text smaller and gray, and when applied
|
||||||
to ``p`` elements withing ``.form-row`` elements (see Form Styles below),
|
to ``p`` elements within ``.form-row`` elements (see Form Styles below),
|
||||||
it will offset the text to align with the form field. Use this for help
|
it will offset the text to align with the form field. Use this for help
|
||||||
text, instead of ``small quiet``. It works on other elements, but try to
|
text, instead of ``small quiet``. It works on other elements, but try to
|
||||||
put the class on a ``p`` whenever you can.
|
put the class on a ``p`` whenever you can.
|
||||||
@ -170,4 +170,4 @@ Labels
|
|||||||
Form labels should always precede the field, except in the case
|
Form labels should always precede the field, except in the case
|
||||||
of checkboxes and radio buttons, where the ``input`` should come first. Any
|
of checkboxes and radio buttons, where the ``input`` should come first. Any
|
||||||
explanation or help text should follow the ``label`` in a ``p`` with class
|
explanation or help text should follow the ``label`` in a ``p`` with class
|
||||||
``.help``.
|
``.help``.
|
||||||
|
@ -82,7 +82,7 @@ that 90% of Django can be considered forwards-compatible at this point.
|
|||||||
That said, these APIs should *not* be considered stable, and are likely to
|
That said, these APIs should *not* be considered stable, and are likely to
|
||||||
change:
|
change:
|
||||||
|
|
||||||
- `Forms and validation`_ will most likely be compeltely rewritten to
|
- `Forms and validation`_ will most likely be completely rewritten to
|
||||||
deemphasize Manipulators in favor of validation-aware models.
|
deemphasize Manipulators in favor of validation-aware models.
|
||||||
|
|
||||||
- `Serialization`_ is under heavy development; changes are likely.
|
- `Serialization`_ is under heavy development; changes are likely.
|
||||||
@ -91,7 +91,7 @@ change:
|
|||||||
API changes may be necessary.
|
API changes may be necessary.
|
||||||
|
|
||||||
- Generic relations will most likely be moved out of core and into the
|
- Generic relations will most likely be moved out of core and into the
|
||||||
content-types contrib package to avoid core dependacies on optional
|
content-types contrib package to avoid core dependancies on optional
|
||||||
components.
|
components.
|
||||||
|
|
||||||
- The comments framework, which is yet undocumented, will likely get a complete
|
- The comments framework, which is yet undocumented, will likely get a complete
|
||||||
|
@ -66,8 +66,8 @@ Fields
|
|||||||
long and can contain any character. See the "Passwords" section below.
|
long and can contain any character. See the "Passwords" section below.
|
||||||
* ``is_staff`` -- Boolean. Designates whether this user can access the
|
* ``is_staff`` -- Boolean. Designates whether this user can access the
|
||||||
admin site.
|
admin site.
|
||||||
* ``is_active`` -- Boolean. Designates whether this user can log into the
|
* ``is_active`` -- Boolean. Designates whether this account can be used
|
||||||
Django admin. Set this to ``False`` instead of deleting accounts.
|
to log in. Set this flag to ``False`` instead of deleting accounts.
|
||||||
* ``is_superuser`` -- Boolean. Designates that this user has all permissions
|
* ``is_superuser`` -- Boolean. Designates that this user has all permissions
|
||||||
without explicitly assigning them.
|
without explicitly assigning them.
|
||||||
* ``last_login`` -- A datetime of the user's last login. Is set to the
|
* ``last_login`` -- A datetime of the user's last login. Is set to the
|
||||||
@ -99,7 +99,9 @@ custom methods:
|
|||||||
should prefer using ``is_authenticated()`` to this method.
|
should prefer using ``is_authenticated()`` to this method.
|
||||||
|
|
||||||
* ``is_authenticated()`` -- Always returns ``True``. This is a way to
|
* ``is_authenticated()`` -- Always returns ``True``. This is a way to
|
||||||
tell if the user has been authenticated.
|
tell if the user has been authenticated. This does not imply any
|
||||||
|
permissions, and doesn't check if the user is active - it only indicates
|
||||||
|
that the user has provided a valid username and password.
|
||||||
|
|
||||||
* ``get_full_name()`` -- Returns the ``first_name`` plus the ``last_name``,
|
* ``get_full_name()`` -- Returns the ``first_name`` plus the ``last_name``,
|
||||||
with a space in between.
|
with a space in between.
|
||||||
@ -120,13 +122,16 @@ custom methods:
|
|||||||
|
|
||||||
* ``has_perm(perm)`` -- Returns ``True`` if the user has the specified
|
* ``has_perm(perm)`` -- Returns ``True`` if the user has the specified
|
||||||
permission, where perm is in the format ``"package.codename"``.
|
permission, where perm is in the format ``"package.codename"``.
|
||||||
|
If the user is inactive, this method will always return ``False``.
|
||||||
|
|
||||||
* ``has_perms(perm_list)`` -- Returns ``True`` if the user has each of the
|
* ``has_perms(perm_list)`` -- Returns ``True`` if the user has each of the
|
||||||
specified permissions, where each perm is in the format
|
specified permissions, where each perm is in the format
|
||||||
``"package.codename"``.
|
``"package.codename"``. If the user is inactive, this method will
|
||||||
|
always return ``False``.
|
||||||
|
|
||||||
* ``has_module_perms(package_name)`` -- Returns ``True`` if the user has
|
* ``has_module_perms(package_name)`` -- Returns ``True`` if the user has
|
||||||
any permissions in the given package (the Django app label).
|
any permissions in the given package (the Django app label).
|
||||||
|
If the user is inactive, this method will always return ``False``.
|
||||||
|
|
||||||
* ``get_and_delete_messages()`` -- Returns a list of ``Message`` objects in
|
* ``get_and_delete_messages()`` -- Returns a list of ``Message`` objects in
|
||||||
the user's queue and deletes the messages from the queue.
|
the user's queue and deletes the messages from the queue.
|
||||||
@ -283,7 +288,10 @@ password is invalid, ``authenticate()`` returns ``None``. Example::
|
|||||||
from django.contrib.auth import authenticate
|
from django.contrib.auth import authenticate
|
||||||
user = authenticate(username='john', password='secret')
|
user = authenticate(username='john', password='secret')
|
||||||
if user is not None:
|
if user is not None:
|
||||||
print "You provided a correct username and password!"
|
if user.is_active:
|
||||||
|
print "You provided a correct username and password!"
|
||||||
|
else:
|
||||||
|
print "Your account has been disabled!"
|
||||||
else:
|
else:
|
||||||
print "Your username and password were incorrect."
|
print "Your username and password were incorrect."
|
||||||
|
|
||||||
@ -301,10 +309,13 @@ This example shows how you might use both ``authenticate()`` and ``login()``::
|
|||||||
password = request.POST['password']
|
password = request.POST['password']
|
||||||
user = authenticate(username=username, password=password)
|
user = authenticate(username=username, password=password)
|
||||||
if user is not None:
|
if user is not None:
|
||||||
login(request, user)
|
if user.is_active:
|
||||||
# Redirect to a success page.
|
login(request, user)
|
||||||
|
# Redirect to a success page.
|
||||||
|
else:
|
||||||
|
# Return a 'disabled account' error message
|
||||||
else:
|
else:
|
||||||
# Return an error message.
|
# Return an 'invalid login' error message.
|
||||||
|
|
||||||
How to log a user out
|
How to log a user out
|
||||||
---------------------
|
---------------------
|
||||||
|
@ -499,7 +499,7 @@ specify an object to edit or delete.
|
|||||||
How do I add database-specific options to my CREATE TABLE statements, such as specifying MyISAM as the table type?
|
How do I add database-specific options to my CREATE TABLE statements, such as specifying MyISAM as the table type?
|
||||||
------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
We try to avoid adding special cases in the Django code to accomodate all the
|
We try to avoid adding special cases in the Django code to accommodate all the
|
||||||
database-specific options such as table type, etc. If you'd like to use any of
|
database-specific options such as table type, etc. If you'd like to use any of
|
||||||
these options, create an `SQL initial data file`_ that contains ``ALTER TABLE``
|
these options, create an `SQL initial data file`_ that contains ``ALTER TABLE``
|
||||||
statements that do what you want to do. The initial data files are executed in
|
statements that do what you want to do. The initial data files are executed in
|
||||||
|
@ -489,7 +489,7 @@ required fields are present and non-empty. For each field that passes that
|
|||||||
test *and if the form submission contained data* for that field, all the
|
test *and if the form submission contained data* for that field, all the
|
||||||
validators for that field are called in turn. The emphasized portion in the
|
validators for that field are called in turn. The emphasized portion in the
|
||||||
last sentence is important: if a form field is not submitted (because it
|
last sentence is important: if a form field is not submitted (because it
|
||||||
contains no data -- which is normal HTML behaviour), the validators are not
|
contains no data -- which is normal HTML behavior), the validators are not
|
||||||
run against the field.
|
run against the field.
|
||||||
|
|
||||||
This feature is particularly important for models using
|
This feature is particularly important for models using
|
||||||
|
@ -110,7 +110,7 @@ many common questions appear with some regularity, and any particular problem
|
|||||||
may already have been answered.
|
may already have been answered.
|
||||||
|
|
||||||
Finally, for those who prefer the more immediate feedback offered by IRC,
|
Finally, for those who prefer the more immediate feedback offered by IRC,
|
||||||
there's a #django channel or irc.freenode.net that is regularly populated by
|
there's a #django channel on irc.freenode.net that is regularly populated by
|
||||||
Django users and developers from around the world. Friendly people are usually
|
Django users and developers from around the world. Friendly people are usually
|
||||||
available at any hour of the day -- to help, or just to chat.
|
available at any hour of the day -- to help, or just to chat.
|
||||||
|
|
||||||
|
@ -401,15 +401,6 @@ Subject-line prefix for e-mail messages sent with ``django.core.mail.mail_admins
|
|||||||
or ``django.core.mail.mail_managers``. You'll probably want to include the
|
or ``django.core.mail.mail_managers``. You'll probably want to include the
|
||||||
trailing space.
|
trailing space.
|
||||||
|
|
||||||
ENABLE_PSYCO
|
|
||||||
------------
|
|
||||||
|
|
||||||
Default: ``False``
|
|
||||||
|
|
||||||
Whether to enable Psyco, which optimizes Python code. Requires Psyco_.
|
|
||||||
|
|
||||||
.. _Psyco: http://psyco.sourceforge.net/
|
|
||||||
|
|
||||||
IGNORABLE_404_ENDS
|
IGNORABLE_404_ENDS
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
|
@ -540,6 +540,11 @@ The arguments can be hard-coded strings, so the following is valid::
|
|||||||
...
|
...
|
||||||
{% endifequal %}
|
{% endifequal %}
|
||||||
|
|
||||||
|
It is only possible to compare an argument to template variables or strings.
|
||||||
|
You cannot check for equality with Python objects such as ``True`` or
|
||||||
|
``False``. If you need to test if something is true or false, use the ``if``
|
||||||
|
and ``ifnot`` tags instead.
|
||||||
|
|
||||||
ifnotequal
|
ifnotequal
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
|
|
||||||
@ -1051,7 +1056,7 @@ Formats a date as the time since that date (i.e. "4 days, 6 hours").
|
|||||||
Takes an optional argument that is a variable containing the date to use as
|
Takes an optional argument that is a variable containing the date to use as
|
||||||
the comparison point (without the argument, the comparison point is *now*).
|
the comparison point (without the argument, the comparison point is *now*).
|
||||||
For example, if ``blog_date`` is a date instance representing midnight on 1
|
For example, if ``blog_date`` is a date instance representing midnight on 1
|
||||||
June 2006, and ``comment_date`` is a date instanace for 08:00 on 1 June 2006,
|
June 2006, and ``comment_date`` is a date instance for 08:00 on 1 June 2006,
|
||||||
then ``{{ comment_date|timesince:blog_date }}`` would return "8 hours".
|
then ``{{ comment_date|timesince:blog_date }}`` would return "8 hours".
|
||||||
|
|
||||||
timeuntil
|
timeuntil
|
||||||
|
@ -817,7 +817,7 @@ Inclusion tags
|
|||||||
|
|
||||||
Another common type of template tag is the type that displays some data by
|
Another common type of template tag is the type that displays some data by
|
||||||
rendering *another* template. For example, Django's admin interface uses custom
|
rendering *another* template. For example, Django's admin interface uses custom
|
||||||
template tags to display the buttons along the botton of the "add/change" form
|
template tags to display the buttons along the bottom of the "add/change" form
|
||||||
pages. Those buttons always look the same, but the link targets change depending
|
pages. Those buttons always look the same, but the link targets change depending
|
||||||
on the object being edited -- so they're a perfect case for using a small
|
on the object being edited -- so they're a perfect case for using a small
|
||||||
template that is filled with details from the current object. (In the admin's
|
template that is filled with details from the current object. (In the admin's
|
||||||
|
@ -389,7 +389,7 @@ an alternative framework as if they were normal Django tests.
|
|||||||
|
|
||||||
When you run ``./manage.py test``, Django looks at the ``TEST_RUNNER``
|
When you run ``./manage.py test``, Django looks at the ``TEST_RUNNER``
|
||||||
setting to determine what to do. By default, ``TEST_RUNNER`` points to ``django.test.simple.run_tests``. This method defines the default Django
|
setting to determine what to do. By default, ``TEST_RUNNER`` points to ``django.test.simple.run_tests``. This method defines the default Django
|
||||||
testing behaviour. This behaviour involves:
|
testing behavior. This behavior involves:
|
||||||
|
|
||||||
#. Performing global pre-test setup
|
#. Performing global pre-test setup
|
||||||
#. Creating the test database
|
#. Creating the test database
|
||||||
@ -435,7 +435,7 @@ a number of utility methods in the ``django.test.utils`` module.
|
|||||||
``create_test_db(verbosity=1, autoclobber=False)``
|
``create_test_db(verbosity=1, autoclobber=False)``
|
||||||
Creates a new test database, and run ``syncdb`` against it.
|
Creates a new test database, and run ``syncdb`` against it.
|
||||||
|
|
||||||
``verbosity`` has the same behaviour as in the test runner.
|
``verbosity`` has the same behavior as in the test runner.
|
||||||
|
|
||||||
``Autoclobber`` describes the behavior that will occur if a database with
|
``Autoclobber`` describes the behavior that will occur if a database with
|
||||||
the same name as the test database is discovered. If ``autoclobber`` is False,
|
the same name as the test database is discovered. If ``autoclobber`` is False,
|
||||||
@ -450,4 +450,4 @@ a number of utility methods in the ``django.test.utils`` module.
|
|||||||
Destroys the database with the name ``settings.DATABASE_NAME`` matching,
|
Destroys the database with the name ``settings.DATABASE_NAME`` matching,
|
||||||
and restores the value of ``settings.DATABASE_NAME`` to the provided name.
|
and restores the value of ``settings.DATABASE_NAME`` to the provided name.
|
||||||
|
|
||||||
``verbosity`` has the same behaviour as in the test runner.
|
``verbosity`` has the same behavior as in the test runner.
|
||||||
|
@ -91,7 +91,7 @@ Finally, it calls that ``detail()`` function like so::
|
|||||||
The ``poll_id='23'`` part comes from ``(?P<poll_id>\d+)``. Using parenthesis around a
|
The ``poll_id='23'`` part comes from ``(?P<poll_id>\d+)``. Using parenthesis around a
|
||||||
pattern "captures" the text matched by that pattern and sends it as an argument
|
pattern "captures" the text matched by that pattern and sends it as an argument
|
||||||
to the view function; the ``?P<poll_id>`` defines the name that will be used to
|
to the view function; the ``?P<poll_id>`` defines the name that will be used to
|
||||||
identify the matched pattern; and ``\d+`` is a regular experession to match a sequence of
|
identify the matched pattern; and ``\d+`` is a regular expression to match a sequence of
|
||||||
digits (i.e., a number).
|
digits (i.e., a number).
|
||||||
|
|
||||||
Because the URL patterns are regular expressions, there really is no limit on
|
Because the URL patterns are regular expressions, there really is no limit on
|
||||||
|
@ -207,7 +207,7 @@ for the polls app, we manually specify a template name for the results view:
|
|||||||
template. Note that we use ``dict()`` to return an altered dictionary in place.
|
template. Note that we use ``dict()`` to return an altered dictionary in place.
|
||||||
|
|
||||||
In previous parts of the tutorial, the templates have been provided with a context
|
In previous parts of the tutorial, the templates have been provided with a context
|
||||||
that contains the ``poll` and ``latest_poll_list`` context variables. However,
|
that contains the ``poll`` and ``latest_poll_list`` context variables. However,
|
||||||
the generic views provide the variables ``object`` and ``object_list`` as context.
|
the generic views provide the variables ``object`` and ``object_list`` as context.
|
||||||
Therefore, you need to change your templates to match the new context variables.
|
Therefore, you need to change your templates to match the new context variables.
|
||||||
Go through your templates, and modify any reference to ``latest_poll_list`` to
|
Go through your templates, and modify any reference to ``latest_poll_list`` to
|
||||||
|
Loading…
x
Reference in New Issue
Block a user