diff --git a/AUTHORS b/AUTHORS index edd7d50726..6b25a39035 100644 --- a/AUTHORS +++ b/AUTHORS @@ -71,6 +71,7 @@ answer newbie questions, and generally made Django that much better: lakin.wecker@gmail.com Stuart Langridge Eugene Lazutkin + Christopher Lenz limodou Martin Maney Manuzhai @@ -79,6 +80,7 @@ answer newbie questions, and generally made Django that much better: mattycakes@gmail.com Jason McBrayer michael.mcewan@gmail.com + mir@noris.de mmarshall Eric Moritz Robin Munn @@ -102,7 +104,9 @@ answer newbie questions, and generally made Django that much better: Aaron Swartz Tom Tobin Joe Topjian + Malcolm Tredinnick Amit Upadhyay + Geert Vanderkelen Milton Waddams Rachel Willmer wojtek diff --git a/django/__init__.py b/django/__init__.py index 593e2f46e4..00c6f82478 100644 --- a/django/__init__.py +++ b/django/__init__.py @@ -1 +1 @@ -VERSION = (0, 9, 1, 'SVN') +VERSION = (0, 95, 'post-magic-removal') diff --git a/django/bin/daily_cleanup.py b/django/bin/daily_cleanup.py index 52e2ef43fd..6eb5c17feb 100644 --- a/django/bin/daily_cleanup.py +++ b/django/bin/daily_cleanup.py @@ -1,17 +1,17 @@ "Daily cleanup file" -from django.core.db import db +from django.db import backend, connection, transaction DOCUMENTATION_DIRECTORY = '/home/html/documentation/' def clean_up(): # Clean up old database records - cursor = db.cursor() + cursor = connection.cursor() cursor.execute("DELETE FROM %s WHERE %s < NOW()" % \ - (db.quote_name('core_sessions'), db.quote_name('expire_date'))) + (backend.quote_name('core_sessions'), backend.quote_name('expire_date'))) cursor.execute("DELETE FROM %s WHERE %s < NOW() - INTERVAL '1 week'" % \ - (db.quote_name('registration_challenges'), db.quote_name('request_date'))) - db.commit() + (backend.quote_name('registration_challenges'), backend.quote_name('request_date'))) + transaction.commit_unless_managed() if __name__ == "__main__": clean_up() diff --git a/django/conf/__init__.py b/django/conf/__init__.py index e69de29bb2..291ba8ce3f 100644 --- a/django/conf/__init__.py +++ b/django/conf/__init__.py @@ -0,0 +1,73 @@ +""" +Settings and configuration for Django. + +Values will be read from the module specified by the DJANGO_SETTINGS_MODULE environment +variable, and then from django.conf.global_settings; see the global settings file for +a list of all possible variables. +""" + +import os +import sys +from django.conf import global_settings + +ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE" + +class Settings: + + def __init__(self, settings_module): + + # update this dict from global settings (but only for ALL_CAPS settings) + for setting in dir(global_settings): + if setting == setting.upper(): + setattr(self, setting, getattr(global_settings, setting)) + + # store the settings module in case someone later cares + self.SETTINGS_MODULE = settings_module + + try: + mod = __import__(self.SETTINGS_MODULE, '', '', ['']) + except ImportError, e: + raise EnvironmentError, "Could not import settings '%s' (is it on sys.path?): %s" % (self.SETTINGS_MODULE, e) + + # Settings that should be converted into tuples if they're mistakenly entered + # as strings. + tuple_settings = ("INSTALLED_APPS", "TEMPLATE_DIRS") + + for setting in dir(mod): + if setting == setting.upper(): + setting_value = getattr(mod, setting) + if setting in tuple_settings and type(setting_value) == str: + setting_value = (setting_value,) # In case the user forgot the comma. + setattr(self, setting, setting_value) + + # Expand entries in INSTALLED_APPS like "django.contrib.*" to a list + # of all those apps. + new_installed_apps = [] + for app in self.INSTALLED_APPS: + if app.endswith('.*'): + appdir = os.path.dirname(__import__(app[:-2], '', '', ['']).__file__) + for d in os.listdir(appdir): + if d.isalpha() and os.path.isdir(os.path.join(appdir, d)): + new_installed_apps.append('%s.%s' % (app[:-2], d)) + else: + new_installed_apps.append(app) + self.INSTALLED_APPS = new_installed_apps + + # move the time zone info into os.environ + os.environ['TZ'] = self.TIME_ZONE + +# try to load DJANGO_SETTINGS_MODULE +try: + settings_module = os.environ[ENVIRONMENT_VARIABLE] + if not settings_module: # If it's set but is an empty string. + raise KeyError +except KeyError: + raise EnvironmentError, "Environment variable %s is undefined." % ENVIRONMENT_VARIABLE + +# instantiate the configuration object +settings = Settings(settings_module) + +# install the translation machinery so that it is available +from django.utils import translation +translation.install() + diff --git a/django/conf/app_template/models.py b/django/conf/app_template/models.py new file mode 100644 index 0000000000..71a8362390 --- /dev/null +++ b/django/conf/app_template/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/django/conf/app_template/models/__init__.py b/django/conf/app_template/models/__init__.py deleted file mode 100644 index 502a7d0738..0000000000 --- a/django/conf/app_template/models/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__all__ = ['{{ app_name }}'] diff --git a/django/conf/app_template/models/app_name.py b/django/conf/app_template/models/app_name.py deleted file mode 100644 index 6fce302e01..0000000000 --- a/django/conf/app_template/models/app_name.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.core import meta - -# Create your models here. diff --git a/django/conf/global_settings.py b/django/conf/global_settings.py index f6ec3d2611..cfa174287b 100644 --- a/django/conf/global_settings.py +++ b/django/conf/global_settings.py @@ -79,7 +79,7 @@ SERVER_EMAIL = 'root@localhost' SEND_BROKEN_LINK_EMAILS = False # Database connection info. -DATABASE_ENGINE = 'postgresql' # 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'. +DATABASE_ENGINE = '' # 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'. DATABASE_NAME = '' # Or path to database file if using sqlite3. DATABASE_USER = '' # Not used with sqlite3. DATABASE_PASSWORD = '' # Not used with sqlite3. @@ -102,19 +102,16 @@ INSTALLED_APPS = () # List of locations of the template source files, in search order. TEMPLATE_DIRS = () -# Extension on all templates. -TEMPLATE_FILE_EXTENSION = '.html' - # List of callables that know how to import templates from various sources. # See the comments in django/core/template/loader.py for interface # documentation. TEMPLATE_LOADERS = ( - 'django.core.template.loaders.filesystem.load_template_source', - 'django.core.template.loaders.app_directories.load_template_source', -# 'django.core.template.loaders.eggs.load_template_source', + 'django.template.loaders.filesystem.load_template_source', + 'django.template.loaders.app_directories.load_template_source', +# 'django.template.loaders.eggs.load_template_source', ) -# List of processors used by DjangoContext to populate the context. +# List of processors used by RequestContext to populate the context. # Each one should be a callable that takes the request object as its # only parameter and returns a dictionary to add to the context. TEMPLATE_CONTEXT_PROCESSORS = ( @@ -205,6 +202,10 @@ TIME_FORMAT = 'P' # http://psyco.sourceforge.net/ ENABLE_PSYCO = False +# Do you want to manage transactions manually? +# Hint: you really don't! +TRANSACTIONS_MANAGED = False + ############## # MIDDLEWARE # ############## @@ -213,7 +214,8 @@ ENABLE_PSYCO = False # this middleware classes will be applied in the order given, and in the # response phase the middleware will be applied in reverse order. MIDDLEWARE_CLASSES = ( - "django.middleware.sessions.SessionMiddleware", + "django.contrib.sessions.middleware.SessionMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", # "django.middleware.http.ConditionalGetMiddleware", # "django.middleware.gzip.GZipMiddleware", "django.middleware.common.CommonMiddleware", diff --git a/django/conf/project_template/settings.py b/django/conf/project_template/settings.py index 71d4da472d..800d1023d9 100644 --- a/django/conf/project_template/settings.py +++ b/django/conf/project_template/settings.py @@ -9,7 +9,7 @@ ADMINS = ( MANAGERS = ADMINS -DATABASE_ENGINE = 'postgresql' # 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'. +DATABASE_ENGINE = '' # 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'. DATABASE_NAME = '' # Or path to database file if using sqlite3. DATABASE_USER = '' # Not used with sqlite3. DATABASE_PASSWORD = '' # Not used with sqlite3. @@ -45,14 +45,15 @@ SECRET_KEY = '' # List of callables that know how to import templates from various sources. TEMPLATE_LOADERS = ( - 'django.core.template.loaders.filesystem.load_template_source', - 'django.core.template.loaders.app_directories.load_template_source', -# 'django.core.template.loaders.eggs.load_template_source', + 'django.template.loaders.filesystem.load_template_source', + 'django.template.loaders.app_directories.load_template_source', +# 'django.template.loaders.eggs.load_template_source', ) MIDDLEWARE_CLASSES = ( "django.middleware.common.CommonMiddleware", - "django.middleware.sessions.SessionMiddleware", + "django.contrib.sessions.middleware.SessionMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", "django.middleware.doc.XViewMiddleware", ) @@ -64,4 +65,8 @@ TEMPLATE_DIRS = ( ) INSTALLED_APPS = ( + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.sites', ) diff --git a/django/conf/project_template/urls.py b/django/conf/project_template/urls.py index fe77ea1867..4483014173 100644 --- a/django/conf/project_template/urls.py +++ b/django/conf/project_template/urls.py @@ -5,5 +5,5 @@ urlpatterns = patterns('', # (r'^{{ project_name }}/', include('{{ project_name }}.apps.foo.urls.foo')), # Uncomment this for admin: -# (r'^admin/', include('django.contrib.admin.urls.admin')), +# (r'^admin/', include('django.contrib.admin.urls')), ) diff --git a/django/conf/settings.py b/django/conf/settings.py deleted file mode 100644 index f455f65afe..0000000000 --- a/django/conf/settings.py +++ /dev/null @@ -1,77 +0,0 @@ -""" -Settings and configuration for Django. - -Values will be read from the module specified by the DJANGO_SETTINGS_MODULE environment -variable, and then from django.conf.global_settings; see the global settings file for -a list of all possible variables. -""" - -import os -import sys -from django.conf import global_settings - -ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE" - -# get a reference to this module (why isn't there a __module__ magic var?) -me = sys.modules[__name__] - -# update this dict from global settings (but only for ALL_CAPS settings) -for setting in dir(global_settings): - if setting == setting.upper(): - setattr(me, setting, getattr(global_settings, setting)) - -# try to load DJANGO_SETTINGS_MODULE -try: - me.SETTINGS_MODULE = os.environ[ENVIRONMENT_VARIABLE] - if not me.SETTINGS_MODULE: # If it's set but is an empty string. - raise KeyError -except KeyError: - raise EnvironmentError, "Environment variable %s is undefined." % ENVIRONMENT_VARIABLE - -try: - mod = __import__(me.SETTINGS_MODULE, '', '', ['']) -except ImportError, e: - raise EnvironmentError, "Could not import %s '%s' (is it on sys.path?): %s" % (ENVIRONMENT_VARIABLE, me.SETTINGS_MODULE, e) - -# Settings that should be converted into tuples if they're mistakenly entered -# as strings. -tuple_settings = ("INSTALLED_APPS", "TEMPLATE_DIRS") - -for setting in dir(mod): - if setting == setting.upper(): - setting_value = getattr(mod, setting) - if setting in tuple_settings and type(setting_value) == str: - setting_value = (setting_value,) # In case the user forgot the comma. - setattr(me, setting, setting_value) - -# Expand entries in INSTALLED_APPS like "django.contrib.*" to a list -# of all those apps. -new_installed_apps = [] -for app in me.INSTALLED_APPS: - if app.endswith('.*'): - appdir = os.path.dirname(__import__(app[:-2], '', '', ['']).__file__) - for d in os.listdir(appdir): - if d.isalpha() and os.path.isdir(os.path.join(appdir, d)): - new_installed_apps.append('%s.%s' % (app[:-2], d)) - else: - new_installed_apps.append(app) -me.INSTALLED_APPS = new_installed_apps - -# save DJANGO_SETTINGS_MODULE in case anyone in the future cares -me.SETTINGS_MODULE = os.environ.get(ENVIRONMENT_VARIABLE, '') - -# move the time zone info into os.environ -os.environ['TZ'] = me.TIME_ZONE - -# finally, clean up my namespace -for k in dir(me): - if not k.startswith('_') and k != 'me' and k != k.upper(): - delattr(me, k) -del me, k - -# as the last step, install the translation machinery and -# remove the module again to not clutter the namespace. -from django.utils import translation -translation.install() -del translation - diff --git a/django/conf/urls/registration.py b/django/conf/urls/registration.py index 5a56fe5e05..2d733a898b 100644 --- a/django/conf/urls/registration.py +++ b/django/conf/urls/registration.py @@ -1,9 +1,9 @@ from django.conf.urls.defaults import * urlpatterns = patterns('', - (r'^login/$', 'django.views.auth.login.login'), - (r'^logout/$', 'django.views.auth.login.logout'), - (r'^login_another/$', 'django.views.auth.login.logout_then_login'), + (r'^login/$', 'django.contrib.auth.view.login'), + (r'^logout/$', 'django.contrib.auth.views.logout'), + (r'^login_another/$', 'django.contrib.auth.views.logout_then_login'), (r'^register/$', 'ellington.registration.views.registration.signup'), (r'^register/(?P\w{32})/$', 'ellington.registration.views.registration.register_form'), @@ -12,8 +12,8 @@ urlpatterns = patterns('', (r'^profile/welcome/$', 'ellington.registration.views.profile.profile_welcome'), (r'^profile/edit/$', 'ellington.registration.views.profile.edit_profile'), - (r'^password_reset/$', 'django.views.registration.passwords.password_reset'), - (r'^password_reset/done/$', 'django.views.registration.passwords.password_reset_done'), - (r'^password_change/$', 'django.views.registration.passwords.password_change'), - (r'^password_change/done/$', 'django.views.registration.passwords.password_change_done'), + (r'^password_reset/$', 'django.contrib.auth.views.password_reset'), + (r'^password_reset/done/$', 'django.contrib.auth.views.password_reset_done'), + (r'^password_change/$', 'django.contrib.auth.views.password_change'), + (r'^password_change/done/$', 'django.contrib.auth.views.password_change_done'), ) diff --git a/django/contrib/admin/filterspecs.py b/django/contrib/admin/filterspecs.py index 31a6ba37c9..0284f13114 100644 --- a/django/contrib/admin/filterspecs.py +++ b/django/contrib/admin/filterspecs.py @@ -6,7 +6,7 @@ Each filter subclass knows how to display a filter for a field that passes a certain test -- e.g. being a DateField or ForeignKey. """ -from django.core import meta +from django.db import models import datetime class FilterSpec(object): @@ -50,13 +50,13 @@ class FilterSpec(object): class RelatedFilterSpec(FilterSpec): def __init__(self, f, request, params): super(RelatedFilterSpec, self).__init__(f, request, params) - if isinstance(f, meta.ManyToManyField): - self.lookup_title = f.rel.to.verbose_name + if isinstance(f, models.ManyToManyField): + self.lookup_title = f.rel.to._meta.verbose_name else: self.lookup_title = f.verbose_name - self.lookup_kwarg = '%s__%s__exact' % (f.name, f.rel.to.pk.name) + self.lookup_kwarg = '%s__%s__exact' % (f.name, f.rel.to._meta.pk.name) self.lookup_val = request.GET.get(self.lookup_kwarg, None) - self.lookup_choices = f.rel.to.get_model_module().get_list() + self.lookup_choices = f.rel.to._default_manager.all() def has_output(self): return len(self.lookup_choices) > 1 @@ -69,7 +69,7 @@ class RelatedFilterSpec(FilterSpec): 'query_string': cl.get_query_string({}, [self.lookup_kwarg]), 'display': _('All')} for val in self.lookup_choices: - pk_val = getattr(val, self.field.rel.to.pk.attname) + pk_val = getattr(val, self.field.rel.to._meta.pk.attname) yield {'selected': self.lookup_val == str(pk_val), 'query_string': cl.get_query_string( {self.lookup_kwarg: pk_val}), 'display': val} @@ -103,7 +103,7 @@ class DateFieldFilterSpec(FilterSpec): today = datetime.date.today() one_week_ago = today - datetime.timedelta(days=7) - today_str = isinstance(self.field, meta.DateTimeField) and today.strftime('%Y-%m-%d 23:59:59') or today.strftime('%Y-%m-%d') + today_str = isinstance(self.field, models.DateTimeField) and today.strftime('%Y-%m-%d 23:59:59') or today.strftime('%Y-%m-%d') self.links = ( (_('Any date'), {}), @@ -126,7 +126,7 @@ class DateFieldFilterSpec(FilterSpec): 'query_string': cl.get_query_string( param_dict, self.field_generic), 'display': title} -FilterSpec.register(lambda f: isinstance(f, meta.DateField), DateFieldFilterSpec) +FilterSpec.register(lambda f: isinstance(f, models.DateField), DateFieldFilterSpec) class BooleanFieldFilterSpec(FilterSpec): def __init__(self, f, request, params): @@ -144,9 +144,9 @@ class BooleanFieldFilterSpec(FilterSpec): yield {'selected': self.lookup_val == v and not self.lookup_val2, 'query_string': cl.get_query_string( {self.lookup_kwarg: v}, [self.lookup_kwarg2]), 'display': k} - if isinstance(self.field, meta.NullBooleanField): + if isinstance(self.field, models.NullBooleanField): yield {'selected': self.lookup_val2 == 'True', 'query_string': cl.get_query_string( {self.lookup_kwarg2: 'True'}, [self.lookup_kwarg]), 'display': _('Unknown')} -FilterSpec.register(lambda f: isinstance(f, meta.BooleanField) or isinstance(f, meta.NullBooleanField), BooleanFieldFilterSpec) +FilterSpec.register(lambda f: isinstance(f, models.BooleanField) or isinstance(f, models.NullBooleanField), BooleanFieldFilterSpec) diff --git a/django/contrib/admin/media/css/base.css b/django/contrib/admin/media/css/base.css index 7c4437f454..88f7d9a95a 100644 --- a/django/contrib/admin/media/css/base.css +++ b/django/contrib/admin/media/css/base.css @@ -1,3 +1,14 @@ -@import url(global.css); -@import url(changelists.css); +/* + DJANGO Admin + by Wilson Miner wilson@lawrence.com +*/ + +/* Block IE 5 */ +@import "null?\"\{"; + +/* Import other styles */ +@import url('global.css'); +@import url('layout.css'); + +/* Import patch for IE 6 Windows */ /*\*/ @import "patch-iewin.css"; /**/ \ No newline at end of file diff --git a/django/contrib/admin/media/css/changelists.css b/django/contrib/admin/media/css/changelists.css index 7ff59c5e6b..2269c9fe20 100644 --- a/django/contrib/admin/media/css/changelists.css +++ b/django/contrib/admin/media/css/changelists.css @@ -1,16 +1,13 @@ -/* - DJANGO Admin Changelist Styles - by Wilson Miner wilson@lawrence.com - Copyright (c) 2005 Lawrence Journal-World -*/ +@import url('base.css'); +/* CHANGELISTS */ #changelist { position:relative; width:100%; } #changelist table { width:100%; } .change-list .filtered table { border-right:1px solid #ddd; } .change-list .filtered { min-height:400px; _height:400px; } .change-list .filtered { background:white url(../img/admin/changelist-bg.gif) top right repeat-y !important; } .change-list .filtered table, .change-list .filtered .paginator, .filtered #toolbar, .filtered div.xfull { margin-right:160px !important; width:auto !important; } -.change-list .filtered table tbody th { padding-right:10px; } +.change-list .filtered table tbody th { padding-right:1em; } #changelist .toplinks { border-bottom:1px solid #ccc !important; } #changelist .paginator { color:#666; border-top:1px solid #eee; border-bottom:1px solid #eee; background:white url(../img/admin/nav-bg.gif) 0 180% repeat-x; overflow:hidden; } .change-list .filtered .paginator { border-right:1px solid #ddd; } @@ -42,3 +39,12 @@ .change-list ul.toplinks li { float: left; width: 9em; padding:3px 6px; font-weight: bold; list-style-type:none; } .change-list ul.toplinks .date-back a { color:#999; } .change-list ul.toplinks .date-back a:hover { color:#036; } + +/* PAGINATOR */ +.paginator { font-size:11px; padding-top:10px; padding-bottom:10px; line-height:22px; margin:0; border-top:1px solid #ddd; } +.paginator a:link, .paginator a:visited { padding:2px 6px; border:solid 1px #ccc; background:white; text-decoration:none; } +.paginator a.showall { padding:0 !important; border:none !important; } +.paginator a.showall:hover { color:#036 !important; background:transparent !important; } +.paginator .end { border-width:2px !important; margin-right:6px; } +.paginator .this-page { padding:2px 6px; font-weight:bold; font-size:13px; vertical-align:top; } +.paginator a:hover { color:white; background:#5b80b2; border-color:#036; } diff --git a/django/contrib/admin/media/css/dashboard.css b/django/contrib/admin/media/css/dashboard.css new file mode 100644 index 0000000000..d27797324b --- /dev/null +++ b/django/contrib/admin/media/css/dashboard.css @@ -0,0 +1,10 @@ +@import url('base.css'); + +/* DASHBOARD */ +.dashboard .module table th { width:100%; } +.dashboard .module table td { white-space:nowrap; } +.dashboard .module table td a { display:block; padding-right:.6em; } + +/* RECENT ACTIONS MODULE */ +.module ul.actionlist { margin-left:0; } +ul.actionlist li { list-style-type:none; } \ No newline at end of file diff --git a/django/contrib/admin/media/css/forms.css b/django/contrib/admin/media/css/forms.css new file mode 100644 index 0000000000..b66f268fec --- /dev/null +++ b/django/contrib/admin/media/css/forms.css @@ -0,0 +1,60 @@ +@import url('base.css'); +@import url('widgets.css'); + +/* FORM ROWS */ +.form-row { overflow:hidden; padding:8px 12px; font-size:11px; border-bottom:1px solid #eee; } +.form-row img, .form-row input { vertical-align:middle; } +form .form-row p { padding-left:0; font-size:11px; } + +/* FORM LABELS */ +form h4 { margin:0 !important; padding:0 !important; border:none !important; } +label { font-weight:normal !important; color:#666; font-size:12px; } +label.inline { margin-left:20px; } +.required label, label.required { font-weight:bold !important; color:#333 !important; } + +/* RADIO BUTTONS */ +form ul.radiolist li { list-style-type:none; } +form ul.radiolist label { float:none; display:inline; } +form ul.inline { margin-left:0; padding:0; } +form ul.inline li { float:left; padding-right:7px; } + +/* ALIGNED FIELDSETS */ +.aligned label { display:block; padding:0 1em 3px 0; float:left; width:8em; } +.aligned label.inline { display:inline; float:none; } +.colMS .aligned .vLargeTextField, .colMS .aligned .vXMLLargeTextField { width:350px; } +form .aligned p, form .aligned ul { margin-left:7em; padding-left:30px; } +form .aligned table p { margin-left:0; padding-left:0; } +form .aligned p.help { padding-left:38px; } +.aligned .vCheckboxLabel { float:none !important; display:inline; padding-left:4px; } +.colM .aligned .vLargeTextField, colM .aligned .vXMLLargeTextField { width:610px; } +.checkbox-row p.help { margin-left:0; padding-left:0 !important; } + +/* WIDE FIELDSETS */ +.wide label { width:15em !important; } +form .wide p { margin-left:15em; } +form .wide p.help { padding-left:38px; } +.colM fieldset.wide .vLargeTextField, .colM fieldset.wide .vXMLLargeTextField { width:450px; } + +/* COLLAPSED FIELDSETS */ +fieldset.collapsed * { display:none; } +fieldset.collapsed h2, fieldset.collapsed { display:block !important; } +fieldset.collapsed h2 { background-image:url(../img/admin/nav-bg.gif); background-position:bottom left; color:#999; } +fieldset.collapsed .collapse-toggle { padding:3px 5px !important; background:transparent; display:inline !important;} + +/* MONOSPACE TEXTAREAS */ +fieldset.monospace textarea { font-family:"Bitstream Vera Sans Mono",Monaco,"Courier New",Courier,monospace; } + +/* SUBMIT ROW */ +.submit-row { padding:5px 7px; text-align:right; background:white url(../img/admin/nav-bg.gif) 0 100% repeat-x; border:1px solid #ccc; margin:5px 0; } +.submit-row input { margin:0 0 0 5px; } +.submit-row p { margin-top:0.3em; } +.submit-row .deletelink { background:url(../img/admin/icon_deletelink.gif) 0 50% no-repeat; padding-left:14px; } + +/* CUSTOM FORM FIELDS */ +.vSelectMultipleField { vertical-align:top !important; } +.vCheckboxField { border:none; } +.vDateField, .vTimeField { margin-right:2px; } +.vURLField { width:30em; } +.vLargeTextField, .vXMLLargeTextField { width:48em; } +.flatpages-flatpage #id_content { height:40.2em; } +.module table .vPositiveSmallIntegerField { width:2.2em; } \ No newline at end of file diff --git a/django/contrib/admin/media/css/global.css b/django/contrib/admin/media/css/global.css index 765e752d48..67e37324e5 100644 --- a/django/contrib/admin/media/css/global.css +++ b/django/contrib/admin/media/css/global.css @@ -1,19 +1,14 @@ -/* - DJANGO Admin Global Styles - by Wilson Miner wilson@lawrence.com - Copyright (c) 2005 Lawrence Journal-World -*/ - -body { margin:0; padding:0; font-family:"Lucida Grande","Bitstream Vera Sans",Verdana,Arial,sans-serif; color:#333; background:#fff; } +body { margin:0; padding:0; font-size:12px; font-family:"Lucida Grande","Bitstream Vera Sans",Verdana,Arial,sans-serif; color:#333; background:#fff; } /* LINKS */ a:link, a:visited { color: #5b80b2; text-decoration:none; } a:hover { color: #036; } a img { border:none; } -/* GLOBAL DEFAULTS */ -p, ol, ul, dl { margin:.2em 0 .8em 0; font-size:12px; } +/* GLOBAL DEFAULTS */ +p, ol, ul, dl { margin:.2em 0 .8em 0; } p { padding:0; line-height:140%; } + h1,h2,h3,h4,h5 { font-weight:bold; } h1 { font-size:18px; color:#666; padding:0 6px 0 0; margin:0 0 .2em 0; } h2 { font-size:16px; margin:1em 0 .5em 0; } @@ -21,6 +16,7 @@ h2.subhead { font-weight:normal;margin-top:0; } h3 { font-size:14px; margin:.8em 0 .3em 0; color:#666; font-weight:bold; } h4 { font-size:12px; margin:1em 0 .8em 0; padding-bottom:3px; } h5 { font-size:10px; margin:1.5em 0 .5em 0; color:#666; text-transform:uppercase; letter-spacing:1px; } + ul li { list-style-type:square; padding:1px 0; } ul.plainlist { margin-left:0 !important; } ul.plainlist li { list-style-type:none; } @@ -28,274 +24,17 @@ li ul { margin-bottom:0; } li, dt, dd { font-size:11px; line-height:14px; } dt { font-weight:bold; margin-top:4px; } dd { margin-left:0; } + form { margin:0; padding:0; } fieldset { margin:0; padding:0; } + blockquote { font-size:11px; color:#777; margin-left:2px; padding-left:10px; border-left:5px solid #ddd; } code, pre { font-family:"Bitstream Vera Sans Mono", Monaco, "Courier New", Courier, monospace; background:inherit; color:#666; font-size:11px; } pre.literal-block { margin:10px; background:#eee; padding:6px 8px; } code strong { color:#930; } hr { clear:both; color:#eee; background-color:#eee; height:1px; border:none; margin:0; padding:0; font-size:1px; line-height:1px; } -/* PAGE STRUCTURE */ -#container { position:relative; width:100%; min-width:760px; } -#content { margin:10px 15px; } -#header { width:100%; } -#content-main { float:left; width:100%; } -#content-related { float:right; width:220px; position:relative; margin-right:-230px; } -#footer { clear:both; padding:10px; } - -/* COLUMN TYPES */ -.colMS { margin-right:245px !important; } -.colSM { margin-left:245px !important; } -.colSM #content-related { float:left; margin-right:0; margin-left:-230px; } -.colSM #content-main { float:right; } -.popup .colM { width:95%; } -.subcol { float:left; width:46%; margin-right:15px; } -.dashboard #content { width:500px; } - -/* HEADER */ -#header { background:#417690; color:#ffc; min-height:2.4em; overflow:hidden; } -#header a:link, #header a:visited { color:white; } -#header a:hover { text-decoration:underline; } -#branding h1 { padding:0.5em 10px 0 10px; font-size:18px; margin:0; font-weight:normal; color:#f4f379; } -#branding h2 { padding:0 10px 0.8em 10px; font-size:14px; margin:0; font-weight:normal; color:#ffc; } -#user-tools { position:absolute; top:0; right:0; padding:1.2em 10px; font-size:11px; text-align:right; } - -/* SIDEBAR */ -#content-related h3 { font-size:12px; color:#666; margin-bottom:3px; } -#content-related h4 { font-size:11px; } - -/* TABLES */ -table { border-collapse:collapse; border-color:#ccc; } -td, th { font-size:11px; line-height:13px; border-bottom:1px solid #eee; vertical-align:top; padding:5px; font-family:"Lucida Grande", Verdana, Arial, sans-serif; } -th { text-align:left; font-size:12px; } -thead th { font-weight:bold; color:#666; padding:2px 5px; font-size:11px; background:#e1e1e1 url(../img/admin/nav-bg.gif) top left repeat-x; border-left:1px solid #ddd; border-bottom:1px solid #ddd; } -thead th:first-child { border-left:none !important; } -.superwide table th, .superwide table td, .superwide table input, .superwide table select { font-size:10px; } -.module table { border-collapse: collapse; } -thead th.optional { font-weight:normal !important; } -#home-page table.module tr:hover { background:#EDF3FE; } -fieldset table { border-right:1px solid #eee; } -tr.row-label td { font-size:9px; padding-top:2px; padding-bottom:0; border-bottom:none; color:#666; margin-top:-1px; } -tr.alt { background:#f6f6f6; } -.row1 { background:#EDF3FE; } -.row2 { background:white; } -table#change-history { width:100%; } -table#change-history tbody th { width:16em; } - -/* TABLE SORTING */ -thead th a:link, thead th a:visited { color:#666; display:block; } -table thead th.sorted { background-position:bottom left !important; } -table thead th.sorted a { padding-right:13px; } -table thead th.ascending a { background:url(../img/admin/arrow-down.gif) right .4em no-repeat; } -table thead th.descending a { background:url(../img/admin/arrow-up.gif) right .4em no-repeat; } - -/* MODULES */ -.module { border:1px solid #ccc; margin-bottom:5px; background:white; } -.module p, .module ul, .module h3, .module h4, .module dl, .module pre { padding-left:10px; padding-right:10px; } -.module blockquote { margin-left:12px; } -.module ul, .module ol { margin-left:1.5em; } -.module h2, .module caption { margin:0; padding:2px 5px 3px 5px; font-size:11px; text-align:left; background:#7CA0C7 url(../img/admin/default-bg.gif) left top repeat-x; color:white; font-weight:bold; } -.module caption { border:1px solid #ccc; border-bottom:none; } -.module h3 { margin-top:.6em; } -#content-related .module h2 { background:#eee url(../img/admin/nav-bg.gif) bottom left repeat-x; color:#666; } -#content-main .verbose .actionlist { float:right; font-size:10px; width:17em; position:relative; top:-1.6em; margin:0 8px; } - -/* DASHBOARD */ -.dashboard .module table th { width:100%; } -.dashboard .module table td { white-space:nowrap; } -.dashboard .module table td a { display:block; padding-right:.6em; } - -/* RECENT ACTIONS MODULE */ -.module ul.actionlist { margin-left:0; } -ul.actionlist li { list-style-type:none; } - -/* FORM DEFAULTS */ -input, textarea, select { margin:2px 0; padding:2px 3px; vertical-align:middle; border:1px solid #ccc; font-family:"Lucida Grande", Verdana, Arial, sans-serif; font-weight:normal; font-size:11px; } -textarea { vertical-align:top !important; } -input[type=checkbox], input[type=radio] { border:none; } - -/* FORM BUTTONS */ -input[type=submit], input[type=button], .submit-row input { background:white url(../img/admin/nav-bg.gif) bottom repeat-x; padding:3px; color:black; } -input[type=submit]:active, input[type=button]:active { background-image:url(../img/admin/nav-bg-reverse.gif); background-position:top; } -input[type=submit].default, .submit-row input.default { border:2px solid #5b80b2; background:#7CA0C7 url(../img/admin/default-bg.gif) bottom repeat-x; font-weight:bold; color:white; } -input[type=submit].default:active { background-image:url(../img/admin/default-bg-reverse.gif); background-position:top; } -.submit-row { padding:5px 7px; text-align:right; background:#ffc; border:1px solid #ccc; margin:5px 0; } -.submit-row input { margin:0 0 0 5px; } -.submit-row .float-left { padding-top:.1em; } - -/* FORM ROWS */ -.form-row { clear:both; padding:8px 12px; font-size:11px; } -html>body .form-row { border-bottom:1px solid #eee; } -.form-row:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } -.form-row img, .form-row input { vertical-align:middle; } -form .form-row p { padding-left:0; font-size:11px; } - -/* FORM LABELS */ -form h4 { margin:0 !important; padding:0 !important; border:none !important; } -label { font-weight:normal !important; color:#666; font-size:12px; } -label.inline { margin-left:20px; } -.required label, label.required { font-weight:bold !important; color:#333 !important; } - -/* RADIO BUTTONS */ -form ul.radiolist li { list-style-type:none; } -form ul.radiolist label { float:none; display:inline; } -form ul.inline { margin-left:0; padding:0; } -form ul.inline li { float:left; padding-right:7px; } - -/* ALIGNED FIELDSETS */ -.aligned label { display:block; padding:0 1em 3px 0; float:left; text-align:left; width:8em; } -.aligned label.inline { display:inline; float:none; } -.colMS .aligned .vLargeTextField, .colMS .aligned .vXMLLargeTextField { width:350px; } -form .aligned p, form .aligned ul { margin-left:7em; padding-left:30px; } -form .aligned table p { margin-left:0; padding-left:0; } -form .aligned p.help { padding-left:38px; } -.aligned .vCheckboxLabel { float:none !important; display:inline; } -.colM .aligned .vLargeTextField, colM .aligned .vXMLLargeTextField { width:610px; } -.checkbox-row p.help { margin-left:0; padding-left:0 !important; } - -/* WIDE FIELDSETS */ -.wide label { width:15em !important; } -form .wide p { margin-left:15em; } -form .wide p.help { padding-left:38px; } -.colM fieldset.wide .vLargeTextField, .colM fieldset.wide .vXMLLargeTextField { width:450px; } - -/* COLLAPSED FIELDSETS */ -fieldset.collapsed * { display:none; } -fieldset.collapsed h2, fieldset.collapsed { display:block !important; } -fieldset.collapsed .collapse-toggle { display: inline !important; } -fieldset.collapse h2 a.collapse-toggle { color:#ffc; } -fieldset.collapse h2 a.collapse-toggle:hover { text-decoration:underline; } -.hidden { display:none; } - -/* MONOSPACE TEXTAREAS */ -fieldset.monospace textarea { font-family:"Bitstream Vera Sans Mono",Monaco,"Courier New",Courier,monospace; } - -/* MESSAGES & ERRORS */ -ul.messagelist { padding:0 0 5px 0; margin:0; } -ul.messagelist li { font-size:12px; display:block; padding:4px 5px 4px 25px; margin:0 0 3px 0; border-bottom:1px solid #ddd; color:#666; background:#ffc url(../img/admin/icon_success.gif) 5px .3em no-repeat; } -.errornote { font-size:12px !important; display:block; padding:4px 5px 4px 25px; margin:0 0 3px 0; border:1px solid red; color:red;background:#ffc url(../img/admin/icon_error.gif) 5px .3em no-repeat; } -ul.errorlist { margin:0 !important; padding:0 !important; } -.errorlist li { font-size:12px !important; display:block; padding:4px 5px 4px 25px; margin:0 0 3px 0; border:1px solid red; color:white; background:red url(../img/admin/icon_alert.gif) 5px .3em no-repeat; } -td ul.errorlist { margin:0 !important; padding:0 !important; } -td ul.errorlist li { margin:0 !important; } -.error { background:#ffc; } -.error input, .error select { border:1px solid red; } -div.system-message { background: #ffc; margin: 10px; padding: 6px 8px; font-size: .8em; } -div.system-message p.system-message-title { padding:4px 5px 4px 25px; margin:0; color:red; background:#ffc url(../img/admin/icon_error.gif) 5px .3em no-repeat; } - -/* ACTION ICONS */ -.addlink { padding-left:12px; background:url(../img/admin/icon_addlink.gif) 0 .2em no-repeat; } -.changelink { padding-left:12px; background:url(../img/admin/icon_changelink.gif) 0 .2em no-repeat; } -.deletelink { padding-left:12px; background:url(../img/admin/icon_deletelink.gif) 0 .2em no-repeat; } -a.deletelink:link, a.deletelink:visited { color:#CC3434; } -a.deletelink:hover { color:#993333; } - -/* OBJECT TOOLS */ -.object-tools { font-size:10px; font-weight:bold; font-family:Arial,Helvetica,sans-serif; padding-left:0; margin-bottom:5px; float:right; position:relative; margin-top:-2.4em; margin-bottom:-2em; } -.form-row .object-tools { margin-top:0; margin-bottom:0; } -.object-tools li { display:block; float:left; background:url(../img/admin/tool-left.gif) 0 0 no-repeat; padding:0 0 0 8px; margin-left:2px; height:16px; } -.object-tools li:hover { background:url(../img/admin/tool-left_over.gif) 0 0 no-repeat; } -.object-tools a:link, .object-tools a:visited { display:block; float:left; color:white; padding:.1em 14px .1em 8px; height:14px; background:#999 url(../img/admin/tool-right.gif) 100% 0 no-repeat; } -.object-tools a:hover, .object-tools li:hover a { background:#5b80b2 url(../img/admin/tool-right_over.gif) 100% 0 no-repeat; } -.object-tools a.viewsitelink, .object-tools a.golink { background:#999 url(../img/admin/tooltag-arrowright.gif) top right no-repeat; padding-right:28px; } -.object-tools a.viewsitelink:hover, .object-tools a.golink:hover { background:#5b80b2 url(../img/admin/tooltag-arrowright_over.gif) top right no-repeat; } -.object-tools a.addlink { background:#999 url(../img/admin/tooltag-add.gif) top right no-repeat; padding-right:28px; } -.object-tools a.addlink:hover { background:#5b80b2 url(../img/admin/tooltag-add_over.gif) top right no-repeat; } - -/* INLINE CONTROLS */ -#inline-controls { font-weight:bold; font-size:12px; } -#inline-specific-controls { margin-left:6px; padding:0 8px; border-left:6px solid #ccc; } - -/* BREADCRUMBS */ -p.breadcrumbs { font-size:11px; color:#ccc;text-align:left; } /* old breadcrumbs style */ -div.breadcrumbs { background:white url(../img/admin/nav-bg-reverse.gif) 0 -10px repeat-x; padding:2px 8px 3px 8px; font-size:11px; color:#999; border-top:1px solid white; border-bottom:1px solid #ccc; text-align:left; } - -/* SELECTOR (FILTER INTERFACE) */ -.selector { width:580px; float:left; } -.selector select { width:270px; height:170px; } -.selector-available, .selector-chosen { float:left; width:270px; text-align:center; margin-bottom:5px; } -.selector-available h2, .selector-chosen h2 { border:1px solid #ccc; } -.selector .selector-available h2 { background:white url(../img/admin/nav-bg.gif) bottom left repeat-x; color:#666; } -.selector .selector-filter { background:white; border:1px solid #ccc; border-width:0 1px; padding:3px; color:#999; font-size:10px; margin:0; text-align:left; } -.selector .selector-chosen .selector-filter { padding:4px 5px; } -.selector .selector-available input { width:230px; } -.selector ul.selector-chooser { float:left; width:22px; height:50px; background:url(../img/admin/chooser-bg.gif) top center no-repeat; margin:13% 3px 0 3px; padding:0; } -.selector-chooser li { margin:0; padding:3px; list-style-type:none; } -.selector select { margin-bottom:5px; margin-top:0; } -.selector-add, .selector-remove { width:16px; height:16px; display:block; text-indent:-3000px; } -.selector-add { background:url(../img/admin/selector-add.gif) top center no-repeat; margin-bottom:2px; } -.selector-remove { background:url(../img/admin/selector-remove.gif) top center no-repeat; } -a.selector-chooseall, a.selector-clearall { display:block; width:6em; text-align:left; margin-left:auto; margin-right:auto; font-weight:bold; color:#666; padding:3px 0 3px 18px; } -a.selector-chooseall:hover, a.selector-clearall:hover { color:#036; } -a.selector-chooseall { width:7em; background:url(../img/admin/selector-addall.gif) left center no-repeat; } -a.selector-clearall { background:url(../img/admin/selector-removeall.gif) left center no-repeat; } - -/* Stacked selectors for long items */ -.stacked { float:left; width:500px; } -.stacked select { width:480px; height:100px; } -.stacked .selector-available, .stacked .selector-chosen { width:480px; } -.stacked .selector-available { margin-bottom:0; } -.stacked .selector-available input { width:442px; } -.stacked ul.selector-chooser { height:22px; width:50px; margin:0 0 3px 40%; background:url(../img/admin/chooser_stacked-bg.gif) top center no-repeat; } -.stacked .selector-chooser li { float:left; padding:3px 3px 3px 5px; } -.stacked .selector-chooseall, .stacked .selector-clearall { display:none; } -.stacked .selector-add { background-image:url(../img/admin/selector_stacked-add.gif); } -.stacked .selector-remove { background-image:url(../img/admin/selector_stacked-remove.gif); } - -/* DATE AND TIME */ -p.datetime { line-height:20px; margin:0; padding:0; color:#666; font-size:11px; font-weight:bold; } -.datetime span { font-size:11px; font-weight:normal; color:#ccc; white-space:nowrap; } -.vDateField { margin-left:4px; } -table p.datetime { font-size:10px; margin-left:0; padding-left:0; } - -/* FILE UPLOADS */ -p.file-upload { line-height:20px; margin:0; padding:0; color:#666; font-size:11px; font-weight:bold; } -.file-upload a { font-weight:normal; } -.file-upload .deletelink { margin-left:5px; } - -/* CALENDARS & CLOCKS */ -.calendarbox, .clockbox { margin:5px auto; font-size:11px; width: 16em; text-align: center; background:white; position:relative; } -.clockbox { width:9em; } -.calendar { margin:0; padding: 0; } -.calendar table { margin: 0; padding: 0; border-collapse:collapse; background:white; width:99%; } -.calendar caption, .calendarbox h2 { margin: 0; font-size:11px; text-align:center; border-top:none; } -.calendar th { font-size:10px; color:#666; padding:2px 3px; text-align:center; background:#e1e1e1 url(../img/admin/nav-bg.gif) 0 50% repeat-x; border-bottom:1px solid #ddd; } -.calendar td { font-size:11px; text-align: center; padding: 0; border-top:1px solid #eee; border-bottom:none; } -.calendar td.selected a { background: #C9DBED; } -.calendar td.nonday { background:#efefef; } -.calendar td.today a { background:#ffc; } -.calendar td a, .timelist a { display: block; font-weight:bold; padding:4px; text-decoration: none; color:#444; } -.calendar td a:hover, .timelist a:hover { background: #5b80b2; color:white; } -.calendar td a:active, .timelist a:active { background: #036; color:white; } -.calendarnav { font-size:10px; text-align: center; color:#ccc; margin:0; padding:1px 3px; } -.calendarnav a:link, #calendarnav a:visited, #calendarnav a:hover { color: #999; } -.calendar-shortcuts { background:white; font-size:10px; line-height:11px; border-top:1px solid #eee; padding:3px 0 4px; color:#ccc; } -.calendarbox .calendarnav-previous, .calendarbox .calendarnav-next { display:block; position:absolute; font-weight:bold; font-size:12px; background:#C9DBED url(../img/admin/default-bg.gif) bottom left repeat-x; padding:1px 4px 2px 4px; color:white; } -.calendarnav-previous:hover, .calendarnav-next:hover { background:#036; } -.calendarnav-previous { top:0; left:0; } -.calendarnav-next { top:0; right:0; } -.calendar-cancel { margin:0 !important; padding:0; font-size:10px; background:#e1e1e1 url(../img/admin/nav-bg.gif) 0 50% repeat-x; border-top:1px solid #ddd; } -.calendar-cancel a { padding:2px; color:#999; } -ul.timelist, .timelist li { list-style-type:none; margin:0; padding:0; } -.timelist a { padding:2px; } - -/* ORDERING WIDGET */ -ul#orderthese { position:absolute; top:8em; right:0; width:240px; padding:0; margin:0; list-style-type:none; } -ul#orderthese li { list-style-type:none; display:block; padding:0; margin:6px 0; width:214px; background:#f6f6f6; white-space:nowrap; overflow:hidden; } -ul#orderthese li span { display:block; border:1px solid #e7e7e7; background:transparent url(../img/admin/nav-bg-grabber.gif) top left repeat-y; font-size:10px !important; padding:4px 6px 4px 12px; } -ul#orderthese span:hover { background-color:#efefef; } - -/* PAGINATOR */ -.paginator { font-size:11px; padding-top:10px; padding-bottom:10px; line-height:22px; margin:0; border-top:1px solid #ddd; } -.paginator a:link, .paginator a:visited { padding:2px 6px; border:solid 1px #ccc; background:white; text-decoration:none; } -.paginator a.showall { padding:0 !important; border:none !important; } -.paginator a.showall:hover { color:#036 !important; background:transparent !important; } -.paginator .end { border-width:2px !important; margin-right:6px; } -.paginator .this-page { padding:2px 6px; font-weight:bold; font-size:13px; vertical-align:top; } -.paginator a:hover { color:white; background:#5b80b2; border-color:#036; } - -/* TEXT STYLES & MODIFIERS */ +/* TEXT STYLES & MODIFIERS */ .small { font-size:11px; } .tiny { font-size:10px; } p.tiny { margin-top:-2px; } @@ -313,13 +52,90 @@ p img, h1 img, h2 img, h3 img, h4 img, td img { vertical-align:middle; } .example { margin:10px 0; padding:5px 10px; background:#efefef; } .nowrap { white-space:nowrap; } -/* CUSTOM FORM FIELDS */ -.vSelectMultipleField { vertical-align:top !important; } -.vCheckboxField { border:none; } -.vDateField, .vTimeField { margin-right:2px; } -.vFileUploadField { border:none; } -.vURLField { width:380px; } -.vLargeTextField, .vXMLLargeTextField { width:480px; } -.colM .vLargeTextField, .colM .vXMLLargeTextField { width:720px; } -body.core-flatfile #id_content { height: 400px; } -.module table .vPositiveSmallIntegerField { width: 22px; } \ No newline at end of file +/* TABLES */ +table { border-collapse:collapse; border-color:#ccc; } +td, th { font-size:11px; line-height:13px; border-bottom:1px solid #eee; vertical-align:top; padding:5px; font-family:"Lucida Grande", Verdana, Arial, sans-serif; } +th { text-align:left; font-size:12px; font-weight:bold; } +thead th, +tfoot td { color:#666; padding:2px 5px; font-size:11px; background:#e1e1e1 url(../img/admin/nav-bg.gif) top left repeat-x; border-left:1px solid #ddd; border-bottom:1px solid #ddd; } +tfoot td { border-bottom:none; border-top:1px solid #ddd; } +thead th:first-child, +tfoot td:first-child { border-left:none !important; } +thead th.optional { font-weight:normal !important; } +fieldset table { border-right:1px solid #eee; } +tr.row-label td { font-size:9px; padding-top:2px; padding-bottom:0; border-bottom:none; color:#666; margin-top:-1px; } +tr.alt { background:#f6f6f6; } +.row1 { background:#EDF3FE; } +.row2 { background:white; } + +/* SORTABLE TABLES */ +thead th a:link, thead th a:visited { color:#666; display:block; } +table thead th.sorted { background-position:bottom left !important; } +table thead th.sorted a { padding-right:13px; } +table thead th.ascending a { background:url(../img/admin/arrow-down.gif) right .4em no-repeat; } +table thead th.descending a { background:url(../img/admin/arrow-up.gif) right .4em no-repeat; } + +/* ORDERABLE TABLES */ +table.orderable tbody tr td:hover { cursor:move; } +table.orderable tbody tr td:first-child { padding-left:14px; background-image:url(../img/admin/nav-bg-grabber.gif); background-repeat:repeat-y; } +table.orderable-initalized .order-cell, body>tr>td.order-cell { display:none; } + +/* FORM DEFAULTS */ +input, textarea, select { margin:2px 0; padding:2px 3px; vertical-align:middle; font-family:"Lucida Grande", Verdana, Arial, sans-serif; font-weight:normal; font-size:11px; } +textarea { vertical-align:top !important; } +input[type=text], input[type=password], textarea, select, .vTextField { border:1px solid #ccc; } + +/* FORM BUTTONS */ +input[type=submit], input[type=button], .submit-row input { background:white url(../img/admin/nav-bg.gif) bottom repeat-x; padding:3px; color:black; } +input[type=submit]:active, input[type=button]:active { background-image:url(../img/admin/nav-bg-reverse.gif); background-position:top; } +input[type=submit].default, .submit-row input.default { border:2px solid #5b80b2; background:#7CA0C7 url(../img/admin/default-bg.gif) bottom repeat-x; font-weight:bold; color:white; } +input[type=submit].default:active { background-image:url(../img/admin/default-bg-reverse.gif); background-position:top; } + +/* MODULES */ +.module { border:1px solid #ccc; margin-bottom:5px; background:white; } +.module p, .module ul, .module h3, .module h4, .module dl, .module pre { padding-left:10px; padding-right:10px; } +.module blockquote { margin-left:12px; } +.module ul, .module ol { margin-left:1.5em; } +.module h3 { margin-top:.6em; } +.module h2, .module caption { margin:0; padding:2px 5px 3px 5px; font-size:11px; text-align:left; font-weight:bold; background:#7CA0C7 url(../img/admin/default-bg.gif) top left repeat-x; color:white; } +.module table { border-collapse: collapse; } + +/* MESSAGES & ERRORS */ +ul.messagelist { padding:0 0 5px 0; margin:0; } +ul.messagelist li { font-size:12px; display:block; padding:4px 5px 4px 25px; margin:0 0 3px 0; border-bottom:1px solid #ddd; color:#666; background:#ffc url(../img/admin/icon_success.gif) 5px .3em no-repeat; } +.errornote { font-size:12px !important; display:block; padding:4px 5px 4px 25px; margin:0 0 3px 0; border:1px solid red; color:red;background:#ffc url(../img/admin/icon_error.gif) 5px .3em no-repeat; } +ul.errorlist { margin:0 !important; padding:0 !important; } +.errorlist li { font-size:12px !important; display:block; padding:4px 5px 4px 25px; margin:0 0 3px 0; border:1px solid red; color:white; background:red url(../img/admin/icon_alert.gif) 5px .3em no-repeat; } +td ul.errorlist { margin:0 !important; padding:0 !important; } +td ul.errorlist li { margin:0 !important; } +.error { background:#ffc; } +.error input, .error select { border:1px solid red; } +div.system-message { background: #ffc; margin: 10px; padding: 6px 8px; font-size: .8em; } +div.system-message p.system-message-title { padding:4px 5px 4px 25px; margin:0; color:red; background:#ffc url(../img/admin/icon_error.gif) 5px .3em no-repeat; } +.description { font-size:12px; padding:5px 0 0 12px; } + +/* BREADCRUMBS */ +div.breadcrumbs { background:white url(../img/admin/nav-bg-reverse.gif) 0 -10px repeat-x; padding:2px 8px 3px 8px; font-size:11px; color:#999; border-top:1px solid white; border-bottom:1px solid #ccc; text-align:left; } + +/* ACTION ICONS */ +.addlink { padding-left:12px; background:url(../img/admin/icon_addlink.gif) 0 .2em no-repeat; } +.changelink { padding-left:12px; background:url(../img/admin/icon_changelink.gif) 0 .2em no-repeat; } +.deletelink { padding-left:12px; background:url(../img/admin/icon_deletelink.gif) 0 .25em no-repeat; } +a.deletelink:link, a.deletelink:visited { color:#CC3434; } +a.deletelink:hover { color:#993333; } + +/* OBJECT TOOLS */ +.object-tools { font-size:10px; font-weight:bold; font-family:Arial,Helvetica,sans-serif; padding-left:0; float:right; position:relative; margin-top:-2.4em; margin-bottom:-2em; } +.form-row .object-tools { margin-top:5px; margin-bottom:5px; float:none; height:2em; padding-left:3.5em; } +.object-tools li { display:block; float:left; background:url(../img/admin/tool-left.gif) 0 0 no-repeat; padding:0 0 0 8px; margin-left:2px; height:16px; } +.object-tools li:hover { background:url(../img/admin/tool-left_over.gif) 0 0 no-repeat; } +.object-tools a:link, .object-tools a:visited { display:block; float:left; color:white; padding:.1em 14px .1em 8px; height:14px; background:#999 url(../img/admin/tool-right.gif) 100% 0 no-repeat; } +.object-tools a:hover, .object-tools li:hover a { background:#5b80b2 url(../img/admin/tool-right_over.gif) 100% 0 no-repeat; } +.object-tools a.viewsitelink, .object-tools a.golink { background:#999 url(../img/admin/tooltag-arrowright.gif) top right no-repeat; padding-right:28px; } +.object-tools a.viewsitelink:hover, .object-tools a.golink:hover { background:#5b80b2 url(../img/admin/tooltag-arrowright_over.gif) top right no-repeat; } +.object-tools a.addlink { background:#999 url(../img/admin/tooltag-add.gif) top right no-repeat; padding-right:28px; } +.object-tools a.addlink:hover { background:#5b80b2 url(../img/admin/tooltag-add_over.gif) top right no-repeat; } + +/* OBJECT HISTORY */ +table#change-history { width:100%; } +table#change-history tbody th { width:16em; } diff --git a/django/contrib/admin/media/css/layout.css b/django/contrib/admin/media/css/layout.css new file mode 100644 index 0000000000..19c9286b85 --- /dev/null +++ b/django/contrib/admin/media/css/layout.css @@ -0,0 +1,29 @@ +/* PAGE STRUCTURE */ +#container { position:relative; width:100%; min-width:760px; } +#content { margin:10px 15px; } +#header { width:100%; } +#content-main { float:left; width:100%; } +#content-related { float:right; width:220px; position:relative; margin-right:-230px; } +#footer { clear:both; padding:10px; } + +/* COLUMN TYPES */ +.colMS { margin-right:245px !important; } +.colSM { margin-left:245px !important; } +.colSM #content-related { float:left; margin-right:0; margin-left:-230px; } +.colSM #content-main { float:right; } +.popup .colM { width:95%; } +.subcol { float:left; width:46%; margin-right:15px; } +.dashboard #content { width:500px; } + +/* HEADER */ +#header { background:#417690; color:#ffc; overflow:hidden; } +#header a:link, #header a:visited { color:white; } +#header a:hover { text-decoration:underline; } +#branding h1 { padding:0 10px; font-size:18px; margin:8px 0; font-weight:normal; color:#f4f379; } +#branding h2 { padding:0 10px; font-size:14px; margin:-8px 0 8px 0; font-weight:normal; color:#ffc; } +#user-tools { position:absolute; top:0; right:0; padding:1.2em 10px; font-size:11px; text-align:right; } + +/* SIDEBAR */ +#content-related h3 { font-size:12px; color:#666; margin-bottom:3px; } +#content-related h4 { font-size:11px; } +#content-related .module h2 { background:#eee url(../img/admin/nav-bg.gif) bottom left repeat-x; color:#666; } \ No newline at end of file diff --git a/django/contrib/admin/media/css/login.css b/django/contrib/admin/media/css/login.css new file mode 100644 index 0000000000..041135f31e --- /dev/null +++ b/django/contrib/admin/media/css/login.css @@ -0,0 +1,13 @@ +@import url('base.css'); +@import url('layout.css'); + +/* LOGIN FORM */ +body.login { background:#eee; } +.login #container { background:white; border:1px solid #ccc; width:28em; min-width:300px; margin-left:auto; margin-right:auto; margin-top:100px; } +.login #content-main { width:100%; } +.login form { margin-top:1em; } +.login .form-row { padding:4px 0; float:left; width:100%; } +.login .form-row label { float:left; width:7em; padding-right:0.5em; line-height:2em; text-align:right; font-size:1em; color:#333; } +.login .form-row #id_username, .login .form-row #id_password { width:16em; } +.login span.help { font-size:10px; display:block; } +.login .submit-row { clear:both; padding:1em 0 0 7.4em; } \ No newline at end of file diff --git a/django/contrib/admin/media/css/patch-iewin.css b/django/contrib/admin/media/css/patch-iewin.css index 46531325df..b2e6a4c560 100644 --- a/django/contrib/admin/media/css/patch-iewin.css +++ b/django/contrib/admin/media/css/patch-iewin.css @@ -1,7 +1,6 @@ * html #container { position:static; } /* keep header from flowing off the page */ * html .colMS #content-related { margin-right:0; margin-left:10px; position:static; } /* put the right sidebars back on the page */ * html .colSM #content-related { margin-right:10px; margin-left:-115px; position:static; } /* put the left sidebars back on the page */ +* html .form-row { height:1%; } * html .dashboard #content { width:768px; } /* proper fixed width for dashboard in IE6 */ -* html .dashboard #content-main { width:535px; } /* proper fixed width for dashboard in IE6 */ -* html #content { width /**/: 768px; } /* fixed width for IE5 */ -* html #content-main { width /**/: 535px; } /* fixed width for IE5 */ \ No newline at end of file +* html .dashboard #content-main { width:535px; } /* proper fixed width for dashboard in IE6 */ \ No newline at end of file diff --git a/django/contrib/admin/media/css/widgets.css b/django/contrib/admin/media/css/widgets.css new file mode 100644 index 0000000000..bf526bfd66 --- /dev/null +++ b/django/contrib/admin/media/css/widgets.css @@ -0,0 +1,101 @@ +/* SELECTOR (FILTER INTERFACE) */ +.selector { width:580px; float:left; } +.selector select { width:270px; height:17.2em; } +.selector-available, .selector-chosen { float:left; width:270px; text-align:center; margin-bottom:5px; } +.selector-available h2, .selector-chosen h2 { border:1px solid #ccc; } +.selector .selector-available h2 { background:white url(../img/admin/nav-bg.gif) bottom left repeat-x; color:#666; } +.selector .selector-filter { background:white; border:1px solid #ccc; border-width:0 1px; padding:3px; color:#999; font-size:10px; margin:0; text-align:left; } +.selector .selector-chosen .selector-filter { padding:4px 5px; } +.selector .selector-available input { width:230px; } +.selector ul.selector-chooser { float:left; width:22px; height:50px; background:url(../img/admin/chooser-bg.gif) top center no-repeat; margin:8em 3px 0 3px; padding:0; } +.selector-chooser li { margin:0; padding:3px; list-style-type:none; } +.selector select { margin-bottom:5px; margin-top:0; } +.selector-add, .selector-remove { width:16px; height:16px; display:block; text-indent:-3000px; } +.selector-add { background:url(../img/admin/selector-add.gif) top center no-repeat; margin-bottom:2px; } +.selector-remove { background:url(../img/admin/selector-remove.gif) top center no-repeat; } +a.selector-chooseall, a.selector-clearall { display:block; width:6em; text-align:left; margin-left:auto; margin-right:auto; font-weight:bold; color:#666; padding:3px 0 3px 18px; } +a.selector-chooseall:hover, a.selector-clearall:hover { color:#036; } +a.selector-chooseall { width:7em; background:url(../img/admin/selector-addall.gif) left center no-repeat; } +a.selector-clearall { background:url(../img/admin/selector-removeall.gif) left center no-repeat; } + +/* STACKED SELECTORS */ +.stacked { float:left; width:500px; } +.stacked select { width:480px; height:10.1em; } +.stacked .selector-available, .stacked .selector-chosen { width:480px; } +.stacked .selector-available { margin-bottom:0; } +.stacked .selector-available input { width:442px; } +.stacked ul.selector-chooser { height:22px; width:50px; margin:0 0 3px 40%; background:url(../img/admin/chooser_stacked-bg.gif) top center no-repeat; } +.stacked .selector-chooser li { float:left; padding:3px 3px 3px 5px; } +.stacked .selector-chooseall, .stacked .selector-clearall { display:none; } +.stacked .selector-add { background-image:url(../img/admin/selector_stacked-add.gif); } +.stacked .selector-remove { background-image:url(../img/admin/selector_stacked-remove.gif); } + +/* DATE AND TIME */ +p.datetime { line-height:20px; margin:0; padding:0; color:#666; font-size:11px; font-weight:bold; } +.datetime span { font-size:11px; color:#ccc; font-weight:normal; white-space:nowrap; } +.vDateField { margin-left:4px; } +table p.datetime { font-size:10px; margin-left:0; padding-left:0; } + +/* FILE UPLOADS */ +p.file-upload { line-height:20px; margin:0; padding:0; color:#666; font-size:11px; font-weight:bold; } +.file-upload a { font-weight:normal; } +.file-upload .deletelink { margin-left:5px; } + +/* CALENDARS & CLOCKS */ +.calendarbox, .clockbox { margin:5px auto; font-size:11px; width:16em; text-align:center; background:white; position:relative; } +.clockbox { width:9em; } +.calendar { margin:0; padding: 0; } +.calendar table { margin:0; padding:0; border-collapse:collapse; background:white; width:99%; } +.calendar caption, .calendarbox h2 { margin: 0; font-size:11px; text-align:center; border-top:none; } +.calendar th { font-size:10px; color:#666; padding:2px 3px; text-align:center; background:#e1e1e1 url(../img/admin/nav-bg.gif) 0 50% repeat-x; border-bottom:1px solid #ddd; } +.calendar td { font-size:11px; text-align: center; padding: 0; border-top:1px solid #eee; border-bottom:none; } +.calendar td.selected a { background: #C9DBED; } +.calendar td.nonday { background:#efefef; } +.calendar td.today a { background:#ffc; } +.calendar td a, .timelist a { display: block; font-weight:bold; padding:4px; text-decoration: none; color:#444; } +.calendar td a:hover, .timelist a:hover { background: #5b80b2; color:white; } +.calendar td a:active, .timelist a:active { background: #036; color:white; } +.calendarnav { font-size:10px; text-align: center; color:#ccc; margin:0; padding:1px 3px; } +.calendarnav a:link, #calendarnav a:visited, #calendarnav a:hover { color: #999; } +.calendar-shortcuts { background:white; font-size:10px; line-height:11px; border-top:1px solid #eee; padding:3px 0 4px; color:#ccc; } +.calendarbox .calendarnav-previous, .calendarbox .calendarnav-next { display:block; position:absolute; font-weight:bold; font-size:12px; background:#C9DBED url(../img/admin/default-bg.gif) bottom left repeat-x; padding:1px 4px 2px 4px; color:white; } +.calendarnav-previous:hover, .calendarnav-next:hover { background:#036; } +.calendarnav-previous { top:0; left:0; } +.calendarnav-next { top:0; right:0; } +.calendar-cancel { margin:0 !important; padding:0; font-size:10px; background:#e1e1e1 url(../img/admin/nav-bg.gif) 0 50% repeat-x; border-top:1px solid #ddd; } +.calendar-cancel a { padding:2px; color:#999; } +ul.timelist, .timelist li { list-style-type:none; margin:0; padding:0; } +.timelist a { padding:2px; } + +/* INLINE ORDERER */ +ul.orderer { position:relative; padding:0 !important; margin:0 !important; list-style-type:none; } +ul.orderer li { list-style-type:none; display:block; padding:0; margin:0; border:1px solid #bbb; border-width:0 1px 1px 0; white-space:nowrap; overflow:hidden; background:#e2e2e2 url(../img/admin/nav-bg-grabber.gif) repeat-y; } +ul.orderer li:hover { cursor:move; background-color:#ddd; } +ul.orderer li a.selector { margin-left:12px; overflow:hidden; width:83%; font-size:10px !important; padding:0.6em 0; } +ul.orderer li a:link, ul.orderer li a:visited { color:#333; } +ul.orderer li .inline-deletelink { position:absolute; right:4px; margin-top:0.6em; } +ul.orderer li.selected { background-color:#f8f8f8; border-right-color:#f8f8f8; } +ul.orderer li.deleted { background:#bbb url(../img/admin/deleted-overlay.gif); } +ul.orderer li.deleted a:link, ul.orderer li.deleted a:visited { color:#888; } +ul.orderer li.deleted .inline-deletelink { background-image:url(../img/admin/inline-restore.png); } +ul.orderer li.deleted:hover, ul.orderer li.deleted a.selector:hover { cursor:default; } + +/* EDIT INLINE */ +.inline-deletelink { display:block; text-indent:-9999px; background:transparent url(../img/admin/inline-delete.png) no-repeat; width:15px; height:15px; margin:0.4em 0; border: 0px none; } +.inline-deletelink:hover { background-position:-15px 0; cursor:pointer; } +.editinline button.addlink { border: 0px none; color: #5b80b2; font-size: 100%; cursor: pointer; } +.editinline button.addlink:hover { color: #036; cursor: pointer; } +.editinline table .help { text-align:right; float:right; padding-left:2em; } +.editinline tfoot .addlink { white-space:nowrap; } +.editinline table thead th:last-child { border-left:none; } +.editinline tr.deleted { background:#ddd url(../img/admin/deleted-overlay.gif); } +.editinline tr.deleted .inline-deletelink { background-image:url(../img/admin/inline-restore.png); } +.editinline tr.deleted td:hover { cursor:default; } +.editinline tr.deleted td:first-child { background-image:none !important; } + +/* EDIT INLINE - STACKED */ +.editinline-stacked { min-width:758px; } +.editinline-stacked .inline-object { margin-left:210px; background:white; } +.editinline-stacked .inline-source { float:left; width:200px; background:#f8f8f8; } +.editinline-stacked .inline-splitter { float:left; width:9px; background:#f8f8f8 url(../img/admin/inline-splitter-bg.gif) 50% 50% no-repeat; border-right:1px solid #ccc; } +.editinline-stacked .controls { clear:both; background:#e1e1e1 url(../img/admin/nav-bg.gif) top left repeat-x; padding:3px 4px; font-size:11px; border-top:1px solid #ddd; } \ No newline at end of file diff --git a/django/contrib/admin/media/img/admin/deleted-overlay.gif b/django/contrib/admin/media/img/admin/deleted-overlay.gif new file mode 100644 index 0000000000..dc3828fe06 Binary files /dev/null and b/django/contrib/admin/media/img/admin/deleted-overlay.gif differ diff --git a/django/contrib/admin/media/img/admin/inline-delete-8bit.png b/django/contrib/admin/media/img/admin/inline-delete-8bit.png new file mode 100644 index 0000000000..95caf59a8d Binary files /dev/null and b/django/contrib/admin/media/img/admin/inline-delete-8bit.png differ diff --git a/django/contrib/admin/media/img/admin/inline-delete.png b/django/contrib/admin/media/img/admin/inline-delete.png new file mode 100644 index 0000000000..d59bcd2444 Binary files /dev/null and b/django/contrib/admin/media/img/admin/inline-delete.png differ diff --git a/django/contrib/admin/media/img/admin/inline-restore-8bit.png b/django/contrib/admin/media/img/admin/inline-restore-8bit.png new file mode 100644 index 0000000000..e087c8ead3 Binary files /dev/null and b/django/contrib/admin/media/img/admin/inline-restore-8bit.png differ diff --git a/django/contrib/admin/media/img/admin/inline-restore.png b/django/contrib/admin/media/img/admin/inline-restore.png new file mode 100644 index 0000000000..efdd92ac39 Binary files /dev/null and b/django/contrib/admin/media/img/admin/inline-restore.png differ diff --git a/django/contrib/admin/media/img/admin/inline-splitter-bg.gif b/django/contrib/admin/media/img/admin/inline-splitter-bg.gif new file mode 100644 index 0000000000..32ac5b3498 Binary files /dev/null and b/django/contrib/admin/media/img/admin/inline-splitter-bg.gif differ diff --git a/django/contrib/admin/media/js/admin/RelatedObjectLookups.js b/django/contrib/admin/media/js/admin/RelatedObjectLookups.js index 72c4e95eca..cb84790f44 100644 --- a/django/contrib/admin/media/js/admin/RelatedObjectLookups.js +++ b/django/contrib/admin/media/js/admin/RelatedObjectLookups.js @@ -39,7 +39,7 @@ function dismissAddAnotherPopup(win, newId, newRepr) { if (elem.nodeName == 'SELECT') { var o = new Option(newRepr, newId); elem.options[elem.options.length] = o; - elem.selectedIndex = elem.length - 1; + o.selected = true; } else if (elem.nodeName == 'INPUT') { elem.value = newId; } diff --git a/django/contrib/admin/models.py b/django/contrib/admin/models.py new file mode 100644 index 0000000000..022d20bed9 --- /dev/null +++ b/django/contrib/admin/models.py @@ -0,0 +1,51 @@ +from django.db import models +from django.contrib.contenttypes.models import ContentType +from django.contrib.auth.models import User +from django.utils.translation import gettext_lazy as _ + +ADDITION = 1 +CHANGE = 2 +DELETION = 3 + +class LogEntryManager(models.Manager): + def log_action(self, user_id, content_type_id, object_id, object_repr, action_flag, change_message=''): + e = self.model(None, None, user_id, content_type_id, object_id, object_repr[:200], action_flag, change_message) + e.save() + +class LogEntry(models.Model): + action_time = models.DateTimeField(_('action time'), auto_now=True) + user = models.ForeignKey(User) + content_type = models.ForeignKey(ContentType, blank=True, null=True) + object_id = models.TextField(_('object id'), blank=True, null=True) + object_repr = models.CharField(_('object repr'), maxlength=200) + action_flag = models.PositiveSmallIntegerField(_('action flag')) + change_message = models.TextField(_('change message'), blank=True) + objects = LogEntryManager() + class Meta: + verbose_name = _('log entry') + verbose_name_plural = _('log entries') + db_table = 'django_admin_log' + ordering = ('-action_time',) + + def __repr__(self): + return str(self.action_time) + + def is_addition(self): + return self.action_flag == ADDITION + + def is_change(self): + return self.action_flag == CHANGE + + def is_deletion(self): + return self.action_flag == DELETION + + def get_edited_object(self): + "Returns the edited object represented by this log entry" + return self.content_type.get_object_for_this_type(pk=self.object_id) + + def get_admin_url(self): + """ + Returns the admin URL to edit the object represented by this log entry. + This is relative to the Django admin index page. + """ + return "%s/%s/%s/" % (self.content_type.app_label, self.content_type.model, self.object_id) diff --git a/django/contrib/admin/models/__init__.py b/django/contrib/admin/models/__init__.py deleted file mode 100644 index e11e2df093..0000000000 --- a/django/contrib/admin/models/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__all__ = ['admin'] diff --git a/django/contrib/admin/models/admin.py b/django/contrib/admin/models/admin.py deleted file mode 100644 index b7bcda192b..0000000000 --- a/django/contrib/admin/models/admin.py +++ /dev/null @@ -1,50 +0,0 @@ -from django.core import meta -from django.models import auth, core -from django.utils.translation import gettext_lazy as _ - -class LogEntry(meta.Model): - action_time = meta.DateTimeField(_('action time'), auto_now=True) - user = meta.ForeignKey(auth.User) - content_type = meta.ForeignKey(core.ContentType, blank=True, null=True) - object_id = meta.TextField(_('object id'), blank=True, null=True) - object_repr = meta.CharField(_('object repr'), maxlength=200) - action_flag = meta.PositiveSmallIntegerField(_('action flag')) - change_message = meta.TextField(_('change message'), blank=True) - class META: - module_name = 'log' - verbose_name = _('log entry') - verbose_name_plural = _('log entries') - db_table = 'django_admin_log' - ordering = ('-action_time',) - module_constants = { - 'ADDITION': 1, - 'CHANGE': 2, - 'DELETION': 3, - } - - def __repr__(self): - return str(self.action_time) - - def is_addition(self): - return self.action_flag == ADDITION - - def is_change(self): - return self.action_flag == CHANGE - - def is_deletion(self): - return self.action_flag == DELETION - - def get_edited_object(self): - "Returns the edited object represented by this log entry" - return self.get_content_type().get_object_for_this_type(pk=self.object_id) - - def get_admin_url(self): - """ - Returns the admin URL to edit the object represented by this log entry. - This is relative to the Django admin index page. - """ - return "%s/%s/%s/" % (self.get_content_type().get_package(), self.get_content_type().python_module_name, self.object_id) - - def _module_log_action(user_id, content_type_id, object_id, object_repr, action_flag, change_message=''): - e = LogEntry(None, None, user_id, content_type_id, object_id, object_repr[:200], action_flag, change_message) - e.save() diff --git a/django/contrib/admin/templates/admin/404.html b/django/contrib/admin/templates/admin/404.html index d791f565ba..9bf4293e76 100644 --- a/django/contrib/admin/templates/admin/404.html +++ b/django/contrib/admin/templates/admin/404.html @@ -1,4 +1,4 @@ -{% extends "admin/base_site" %} +{% extends "admin/base_site.html" %} {% load i18n %} {% block title %}{% trans 'Page not found' %}{% endblock %} diff --git a/django/contrib/admin/templates/admin/500.html b/django/contrib/admin/templates/admin/500.html index 9d3e3de32c..b30e43170d 100644 --- a/django/contrib/admin/templates/admin/500.html +++ b/django/contrib/admin/templates/admin/500.html @@ -1,4 +1,4 @@ -{% extends "admin/base_site" %} +{% extends "admin/base_site.html" %} {% load i18n %} {% block breadcrumbs %}{% endblock %} diff --git a/django/contrib/admin/templates/admin/base_site.html b/django/contrib/admin/templates/admin/base_site.html index b4d285b779..b867bd29bd 100644 --- a/django/contrib/admin/templates/admin/base_site.html +++ b/django/contrib/admin/templates/admin/base_site.html @@ -1,4 +1,4 @@ -{% extends "admin/base" %} +{% extends "admin/base.html" %} {% load i18n %} {% block title %}{{ title }} | {% trans 'Django site admin' %}{% endblock %} diff --git a/django/contrib/admin/templates/admin/change_form.html b/django/contrib/admin/templates/admin/change_form.html index 02d5760509..a667087f5f 100644 --- a/django/contrib/admin/templates/admin/change_form.html +++ b/django/contrib/admin/templates/admin/change_form.html @@ -1,36 +1,39 @@ -{% extends "admin/base_site" %} +{% extends "admin/base_site.html" %} {% load i18n admin_modify adminmedia %} {% block extrahead %}{{ block.super }} -{% for js in bound_manipulator.javascript_imports %}{% include_admin_script js %}{% endfor %} +{% for js in javascript_imports %}{% include_admin_script js %}{% endfor %} {% endblock %} -{% block coltype %}{{ bound_manipulator.coltype }}{% endblock %} -{% block bodyclass %}{{ app_label }}-{{ bound_manipulator.object_name.lower }} change-form{% endblock %} +{% block stylesheet %}{% admin_media_prefix %}css/forms.css{% endblock %} +{% block coltype %}{% if ordered_objects %}colMS{% else %}colM{% endif %}{% endblock %} +{% block bodyclass %}{{ opts.app_label }}-{{ opts.object_name.lower }} change-form{% endblock %} {% block userlinks %}{% trans 'Documentation' %} / {% trans 'Change password' %} / {% trans 'Log out' %}{% endblock %} {% block breadcrumbs %}{% if not is_popup %} {% endif %}{% endblock %} {% block content %}
{% if change %}{% if not is_popup %} {% endif %}{% endif %} -
{% block form_top %}{% endblock %} +{% block form_top %}{% endblock %} +
{% if is_popup %}{% endif %} -{% if bound_manipulator.save_on_top %}{% submit_row bound_manipulator %}{% endif %} +{% if opts.admin.save_on_top %}{% submit_row %}{% endif %} {% if form.error_dict %}

