diff --git a/AUTHORS b/AUTHORS index ba1f4036e9..a7f12d6e48 100644 --- a/AUTHORS +++ b/AUTHORS @@ -204,6 +204,7 @@ answer newbie questions, and generally made Django that much better: Clint Ecker Nick Efford Marc Egli + Matt Deacalion Stevens eibaan@gmail.com David Eklund Julia Elman @@ -530,6 +531,7 @@ answer newbie questions, and generally made Django that much better: Leo Shklovskii jason.sidabras@gmail.com Mikołaj Siedlarek + Karol Sikora Brenton Simpson Jozko Skrablin Ben Slavin @@ -542,6 +544,7 @@ answer newbie questions, and generally made Django that much better: George Song sopel Leo Soto + Thomas Sorrel Wiliam Alves de Souza Don Spaulding Calvin Spealman diff --git a/django/conf/global_settings.py b/django/conf/global_settings.py index 7882b21b9b..364aa10320 100644 --- a/django/conf/global_settings.py +++ b/django/conf/global_settings.py @@ -184,6 +184,7 @@ EMAIL_PORT = 25 EMAIL_HOST_USER = '' EMAIL_HOST_PASSWORD = '' EMAIL_USE_TLS = False +EMAIL_USE_SSL = False # List of strings representing installed apps. INSTALLED_APPS = () diff --git a/django/conf/locale/__init__.py b/django/conf/locale/__init__.py index df6ab07663..59927b2397 100644 --- a/django/conf/locale/__init__.py +++ b/django/conf/locale/__init__.py @@ -279,7 +279,7 @@ LANG_INFO = { 'bidi': False, 'code': 'lt', 'name': 'Lithuanian', - 'name_local': 'Lithuanian', + 'name_local': 'Lietuviškai', }, 'lv': { 'bidi': False, @@ -399,7 +399,7 @@ LANG_INFO = { 'bidi': False, 'code': 'sq', 'name': 'Albanian', - 'name_local': 'Albanian', + 'name_local': 'shqip', }, 'sr': { 'bidi': False, @@ -441,7 +441,7 @@ LANG_INFO = { 'bidi': False, 'code': 'th', 'name': 'Thai', - 'name_local': 'Thai', + 'name_local': 'ภาษาไทย', }, 'tr': { 'bidi': False, @@ -477,7 +477,7 @@ LANG_INFO = { 'bidi': False, 'code': 'vi', 'name': 'Vietnamese', - 'name_local': 'Vietnamese', + 'name_local': 'Tiếng Việt', }, 'zh-cn': { 'bidi': False, diff --git a/django/conf/locale/en/LC_MESSAGES/django.po b/django/conf/locale/en/LC_MESSAGES/django.po index 371f0af2ab..f8069f07d2 100644 --- a/django/conf/locale/en/LC_MESSAGES/django.po +++ b/django/conf/locale/en/LC_MESSAGES/django.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: Django\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-05-25 14:27+0200\n" +"POT-Creation-Date: 2013-06-11 18:44+0200\n" "PO-Revision-Date: 2010-05-13 15:35+0200\n" "Last-Translator: Django team\n" "Language-Team: English \n" @@ -699,11 +699,22 @@ msgstr "" msgid "Enter a list of values." msgstr "" -#: forms/forms.py:158 +#. Translators: This is the default suffix added to form field labels +#: forms/forms.py:90 +msgid ":" +msgstr "" + +#: forms/forms.py:159 #, python-format msgid "(Hidden field %(name)s) %(error)s" msgstr "" +#. Translators: If found as last label character, these punctuation +#. characters will prevent the default label_suffix to be appended to the label +#: forms/forms.py:525 +msgid ":?.!" +msgstr "" + #: forms/formsets.py:310 #, python-format msgid "Please submit %d or fewer forms." diff --git a/django/contrib/admin/helpers.py b/django/contrib/admin/helpers.py index 320d3267a7..3ffb85e6c6 100644 --- a/django/contrib/admin/helpers.py +++ b/django/contrib/admin/helpers.py @@ -266,10 +266,12 @@ class InlineAdminForm(AdminForm): yield InlineFieldset(self.formset, self.form, name, self.readonly_fields, model_admin=self.model_admin, **options) - def has_auto_field(self): - if self.form._meta.model._meta.has_auto_field: + def needs_explicit_pk_field(self): + # Auto fields are editable (oddly), so need to check for auto or non-editable pk + if self.form._meta.model._meta.has_auto_field or not self.form._meta.model._meta.pk.editable: return True - # Also search any parents for an auto field. + # Also search any parents for an auto field. (The pk info is propagated to child + # models so that does not need to be checked in parents.) for parent in self.form._meta.model._meta.get_parent_list(): if parent._meta.has_auto_field: return True diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index 9c92f7ae9c..afc7cfc5bd 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -771,12 +771,10 @@ class ModelAdmin(BaseModelAdmin): Returns the preserved filters querystring. """ - # FIXME: We can remove that getattr as soon as #20619 is fixed. - match = getattr(request, 'resolver_match', None) - + match = request.resolver_match if self.preserve_filters and match: opts = self.model._meta - current_url = '%s:%s' % (match.namespace, match.url_name) + current_url = '%s:%s' % (match.app_name, match.url_name) changelist_url = 'admin:%s_%s_changelist' % (opts.app_label, opts.model_name) if current_url == changelist_url: preserved_filters = request.GET.urlencode() diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py index e0f43dfbfe..8abf49331b 100644 --- a/django/contrib/admin/sites.py +++ b/django/contrib/admin/sites.py @@ -439,6 +439,7 @@ class AdminSite(object): context = { 'title': _('%s administration') % capfirst(app_label), 'app_list': [app_dict], + 'app_label': app_label, } context.update(extra_context or {}) diff --git a/django/contrib/admin/static/admin/js/admin/DateTimeShortcuts.js b/django/contrib/admin/static/admin/js/admin/DateTimeShortcuts.js index 671af9bd78..aa12f8cf01 100644 --- a/django/contrib/admin/static/admin/js/admin/DateTimeShortcuts.js +++ b/django/contrib/admin/static/admin/js/admin/DateTimeShortcuts.js @@ -14,6 +14,8 @@ var DateTimeShortcuts = { clockDivName: 'clockbox', // name of clock
that gets toggled clockLinkName: 'clocklink', // name of the link that is used to toggle shortCutsClass: 'datetimeshortcuts', // class of the clock and cal shortcuts + timezoneWarningClass: 'timezonewarning', // class of the warning for timezone mismatch + timezoneOffset: 0, admin_media_prefix: '', init: function() { // Get admin_media_prefix by grabbing it off the window object. It's @@ -26,17 +28,77 @@ var DateTimeShortcuts = { DateTimeShortcuts.admin_media_prefix = '/missing-admin-media-prefix/'; } + if (window.__admin_utc_offset__ != undefined) { + var serverOffset = window.__admin_utc_offset__; + var localOffset = new Date().getTimezoneOffset() * -60; + DateTimeShortcuts.timezoneOffset = localOffset - serverOffset; + } + var inputs = document.getElementsByTagName('input'); for (i=0; i 0) { + message = ngettext( + 'Note: You are %s hour ahead of server time.', + 'Note: You are %s hours ahead of server time.', + timezoneOffset + ); + } + else { + timezoneOffset *= -1 + message = ngettext( + 'Note: You are %s hour behind server time.', + 'Note: You are %s hours behind server time.', + timezoneOffset + ); + } + message = interpolate(message, [timezoneOffset]); + + var $warning = $(''); + $warning.attr('class', warningClass); + $warning.text(message); + + $(inp).parent() + .append($('
')) + .append($warning) + }, // Add clock widget to a given field addClock: function(inp) { var num = DateTimeShortcuts.clockInputs.length; @@ -48,7 +110,7 @@ var DateTimeShortcuts = { shortcuts_span.className = DateTimeShortcuts.shortCutsClass; inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling); var now_link = document.createElement('a'); - now_link.setAttribute('href', "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date().strftime('" + get_format('TIME_INPUT_FORMATS')[0] + "'));"); + now_link.setAttribute('href', "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", -1);"); now_link.appendChild(document.createTextNode(gettext('Now'))); var clock_link = document.createElement('a'); clock_link.setAttribute('href', 'javascript:DateTimeShortcuts.openClock(' + num + ');'); @@ -84,11 +146,10 @@ var DateTimeShortcuts = { quickElement('h2', clock_box, gettext('Choose a time')); var time_list = quickElement('ul', clock_box, ''); time_list.className = 'timelist'; - var time_format = get_format('TIME_INPUT_FORMATS')[0]; - quickElement("a", quickElement("li", time_list, ""), gettext("Now"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date().strftime('" + time_format + "'));"); - quickElement("a", quickElement("li", time_list, ""), gettext("Midnight"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date(1970,1,1,0,0,0,0).strftime('" + time_format + "'));"); - quickElement("a", quickElement("li", time_list, ""), gettext("6 a.m."), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date(1970,1,1,6,0,0,0).strftime('" + time_format + "'));"); - quickElement("a", quickElement("li", time_list, ""), gettext("Noon"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", new Date(1970,1,1,12,0,0,0).strftime('" + time_format + "'));"); + quickElement("a", quickElement("li", time_list, ""), gettext("Now"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", -1);"); + quickElement("a", quickElement("li", time_list, ""), gettext("Midnight"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", 0);"); + quickElement("a", quickElement("li", time_list, ""), gettext("6 a.m."), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", 6);"); + quickElement("a", quickElement("li", time_list, ""), gettext("Noon"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", 12);"); var cancel_p = quickElement('p', clock_box, ''); cancel_p.className = 'calendar-cancel'; @@ -128,7 +189,14 @@ var DateTimeShortcuts = { removeEvent(document, 'click', DateTimeShortcuts.dismissClockFunc[num]); }, handleClockQuicklink: function(num, val) { - DateTimeShortcuts.clockInputs[num].value = val; + var d; + if (val == -1) { + d = DateTimeShortcuts.now(); + } + else { + d = new Date(1970, 1, 1, val, 0, 0, 0) + } + DateTimeShortcuts.clockInputs[num].value = d.strftime(get_format('TIME_INPUT_FORMATS')[0]); DateTimeShortcuts.clockInputs[num].focus(); DateTimeShortcuts.dismissClock(num); }, @@ -258,7 +326,7 @@ var DateTimeShortcuts = { DateTimeShortcuts.calendars[num].drawNextMonth(); }, handleCalendarCallback: function(num) { - format = get_format('DATE_INPUT_FORMATS')[0]; + var format = get_format('DATE_INPUT_FORMATS')[0]; // the format needs to be escaped a little format = format.replace('\\', '\\\\'); format = format.replace('\r', '\\r'); @@ -276,7 +344,7 @@ var DateTimeShortcuts = { ").style.display='none';}"].join(''); }, handleCalendarQuickLink: function(num, offset) { - var d = new Date(); + var d = DateTimeShortcuts.now(); d.setDate(d.getDate() + offset) DateTimeShortcuts.calendarInputs[num].value = d.strftime(get_format('DATE_INPUT_FORMATS')[0]); DateTimeShortcuts.calendarInputs[num].focus(); diff --git a/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js b/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js index 6d1748663e..c82c8c05cb 100644 --- a/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js +++ b/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js @@ -55,7 +55,7 @@ function dismissRelatedLookupPopup(win, chosenId) { function showAddAnotherPopup(triggeringLink) { var name = triggeringLink.id.replace(/^add_/, ''); name = id_to_windowname(name); - href = triggeringLink.href + var href = triggeringLink.href; if (href.indexOf('?') == -1) { href += '?_popup=1'; } else { @@ -73,10 +73,11 @@ function dismissAddAnotherPopup(win, newId, newRepr) { newRepr = html_unescape(newRepr); var name = windowname_to_id(win.name); var elem = document.getElementById(name); + var o; if (elem) { var elemName = elem.nodeName.toUpperCase(); if (elemName == 'SELECT') { - var o = new Option(newRepr, newId); + o = new Option(newRepr, newId); elem.options[elem.options.length] = o; o.selected = true; } else if (elemName == 'INPUT') { @@ -88,8 +89,7 @@ function dismissAddAnotherPopup(win, newId, newRepr) { } } else { var toId = name + "_to"; - elem = document.getElementById(toId); - var o = new Option(newRepr, newId); + o = new Option(newRepr, newId); SelectBox.add_to_cache(toId, o); SelectBox.redisplay(toId); } diff --git a/django/contrib/admin/templates/admin/app_index.html b/django/contrib/admin/templates/admin/app_index.html index 9f65357292..7aff935126 100644 --- a/django/contrib/admin/templates/admin/app_index.html +++ b/django/contrib/admin/templates/admin/app_index.html @@ -1,6 +1,8 @@ {% extends "admin/index.html" %} {% load i18n %} +{% block bodyclass %}app-{{ app_label }} {{ block.super }}{% endblock %} + {% if not is_popup %} {% block breadcrumbs %}