{% blocktrans count form.error_dict.items|length as counter %}Please correct the error below.{% plural %}Please correct the errors below.{% endblocktrans %}

{% endif %} -{% for bound_field_set in bound_manipulator.bound_field_sets %} +{% for bound_field_set in bound_field_sets %}
{% if bound_field_set.name %}

{{ bound_field_set.name }}

{% endif %} + {% if bound_field_set.description %}
{{ bound_field_set.description }}
{% endif %} {% for bound_field_line in bound_field_set %} {% admin_field_line bound_field_line %} {% for bound_field in bound_field_line %} @@ -41,7 +44,7 @@ {% endfor %} {% block after_field_sets %}{% endblock %} {% if change %} - {% if bound_manipulator.ordered_objects %} + {% if ordered_objects %}

{% trans "Ordering" %}

{% if form.order_.errors %}{{ form.order_.html_error_list }}{% endif %} @@ -49,27 +52,17 @@
{% endif %} {% endif %} -{% for related_object in bound_manipulator.inline_related_objects %}{% edit_inline related_object %}{% endfor %} +{% for related_object in inline_related_objects %}{% edit_inline related_object %}{% endfor %} {% block after_related_objects %}{% endblock %} -{% submit_row bound_manipulator %} +{% submit_row %} {% if add %} - + {% endif %} -{% if bound_manipulator.auto_populated_fields %} +{% if auto_populated_fields %} {% endif %} -{% if change %} - {% if bound_manipulator.ordered_objects %} - {% if form.order_objects %}
    - {% for object in form.order_objects %} -
  • - {{ object|truncatewords:"5" }} -
  • - {% endfor %} -
{% endif %} - {% endif %} -{% endif %} +
{% endblock %} diff --git a/django/contrib/admin/templates/admin/change_list.html b/django/contrib/admin/templates/admin/change_list.html index 17b388b699..5b54bfb8cc 100644 --- a/django/contrib/admin/templates/admin/change_list.html +++ b/django/contrib/admin/templates/admin/change_list.html @@ -1,8 +1,9 @@ -{% extends "admin/base_site" %} +{% extends "admin/base_site.html" %} {% load adminmedia admin_list i18n %} +{% block stylesheet %}{% admin_media_prefix %}css/changelists.css{% endblock %} {% block bodyclass %}change-list{% endblock %} {% block userlinks %}{% trans 'Documentation' %} / {% trans 'Change password' %} / {% trans 'Log out' %}{% endblock %} -{% if not is_popup %}{% block breadcrumbs %}{% endblock %}{% endif %} +{% if not is_popup %}{% block breadcrumbs %}{% endblock %}{% endif %} {% block coltype %}flex{% endblock %} {% block content %}
diff --git a/django/contrib/admin/templates/admin/delete_confirmation.html b/django/contrib/admin/templates/admin/delete_confirmation.html index 7fba4cebd7..f907c18a16 100644 --- a/django/contrib/admin/templates/admin/delete_confirmation.html +++ b/django/contrib/admin/templates/admin/delete_confirmation.html @@ -1,6 +1,14 @@ -{% extends "admin/base_site" %} +{% extends "admin/base_site.html" %} {% load i18n %} {% block userlinks %}{% trans 'Documentation' %} / {% trans 'Change password' %} / {% trans 'Log out' %}{% endblock %} +{% block breadcrumbs %} + +{% endblock %} {% block content %} {% if perms_lacking %}

{% blocktrans %}Deleting the {{ object_name }} '{{ object }}' would result in deleting related objects, but your account doesn't have permission to delete the following types of objects:{% endblocktrans %}

@@ -13,8 +21,10 @@

{% blocktrans %}Are you sure you want to delete the {{ object_name }} "{{ object }}"? All of the following related items will be deleted:{% endblocktrans %}

    {{ deleted_objects|unordered_list }}
+
+
{% endif %} {% endblock %} diff --git a/django/contrib/admin/templates/admin/edit_inline_stacked.html b/django/contrib/admin/templates/admin/edit_inline_stacked.html index 62549ef82d..45aa0a4f58 100644 --- a/django/contrib/admin/templates/admin/edit_inline_stacked.html +++ b/django/contrib/admin/templates/admin/edit_inline_stacked.html @@ -13,4 +13,4 @@ {% endif %} {% endfor %} {% endfor %} - \ No newline at end of file + diff --git a/django/contrib/admin/templates/admin/field_line.html b/django/contrib/admin/templates/admin/field_line.html index 10f37d5dc9..b7e2fc2ae0 100644 --- a/django/contrib/admin/templates/admin/field_line.html +++ b/django/contrib/admin/templates/admin/field_line.html @@ -9,14 +9,6 @@ {% if not bound_field.has_label_first %} {% field_label bound_field %} {% endif %} - {% if change %} - {% if bound_field.field.primary_key %} - {{ bound_field.original_value }} - {% endif %} - {% if bound_field.raw_id_admin %} - {% if bound_field.existing_display %} {{ bound_field.existing_display|truncatewords:"14" }}{% endif %} - {% endif %} - {% endif %} {% if bound_field.field.help_text %}

{{ bound_field.field.help_text }}

{% endif %} {% endfor %}
diff --git a/django/contrib/admin/templates/admin/index.html b/django/contrib/admin/templates/admin/index.html index aabd4eecca..246086861b 100644 --- a/django/contrib/admin/templates/admin/index.html +++ b/django/contrib/admin/templates/admin/index.html @@ -1,6 +1,7 @@ -{% extends "admin/base_site" %} +{% extends "admin/base_site.html" %} {% load i18n %} +{% block stylesheet %}{% load adminmedia %}{% admin_media_prefix %}css/dashboard.css{% endblock %} {% block coltype %}colMS{% endblock %} {% block bodyclass %}dashboard{% endblock %} {% block breadcrumbs %}{% endblock %} @@ -13,14 +14,14 @@ {% if app_list %} {% for app in app_list %}
-

{{ app.name }}

- +
+ {% for model in app.models %} {% if model.perms.change %} - + {% else %} - + {% endif %} {% if model.perms.add %} @@ -57,7 +58,7 @@ {% else %} {% endif %} diff --git a/django/contrib/admin/templates/admin/login.html b/django/contrib/admin/templates/admin/login.html index ea823e1020..5f338f703e 100644 --- a/django/contrib/admin/templates/admin/login.html +++ b/django/contrib/admin/templates/admin/login.html @@ -1,6 +1,9 @@ -{% extends "admin/base_site" %} +{% extends "admin/base_site.html" %} {% load i18n %} +{% block stylesheet %}{% load adminmedia %}{% admin_media_prefix %}css/login.css{% endblock %} +{% block bodyclass %}login{% endblock %} +{% block content_title %}{% endblock %} {% block breadcrumbs %}{% endblock %} {% block content %} @@ -9,20 +12,18 @@

{{ error_message }}

{% endif %}
-
- -

- -

-

- - -{% comment %} {% trans 'Have you forgotten your password?' %}{% endcomment %} -

- -
- -
+ +
+ +
+
+ + + {% comment %}{% trans 'Have you forgotten your password?' %}{% endcomment %} +
+
+ +
' % (ADMIN_MEDIA_PREFIX, script_path) + return '' % (settings.ADMIN_MEDIA_PREFIX, script_path) include_admin_script = register.simple_tag(include_admin_script) -def submit_row(context, bound_manipulator): +def submit_row(context): + opts = context['opts'] change = context['change'] - add = context['add'] - show_delete = context['show_delete'] - has_delete_permission = context['has_delete_permission'] is_popup = context['is_popup'] return { - 'onclick_attrib': (bound_manipulator.ordered_objects and change + 'onclick_attrib': (opts.get_ordered_objects() and change and 'onclick="submitOrderForm();"' or ''), - 'show_delete_link': (not is_popup and has_delete_permission - and (change or show_delete)), - 'show_save_as_new': not is_popup and change and bound_manipulator.save_as, - 'show_save_and_add_another': not is_popup and (not bound_manipulator.save_as or add), - 'show_save_and_continue': not is_popup, + 'show_delete_link': (not is_popup and context['has_delete_permission'] + and (change or context['show_delete'])), + 'show_save_as_new': not is_popup and change and opts.admin.save_as, + 'show_save_and_add_another': not is_popup and (not opts.admin.save_as or context['add']), + 'show_save_and_continue': not is_popup and context['has_change_permission'], 'show_save': True } -submit_row = register.inclusion_tag('admin/submit_line', takes_context=True)(submit_row) +submit_row = register.inclusion_tag('admin/submit_line.html', takes_context=True)(submit_row) def field_label(bound_field): class_names = [] - if isinstance(bound_field.field, meta.BooleanField): + if isinstance(bound_field.field, models.BooleanField): class_names.append("vCheckboxLabel") colon = "" else: @@ -64,16 +64,15 @@ class FieldWidgetNode(template.Node): if not cls.nodelists.has_key(klass): try: field_class_name = klass.__name__ - template_name = "widget/%s" % \ - class_name_to_underscored(field_class_name) - nodelist = template_loader.get_template(template_name).nodelist + template_name = "widget/%s.html" % class_name_to_underscored(field_class_name) + nodelist = loader.get_template(template_name).nodelist except template.TemplateDoesNotExist: super_klass = bool(klass.__bases__) and klass.__bases__[0] or None if super_klass and super_klass != Field: nodelist = cls.get_nodelist(super_klass) else: if not cls.default: - cls.default = template_loader.get_template("widget/default").nodelist + cls.default = loader.get_template("widget/default.html").nodelist nodelist = cls.default cls.nodelists[klass] = nodelist @@ -97,21 +96,22 @@ class FieldWrapper(object): self.field = field def needs_header(self): - return not isinstance(self.field, meta.AutoField) + return not isinstance(self.field, models.AutoField) def header_class_attribute(self): return self.field.blank and ' class="optional"' or '' def use_raw_id_admin(self): - return isinstance(self.field.rel, (meta.ManyToOneRel, meta.ManyToManyRel)) \ + return isinstance(self.field.rel, (models.ManyToOneRel, models.ManyToManyRel)) \ and self.field.rel.raw_id_admin class FormFieldCollectionWrapper(object): - def __init__(self, field_mapping, fields): + def __init__(self, field_mapping, fields, index): self.field_mapping = field_mapping self.fields = fields self.bound_fields = [AdminBoundField(field, self.field_mapping, field_mapping['original']) for field in self.fields] + self.index = index class TabularBoundRelatedObject(BoundRelatedObject): def __init__(self, related_object, field_mapping, original): @@ -120,29 +120,25 @@ class TabularBoundRelatedObject(BoundRelatedObject): fields = self.relation.editable_fields() - self.form_field_collection_wrappers = [FormFieldCollectionWrapper(field_mapping, fields) - for field_mapping in self.field_mappings] + self.form_field_collection_wrappers = [FormFieldCollectionWrapper(field_mapping, fields, i) + for (i,field_mapping) in self.field_mappings.items() ] self.original_row_needed = max([fw.use_raw_id_admin() for fw in self.field_wrapper_list]) self.show_url = original and hasattr(self.relation.opts, 'get_absolute_url') def template_name(self): - return "admin/edit_inline_tabular" + return "admin/edit_inline_tabular.html" class StackedBoundRelatedObject(BoundRelatedObject): def __init__(self, related_object, field_mapping, original): super(StackedBoundRelatedObject, self).__init__(related_object, field_mapping, original) fields = self.relation.editable_fields() - self.form_field_collection_wrappers = [FormFieldCollectionWrapper(field_mapping ,fields) - for field_mapping in self.field_mappings] + self.field_mappings.fill() + self.form_field_collection_wrappers = [FormFieldCollectionWrapper(field_mapping ,fields, i) + for (i,field_mapping) in self.field_mappings.items()] self.show_url = original and hasattr(self.relation.opts, 'get_absolute_url') def template_name(self): - return "admin/edit_inline_stacked" - -bound_related_object_overrides = { - TABULAR: TabularBoundRelatedObject, - STACKED: StackedBoundRelatedObject, -} + return "admin/edit_inline_stacked.html" class EditInlineNode(template.Node): def __init__(self, rel_var): @@ -150,21 +146,16 @@ class EditInlineNode(template.Node): def render(self, context): relation = template.resolve_variable(self.rel_var, context) - context.push() - - klass = relation.field.rel.edit_inline - bound_related_object_class = bound_related_object_overrides.get(klass, klass) - + if relation.field.rel.edit_inline == models.TABULAR: + bound_related_object_class = TabularBoundRelatedObject + else: + bound_related_object_class = StackedBoundRelatedObject original = context.get('original', None) - bound_related_object = relation.bind(context['form'], original, bound_related_object_class) context['bound_related_object'] = bound_related_object - - t = template_loader.get_template(bound_related_object.template_name()) - + t = loader.get_template(bound_related_object.template_name()) output = t.render(context) - context.pop() return output @@ -191,30 +182,30 @@ auto_populated_field_script = register.simple_tag(auto_populated_field_script) def filter_interface_script_maybe(bound_field): f = bound_field.field - if f.rel and isinstance(f.rel, meta.ManyToManyRel) and f.rel.filter_interface: - return '\n' % ( - f.name, f.verbose_name, f.rel.filter_interface-1, ADMIN_MEDIA_PREFIX) + f.name, f.verbose_name, f.rel.filter_interface-1, settings.ADMIN_MEDIA_PREFIX) else: return '' filter_interface_script_maybe = register.simple_tag(filter_interface_script_maybe) -def do_one_arg_tag(node_factory, parser,token): - tokens = token.contents.split() - if len(tokens) != 2: - raise template.TemplateSyntaxError("%s takes 1 argument" % tokens[0]) - return node_factory(tokens[1]) +def field_widget(parser, token): + bits = token.contents.split() + if len(bits) != 2: + raise template.TemplateSyntaxError, "%s takes 1 argument" % bits[0] + return FieldWidgetNode(bits[1]) +field_widget = register.tag(field_widget) -def register_one_arg_tag(node): - tag_name = class_name_to_underscored(node.__name__) - parse_func = curry(do_one_arg_tag, node) - register.tag(tag_name, parse_func) - -register_one_arg_tag(FieldWidgetNode) -register_one_arg_tag(EditInlineNode) +def edit_inline(parser, token): + bits = token.contents.split() + if len(bits) != 2: + raise template.TemplateSyntaxError, "%s takes 1 argument" % bits[0] + return EditInlineNode(bits[1]) +edit_inline = register.tag(edit_inline) def admin_field_line(context, argument_val): - if (isinstance(argument_val, BoundField)): + if isinstance(argument_val, AdminBoundField): bound_fields = [argument_val] else: bound_fields = [bf for bf in argument_val] @@ -229,7 +220,7 @@ def admin_field_line(context, argument_val): break # Assumes BooleanFields won't be stacked next to each other! - if isinstance(bound_fields[0].field, meta.BooleanField): + if isinstance(bound_fields[0].field, models.BooleanField): class_names.append('checkbox-row') return { @@ -238,8 +229,4 @@ def admin_field_line(context, argument_val): 'bound_fields': bound_fields, 'class_names': " ".join(class_names), } -admin_field_line = register.inclusion_tag('admin/field_line', takes_context=True)(admin_field_line) - -def object_pk(bound_manip, ordered_obj): - return bound_manip.get_ordered_object_pk(ordered_obj) -object_pk = register.simple_tag(object_pk) +admin_field_line = register.inclusion_tag('admin/field_line.html', takes_context=True)(admin_field_line) diff --git a/django/contrib/admin/templatetags/adminapplist.py b/django/contrib/admin/templatetags/adminapplist.py index 7a91516ebc..c328ddf203 100644 --- a/django/contrib/admin/templatetags/adminapplist.py +++ b/django/contrib/admin/templatetags/adminapplist.py @@ -1,4 +1,5 @@ -from django.core import template +from django import template +from django.db.models import get_models register = template.Library() @@ -7,20 +8,24 @@ class AdminApplistNode(template.Node): self.varname = varname def render(self, context): - from django.core import meta + from django.db import models from django.utils.text import capfirst app_list = [] user = context['user'] - for app in meta.get_installed_model_modules(): - app_label = app.__name__[app.__name__.rindex('.')+1:] + for app in models.get_apps(): + # Determine the app_label. + app_models = get_models(app) + if not app_models: + continue + app_label = app_models[0]._meta.app_label + has_module_perms = user.has_module_perms(app_label) if has_module_perms: model_list = [] - for m in app._MODELS: + for m in app_models: if m._meta.admin: - module_name = m._meta.module_name perms = { 'add': user.has_perm("%s.%s" % (app_label, m._meta.get_add_permission())), 'change': user.has_perm("%s.%s" % (app_label, m._meta.get_change_permission())), @@ -32,7 +37,7 @@ class AdminApplistNode(template.Node): if True in perms.values(): model_list.append({ 'name': capfirst(m._meta.verbose_name_plural), - 'admin_url': '%s/%s/' % (app_label, m._meta.module_name), + 'admin_url': '%s/%s/' % (app_label, m.__name__.lower()), 'perms': perms, }) diff --git a/django/contrib/admin/templatetags/adminmedia.py b/django/contrib/admin/templatetags/adminmedia.py index cd513f6c81..266c017e3d 100644 --- a/django/contrib/admin/templatetags/adminmedia.py +++ b/django/contrib/admin/templatetags/adminmedia.py @@ -1,10 +1,11 @@ -from django.core.template import Library +from django.template import Library + register = Library() def admin_media_prefix(): try: - from django.conf.settings import ADMIN_MEDIA_PREFIX + from django.conf import settings except ImportError: return '' - return ADMIN_MEDIA_PREFIX + return settings.ADMIN_MEDIA_PREFIX admin_media_prefix = register.simple_tag(admin_media_prefix) diff --git a/django/contrib/admin/templatetags/log.py b/django/contrib/admin/templatetags/log.py index 013e07c80f..5caba2b795 100644 --- a/django/contrib/admin/templatetags/log.py +++ b/django/contrib/admin/templatetags/log.py @@ -1,5 +1,5 @@ -from django.models.admin import log -from django.core import template +from django import template +from django.contrib.admin.models import LogEntry register = template.Library() @@ -13,7 +13,7 @@ class AdminLogNode(template.Node): def render(self, context): if self.user is not None and not self.user.isdigit(): self.user = context[self.user].id - context[self.varname] = log.get_list(user__id__exact=self.user, limit=self.limit, select_related=True) + context[self.varname] = LogEntry.objects.filter(user__id__exact=self.user).select_related()[:self.limit] return '' class DoGetAdminLog: diff --git a/django/contrib/admin/urls.py b/django/contrib/admin/urls.py new file mode 100644 index 0000000000..dde848d766 --- /dev/null +++ b/django/contrib/admin/urls.py @@ -0,0 +1,31 @@ +from django.conf.urls.defaults import * + +urlpatterns = patterns('', + ('^$', 'django.contrib.admin.views.main.index'), + ('^r/(\d+)/(\d+)/$', 'django.views.defaults.shortcut'), + ('^jsi18n/$', 'django.views.i18n.javascript_catalog', {'packages': 'django.conf'}), + ('^logout/$', 'django.contrib.auth.views.logout'), + ('^password_change/$', 'django.contrib.auth.views.password_change'), + ('^password_change/done/$', 'django.contrib.auth.views.password_change_done'), + ('^template_validator/$', 'django.contrib.admin.views.template.template_validator'), + + # Documentation + ('^doc/$', 'django.contrib.admin.views.doc.doc_index'), + ('^doc/bookmarklets/$', 'django.contrib.admin.views.doc.bookmarklets'), + ('^doc/tags/$', 'django.contrib.admin.views.doc.template_tag_index'), + ('^doc/filters/$', 'django.contrib.admin.views.doc.template_filter_index'), + ('^doc/views/$', 'django.contrib.admin.views.doc.view_index'), + ('^doc/views/jump/$', 'django.contrib.admin.views.doc.jump_to_view'), + ('^doc/views/(?P[^/]+)/$', 'django.contrib.admin.views.doc.view_detail'), + ('^doc/models/$', 'django.contrib.admin.views.doc.model_index'), + ('^doc/models/(?P[^\.]+)\.(?P[^/]+)/$', 'django.contrib.admin.views.doc.model_detail'), +# ('^doc/templates/$', 'django.views.admin.doc.template_index'), + ('^doc/templates/(?P
{{ app.name }}
{{ model.name }}{{ model.name }}{{ model.name }}{{ model.name }}