Merge branch 'master' into schema-alteration

This commit is contained in:
Andrew Godwin 2013-05-10 12:55:30 +01:00
commit cb4b0de49e
181 changed files with 1973 additions and 1623 deletions

View File

@ -2,77 +2,77 @@
host = https://www.transifex.com
lang_map = sr@latin:sr_Latn
[django.core]
[django-core.core]
file_filter = django/conf/locale/<lang>/LC_MESSAGES/django.po
source_file = django/conf/locale/en/LC_MESSAGES/django.po
source_lang = en
[django.contrib-admin]
[django-core.contrib-admin]
file_filter = django/contrib/admin/locale/<lang>/LC_MESSAGES/django.po
source_file = django/contrib/admin/locale/en/LC_MESSAGES/django.po
source_lang = en
[django.contrib-admin-js]
[django-core.contrib-admin-js]
file_filter = django/contrib/admin/locale/<lang>/LC_MESSAGES/djangojs.po
source_file = django/contrib/admin/locale/en/LC_MESSAGES/djangojs.po
source_lang = en
[django.contrib-admindocs]
[django-core.contrib-admindocs]
file_filter = django/contrib/admindocs/locale/<lang>/LC_MESSAGES/django.po
source_file = django/contrib/admindocs/locale/en/LC_MESSAGES/django.po
source_lang = en
[django.contrib-auth]
[django-core.contrib-auth]
file_filter = django/contrib/auth/locale/<lang>/LC_MESSAGES/django.po
source_file = django/contrib/auth/locale/en/LC_MESSAGES/django.po
source_lang = en
[django.contrib-comments]
[django-core.contrib-comments]
file_filter = django/contrib/comments/locale/<lang>/LC_MESSAGES/django.po
source_file = django/contrib/comments/locale/en/LC_MESSAGES/django.po
source_lang = en
[django.contrib-contenttypes]
[django-core.contrib-contenttypes]
file_filter = django/contrib/contenttypes/locale/<lang>/LC_MESSAGES/django.po
source_file = django/contrib/contenttypes/locale/en/LC_MESSAGES/django.po
source_lang = en
[django.contrib-flatpages]
[django-core.contrib-flatpages]
file_filter = django/contrib/flatpages/locale/<lang>/LC_MESSAGES/django.po
source_file = django/contrib/flatpages/locale/en/LC_MESSAGES/django.po
source_lang = en
[django.contrib-formtools]
[django-core.contrib-formtools]
file_filter = django/contrib/formtools/locale/<lang>/LC_MESSAGES/django.po
source_file = django/contrib/formtools/locale/en/LC_MESSAGES/django.po
source_lang = en
[django.contrib-gis]
[django-core.contrib-gis]
file_filter = django/contrib/gis/locale/<lang>/LC_MESSAGES/django.po
source_file = django/contrib/gis/locale/en/LC_MESSAGES/django.po
source_lang = en
[django.contrib-humanize]
[django-core.contrib-humanize]
file_filter = django/contrib/humanize/locale/<lang>/LC_MESSAGES/django.po
source_file = django/contrib/humanize/locale/en/LC_MESSAGES/django.po
source_lang = en
[django.contrib-messages]
[django-core.contrib-messages]
file_filter = django/contrib/messages/locale/<lang>/LC_MESSAGES/django.po
source_file = django/contrib/messages/locale/en/LC_MESSAGES/django.po
source_lang = en
[django.contrib-redirects]
[django-core.contrib-redirects]
file_filter = django/contrib/redirects/locale/<lang>/LC_MESSAGES/django.po
source_file = django/contrib/redirects/locale/en/LC_MESSAGES/django.po
source_lang = en
[django.contrib-sessions]
[django-core.contrib-sessions]
file_filter = django/contrib/sessions/locale/<lang>/LC_MESSAGES/django.po
source_file = django/contrib/sessions/locale/en/LC_MESSAGES/django.po
source_lang = en
[django.contrib-sites]
[django-core.contrib-sites]
file_filter = django/contrib/sites/locale/<lang>/LC_MESSAGES/django.po
source_file = django/contrib/sites/locale/en/LC_MESSAGES/django.po
source_lang = en

View File

@ -10,7 +10,9 @@ recursive-include docs *
recursive-include scripts *
recursive-include extras *
recursive-include tests *
recursive-include django/conf/app_template *
recursive-include django/conf/locale *
recursive-include django/conf/project_template *
recursive-include django/contrib/*/locale *
recursive-include django/contrib/admin/templates *
recursive-include django/contrib/admin/static *

View File

View File

@ -4,7 +4,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-03-28 10:04+0100\n"
"POT-Creation-Date: 2013-05-02 16:17+0200\n"
"PO-Revision-Date: 2010-05-13 15:35+0200\n"
"Last-Translator: Django team\n"
"Language-Team: English <en@li.org>\n"
@ -337,7 +337,7 @@ msgstr ""
msgid "Enter a valid value."
msgstr ""
#: core/validators.py:53 forms/fields.py:627
#: core/validators.py:53 forms/fields.py:640
msgid "Enter a valid URL."
msgstr ""
@ -408,7 +408,7 @@ msgstr[1] ""
msgid "%(field_name)s must be unique for %(date_field)s %(lookup)s."
msgstr ""
#: db/models/base.py:905 forms/models.py:590
#: db/models/base.py:905 forms/models.py:605
msgid "and"
msgstr ""
@ -630,46 +630,54 @@ msgstr ""
msgid "Enter a number."
msgstr ""
#: forms/fields.py:295
#, python-format
msgid "Ensure that there are no more than %s digits in total."
msgstr ""
#: forms/fields.py:296
#, python-format
msgid "Ensure that there are no more than %s decimal places."
msgstr ""
msgid "Ensure that there are no more than %(max)s digit in total."
msgid_plural "Ensure that there are no more than %(max)s digits in total."
msgstr[0] ""
msgstr[1] ""
#: forms/fields.py:297
#: forms/fields.py:300
#, python-format
msgid "Ensure that there are no more than %s digits before the decimal point."
msgstr ""
msgid "Ensure that there are no more than %(max)s decimal place."
msgid_plural "Ensure that there are no more than %(max)s decimal places."
msgstr[0] ""
msgstr[1] ""
#: forms/fields.py:393 forms/fields.py:1045
#: forms/fields.py:304
#, python-format
msgid ""
"Ensure that there are no more than %(max)s digit before the decimal point."
msgid_plural ""
"Ensure that there are no more than %(max)s digits before the decimal point."
msgstr[0] ""
msgstr[1] ""
#: forms/fields.py:406 forms/fields.py:1058
msgid "Enter a valid date."
msgstr ""
#: forms/fields.py:417 forms/fields.py:1046
#: forms/fields.py:430 forms/fields.py:1059
msgid "Enter a valid time."
msgstr ""
#: forms/fields.py:438
#: forms/fields.py:451
msgid "Enter a valid date/time."
msgstr ""
#: forms/fields.py:512
#: forms/fields.py:525
msgid "No file was submitted. Check the encoding type on the form."
msgstr ""
#: forms/fields.py:513
#: forms/fields.py:526
msgid "No file was submitted."
msgstr ""
#: forms/fields.py:514
#: forms/fields.py:527
msgid "The submitted file is empty."
msgstr ""
#: forms/fields.py:516
#: forms/fields.py:529
#, python-format
msgid "Ensure this filename has at most %(max)d character (it has %(length)d)."
msgid_plural ""
@ -677,22 +685,22 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
#: forms/fields.py:519
#: forms/fields.py:532
msgid "Please either submit a file or check the clear checkbox, not both."
msgstr ""
#: forms/fields.py:580
#: forms/fields.py:593
msgid ""
"Upload a valid image. The file you uploaded was either not an image or a "
"corrupted image."
msgstr ""
#: forms/fields.py:733 forms/fields.py:811
#: forms/fields.py:746 forms/fields.py:824 forms/models.py:1042
#, python-format
msgid "Select a valid choice. %(value)s is not one of the available choices."
msgstr ""
#: forms/fields.py:812 forms/fields.py:915 forms/models.py:1026
#: forms/fields.py:825 forms/fields.py:928 forms/models.py:1041
msgid "Enter a list of values."
msgstr ""
@ -714,43 +722,38 @@ msgstr ""
msgid "Delete"
msgstr ""
#: forms/models.py:584
#: forms/models.py:599
#, python-format
msgid "Please correct the duplicate data for %(field)s."
msgstr ""
#: forms/models.py:588
#: forms/models.py:603
#, python-format
msgid "Please correct the duplicate data for %(field)s, which must be unique."
msgstr ""
#: forms/models.py:594
#: forms/models.py:609
#, python-format
msgid ""
"Please correct the duplicate data for %(field_name)s which must be unique "
"for the %(lookup)s in %(date_field)s."
msgstr ""
#: forms/models.py:602
#: forms/models.py:617
msgid "Please correct the duplicate values below."
msgstr ""
#: forms/models.py:868
#: forms/models.py:883
msgid "The inline foreign key did not match the parent instance primary key."
msgstr ""
#: forms/models.py:932
#: forms/models.py:947
msgid "Select a valid choice. That choice is not one of the available choices."
msgstr ""
#: forms/models.py:1027
#: forms/models.py:1044
#, python-format
msgid "Select a valid choice. %s is not one of the available choices."
msgstr ""
#: forms/models.py:1029
#, python-format
msgid "\"%s\" is not a valid value for a primary key."
msgid "\"%(pk)s\" is not a valid value for a primary key."
msgstr ""
#: forms/util.py:84
@ -760,27 +763,27 @@ msgid ""
"may be ambiguous or it may not exist."
msgstr ""
#: forms/widgets.py:326
#: forms/widgets.py:327
msgid "Currently"
msgstr ""
#: forms/widgets.py:327
#: forms/widgets.py:328
msgid "Change"
msgstr ""
#: forms/widgets.py:328
#: forms/widgets.py:329
msgid "Clear"
msgstr ""
#: forms/widgets.py:546
#: forms/widgets.py:547
msgid "Unknown"
msgstr ""
#: forms/widgets.py:547
#: forms/widgets.py:548
msgid "Yes"
msgstr ""
#: forms/widgets.py:548
#: forms/widgets.py:549
msgid "No"
msgstr ""

File diff suppressed because it is too large Load Diff

View File

@ -1,25 +1,22 @@
# This file is distributed under the same license as the Django package.
#
# Translators:
# Jannis Leidel <jannis@leidel.info>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-03-28 10:04+0100\n"
"PO-Revision-Date: 2012-03-08 10:42+0000\n"
"Last-Translator: Jannis Leidel <jannis@leidel.info>\n"
"POT-Creation-Date: 2013-05-02 16:18+0200\n"
"PO-Revision-Date: 2010-05-13 15:35+0200\n"
"Last-Translator: Django team\n"
"Language-Team: English <en@li.org>\n"
"Language: en\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: static/admin/js/SelectFilter2.js:45
#, c-format
msgid "Available %s"
msgstr "Available %s"
msgstr ""
#: static/admin/js/SelectFilter2.js:46
#, c-format
@ -27,39 +24,37 @@ msgid ""
"This is the list of available %s. You may choose some by selecting them in "
"the box below and then clicking the \"Choose\" arrow between the two boxes."
msgstr ""
"This is the list of available %s. You may choose some by selecting them in "
"the box below and then clicking the \"Choose\" arrow between the two boxes."
#: static/admin/js/SelectFilter2.js:53
#, c-format
msgid "Type into this box to filter down the list of available %s."
msgstr "Type into this box to filter down the list of available %s."
msgstr ""
#: static/admin/js/SelectFilter2.js:57
msgid "Filter"
msgstr "Filter"
msgstr ""
#: static/admin/js/SelectFilter2.js:61
msgid "Choose all"
msgstr "Choose all"
msgstr ""
#: static/admin/js/SelectFilter2.js:61
#, c-format
msgid "Click to choose all %s at once."
msgstr "Click to choose all %s at once."
msgstr ""
#: static/admin/js/SelectFilter2.js:67
msgid "Choose"
msgstr "Choose"
msgstr ""
#: static/admin/js/SelectFilter2.js:69
msgid "Remove"
msgstr "Remove"
msgstr ""
#: static/admin/js/SelectFilter2.js:75
#, c-format
msgid "Chosen %s"
msgstr "Chosen %s"
msgstr ""
#: static/admin/js/SelectFilter2.js:76
#, c-format
@ -67,31 +62,27 @@ msgid ""
"This is the list of chosen %s. You may remove some by selecting them in the "
"box below and then clicking the \"Remove\" arrow between the two boxes."
msgstr ""
"This is the list of chosen %s. You may remove some by selecting them in the "
"box below and then clicking the \"Remove\" arrow between the two boxes."
#: static/admin/js/SelectFilter2.js:80
msgid "Remove all"
msgstr "Remove all"
msgstr ""
#: static/admin/js/SelectFilter2.js:80
#, c-format
msgid "Click to remove all chosen %s at once."
msgstr "Click to remove all chosen %s at once."
msgstr ""
#: static/admin/js/actions.js:18 static/admin/js/actions.min.js:1
msgid "%(sel)s of %(cnt)s selected"
msgid_plural "%(sel)s of %(cnt)s selected"
msgstr[0] "%(sel)s of %(cnt)s selected"
msgstr[1] "%(sel)s of %(cnt)s selected"
msgstr[0] ""
msgstr[1] ""
#: static/admin/js/actions.js:109 static/admin/js/actions.min.js:5
msgid ""
"You have unsaved changes on individual editable fields. If you run an "
"action, your unsaved changes will be lost."
msgstr ""
"You have unsaved changes on individual editable fields. If you run an "
"action, your unsaved changes will be lost."
#: static/admin/js/actions.js:121 static/admin/js/actions.min.js:5
msgid ""
@ -99,9 +90,6 @@ msgid ""
"individual fields yet. Please click OK to save. You'll need to re-run the "
"action."
msgstr ""
"You have selected an action, but you haven't saved your changes to "
"individual fields yet. Please click OK to save. You'll need to re-run the "
"action."
#: static/admin/js/actions.js:123 static/admin/js/actions.min.js:6
msgid ""
@ -109,74 +97,69 @@ msgid ""
"fields. You're probably looking for the Go button rather than the Save "
"button."
msgstr ""
"You have selected an action, and you haven't made any changes on individual "
"fields. You're probably looking for the Go button rather than the Save "
"button."
#: static/admin/js/calendar.js:8
msgid ""
"January February March April May June July August September October November "
"December"
msgstr ""
"January February March April May June July August September October November "
"December"
#: static/admin/js/calendar.js:9
msgid "S M T W T F S"
msgstr "S M T W T F S"
msgstr ""
#: static/admin/js/collapse.js:8 static/admin/js/collapse.js.c:19
#: static/admin/js/collapse.min.js:1
msgid "Show"
msgstr "Show"
msgstr ""
#: static/admin/js/collapse.js:16 static/admin/js/collapse.min.js:1
msgid "Hide"
msgstr "Hide"
#: static/admin/js/admin/DateTimeShortcuts.js:49
#: static/admin/js/admin/DateTimeShortcuts.js:85
msgid "Now"
msgstr "Now"
#: static/admin/js/admin/DateTimeShortcuts.js:53
msgid "Clock"
msgstr "Clock"
#: static/admin/js/admin/DateTimeShortcuts.js:81
msgid "Choose a time"
msgstr "Choose a time"
#: static/admin/js/admin/DateTimeShortcuts.js:86
msgid "Midnight"
msgstr "Midnight"
#: static/admin/js/admin/DateTimeShortcuts.js:87
msgid "6 a.m."
msgstr "6 a.m."
msgstr ""
#: static/admin/js/admin/DateTimeShortcuts.js:52
#: static/admin/js/admin/DateTimeShortcuts.js:88
msgid "Now"
msgstr ""
#: static/admin/js/admin/DateTimeShortcuts.js:56
msgid "Clock"
msgstr ""
#: static/admin/js/admin/DateTimeShortcuts.js:84
msgid "Choose a time"
msgstr ""
#: static/admin/js/admin/DateTimeShortcuts.js:89
msgid "Midnight"
msgstr ""
#: static/admin/js/admin/DateTimeShortcuts.js:90
msgid "6 a.m."
msgstr ""
#: static/admin/js/admin/DateTimeShortcuts.js:91
msgid "Noon"
msgstr "Noon"
msgstr ""
#: static/admin/js/admin/DateTimeShortcuts.js:92
#: static/admin/js/admin/DateTimeShortcuts.js:204
#: static/admin/js/admin/DateTimeShortcuts.js:95
#: static/admin/js/admin/DateTimeShortcuts.js:208
msgid "Cancel"
msgstr "Cancel"
#: static/admin/js/admin/DateTimeShortcuts.js:144
#: static/admin/js/admin/DateTimeShortcuts.js:197
msgid "Today"
msgstr "Today"
msgstr ""
#: static/admin/js/admin/DateTimeShortcuts.js:148
msgid "Calendar"
msgstr "Calendar"
#: static/admin/js/admin/DateTimeShortcuts.js:201
msgid "Today"
msgstr ""
#: static/admin/js/admin/DateTimeShortcuts.js:195
msgid "Yesterday"
msgstr "Yesterday"
#: static/admin/js/admin/DateTimeShortcuts.js:152
msgid "Calendar"
msgstr ""
#: static/admin/js/admin/DateTimeShortcuts.js:199
msgid "Yesterday"
msgstr ""
#: static/admin/js/admin/DateTimeShortcuts.js:203
msgid "Tomorrow"
msgstr "Tomorrow"
msgstr ""

View File

@ -5,7 +5,7 @@ from django import forms
from django.conf import settings
from django.forms.formsets import all_valid, DELETION_FIELD_NAME
from django.forms.models import (modelform_factory, modelformset_factory,
inlineformset_factory, BaseInlineFormSet)
inlineformset_factory, BaseInlineFormSet, modelform_defines_fields)
from django.contrib.contenttypes.models import ContentType
from django.contrib.admin import widgets, helpers
from django.contrib.admin.util import (unquote, flatten_fieldsets, get_deleted_objects,
@ -13,7 +13,7 @@ from django.contrib.admin.util import (unquote, flatten_fieldsets, get_deleted_o
from django.contrib.admin.templatetags.admin_static import static
from django.contrib import messages
from django.views.decorators.csrf import csrf_protect
from django.core.exceptions import PermissionDenied, ValidationError
from django.core.exceptions import PermissionDenied, ValidationError, FieldError
from django.core.paginator import Paginator
from django.core.urlresolvers import reverse
from django.db import models, transaction, router
@ -488,7 +488,15 @@ class ModelAdmin(BaseModelAdmin):
"formfield_callback": partial(self.formfield_for_dbfield, request=request),
}
defaults.update(kwargs)
return modelform_factory(self.model, **defaults)
if defaults['fields'] is None and not modelform_defines_fields(defaults['form']):
defaults['fields'] = forms.ALL_FIELDS
try:
return modelform_factory(self.model, **defaults)
except FieldError as e:
raise FieldError('%s. Check fields/fieldsets/exclude attributes of class %s.'
% (e, self.__class__.__name__))
def get_changelist(self, request, **kwargs):
"""
@ -519,6 +527,10 @@ class ModelAdmin(BaseModelAdmin):
"formfield_callback": partial(self.formfield_for_dbfield, request=request),
}
defaults.update(kwargs)
if (defaults.get('fields') is None
and not modelform_defines_fields(defaults.get('form'))):
defaults['fields'] = forms.ALL_FIELDS
return modelform_factory(self.model, **defaults)
def get_changelist_formset(self, request, **kwargs):
@ -1523,6 +1535,10 @@ class InlineModelAdmin(BaseModelAdmin):
return result
defaults['form'] = DeleteProtectedModelForm
if defaults['fields'] is None and not modelform_defines_fields(defaults['form']):
defaults['fields'] = forms.ALL_FIELDS
return inlineformset_factory(self.parent_model, self.model, **defaults)
def get_fieldsets(self, request, obj=None):

View File

@ -246,7 +246,6 @@ def validate_fields_spec(cls, model, opts, flds, label):
# readonly_fields will handle the validation of such
# things.
continue
check_formfield(cls, model, opts, label, field)
try:
f = opts.get_field(field)
except models.FieldDoesNotExist:
@ -302,14 +301,6 @@ def validate_base(cls, model):
# exclude
if cls.exclude: # default value is None
check_isseq(cls, 'exclude', cls.exclude)
for field in cls.exclude:
check_formfield(cls, model, opts, 'exclude', field)
try:
f = opts.get_field(field)
except models.FieldDoesNotExist:
# If we can't find a field on the model that matches,
# it could be an extra field on the form.
continue
if len(cls.exclude) > len(set(cls.exclude)):
raise ImproperlyConfigured('There are duplicate field(s) in %s.exclude' % cls.__name__)
@ -380,23 +371,6 @@ def get_field(cls, model, opts, label, field):
raise ImproperlyConfigured("'%s.%s' refers to field '%s' that is missing from model '%s.%s'."
% (cls.__name__, label, field, model._meta.app_label, model.__name__))
def check_formfield(cls, model, opts, label, field):
if getattr(cls.form, 'base_fields', None):
try:
cls.form.base_fields[field]
except KeyError:
raise ImproperlyConfigured("'%s.%s' refers to field '%s' that "
"is missing from the form." % (cls.__name__, label, field))
else:
get_form_is_overridden = hasattr(cls, 'get_form') and cls.get_form != ModelAdmin.get_form
if not get_form_is_overridden:
fields = fields_for_model(model)
try:
fields[field]
except KeyError:
raise ImproperlyConfigured("'%s.%s' refers to field '%s' that "
"is missing from the form." % (cls.__name__, label, field))
def fetch_attr(cls, model, opts, label, field):
try:
return opts.get_field(field)

View File

@ -1,77 +1,74 @@
# This file is distributed under the same license as the Django package.
#
# Translators:
# Jannis Leidel <jannis@leidel.info>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-03-28 10:04+0100\n"
"PO-Revision-Date: 2012-10-22 08:46+0000\n"
"Last-Translator: Jannis Leidel <jannis@leidel.info>\n"
"POT-Creation-Date: 2013-05-02 16:18+0200\n"
"PO-Revision-Date: 2010-05-13 15:35+0200\n"
"Last-Translator: Django team\n"
"Language-Team: English <en@li.org>\n"
"Language: en\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: views.py:59 views.py:61 views.py:63
msgid "tag:"
msgstr "tag:"
msgstr ""
#: views.py:94 views.py:96 views.py:98
msgid "filter:"
msgstr "filter:"
msgstr ""
#: views.py:157 views.py:159 views.py:161
msgid "view:"
msgstr "view:"
msgstr ""
#: views.py:189
#, python-format
msgid "App %r not found"
msgstr "App %r not found"
msgstr ""
#: views.py:196
#, python-format
msgid "Model %(model_name)r not found in app %(app_label)r"
msgstr "Model %(model_name)r not found in app %(app_label)r"
msgstr ""
#: views.py:208
#, python-format
msgid "the related `%(app_label)s.%(data_type)s` object"
msgstr "the related `%(app_label)s.%(data_type)s` object"
msgstr ""
#: views.py:208 views.py:227 views.py:232 views.py:246 views.py:260
#: views.py:265
msgid "model:"
msgstr "model:"
msgstr ""
#: views.py:223 views.py:255
#, python-format
msgid "related `%(app_label)s.%(object_name)s` objects"
msgstr "related `%(app_label)s.%(object_name)s` objects"
msgstr ""
#: views.py:227 views.py:260
#, python-format
msgid "all %s"
msgstr "all %s"
msgstr ""
#: views.py:232 views.py:265
#, python-format
msgid "number of %s"
msgstr "number of %s"
msgstr ""
#: views.py:270
#, python-format
msgid "Fields on %s objects"
msgstr "Fields on %s objects"
msgstr ""
#: views.py:362
#, python-format
msgid "%s does not appear to be a urlpattern object"
msgstr "%s does not appear to be a urlpattern object"
msgstr ""
#: templates/admin_doc/bookmarklets.html:6 templates/admin_doc/index.html:6
#: templates/admin_doc/missing_docutils.html:6
@ -83,7 +80,7 @@ msgstr "%s does not appear to be a urlpattern object"
#: templates/admin_doc/view_detail.html:6
#: templates/admin_doc/view_index.html:7
msgid "Home"
msgstr "Home"
msgstr ""
#: templates/admin_doc/bookmarklets.html:7 templates/admin_doc/index.html:7
#: templates/admin_doc/missing_docutils.html:7
@ -95,15 +92,15 @@ msgstr "Home"
#: templates/admin_doc/view_detail.html:7
#: templates/admin_doc/view_index.html:8
msgid "Documentation"
msgstr "Documentation"
msgstr ""
#: templates/admin_doc/bookmarklets.html:8
msgid "Bookmarklets"
msgstr "Bookmarklets"
msgstr ""
#: templates/admin_doc/bookmarklets.html:11
msgid "Documentation bookmarklets"
msgstr "Documentation bookmarklets"
msgstr ""
#: templates/admin_doc/bookmarklets.html:15
msgid ""
@ -115,81 +112,70 @@ msgid ""
"as \"internal\" (talk to your system administrator if you aren't sure if\n"
"your computer is \"internal\").</p>\n"
msgstr ""
"\n"
"<p class=\"help\">To install bookmarklets, drag the link to your bookmarks\n"
"toolbar, or right-click the link and add it to your bookmarks. Now you can\n"
"select the bookmarklet from any page in the site. Note that some of these\n"
"bookmarklets require you to be viewing the site from a computer designated\n"
"as \"internal\" (talk to your system administrator if you aren't sure if\n"
"your computer is \"internal\").</p>\n"
#: templates/admin_doc/bookmarklets.html:25
msgid "Documentation for this page"
msgstr "Documentation for this page"
msgstr ""
#: templates/admin_doc/bookmarklets.html:26
msgid ""
"Jumps you from any page to the documentation for the view that generates "
"that page."
msgstr ""
"Jumps you from any page to the documentation for the view that generates "
"that page."
#: templates/admin_doc/bookmarklets.html:28
msgid "Show object ID"
msgstr "Show object ID"
msgstr ""
#: templates/admin_doc/bookmarklets.html:29
msgid ""
"Shows the content-type and unique ID for pages that represent a single "
"object."
msgstr ""
"Shows the content-type and unique ID for pages that represent a single "
"object."
#: templates/admin_doc/bookmarklets.html:31
msgid "Edit this object (current window)"
msgstr "Edit this object (current window)"
msgstr ""
#: templates/admin_doc/bookmarklets.html:32
msgid "Jumps to the admin page for pages that represent a single object."
msgstr "Jumps to the admin page for pages that represent a single object."
msgstr ""
#: templates/admin_doc/bookmarklets.html:34
msgid "Edit this object (new window)"
msgstr "Edit this object (new window)"
msgstr ""
#: templates/admin_doc/bookmarklets.html:35
msgid "As above, but opens the admin page in a new window."
msgstr "As above, but opens the admin page in a new window."
msgstr ""
#: templates/admin_doc/model_detail.html:16
#: templates/admin_doc/model_index.html:10
msgid "Models"
msgstr "Models"
msgstr ""
#: templates/admin_doc/template_detail.html:8
msgid "Templates"
msgstr "Templates"
msgstr ""
#: templates/admin_doc/template_filter_index.html:9
msgid "Filters"
msgstr "Filters"
msgstr ""
#: templates/admin_doc/template_tag_index.html:9
msgid "Tags"
msgstr "Tags"
msgstr ""
#: templates/admin_doc/view_detail.html:8
#: templates/admin_doc/view_index.html:9
msgid "Views"
msgstr "Views"
msgstr ""
#: tests/__init__.py:23
#: tests/test_fields.py:29
msgid "Boolean (Either True or False)"
msgstr "Boolean (Either True or False)"
msgstr ""
#: tests/__init__.py:33
#: tests/test_fields.py:39
#, python-format
msgid "Field of type: %(field_type)s"
msgstr "Field of type: %(field_type)s"
msgstr ""

View File

@ -130,6 +130,7 @@ class UserChangeForm(forms.ModelForm):
class Meta:
model = User
fields = '__all__'
def __init__(self, *args, **kwargs):
super(UserChangeForm, self).__init__(*args, **kwargs)

View File

@ -1,81 +1,79 @@
# This file is distributed under the same license as the Django package.
#
# Translators:
# Jannis Leidel <jannis@leidel.info>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-03-28 10:04+0100\n"
"PO-Revision-Date: 2012-12-16 08:51+0000\n"
"Last-Translator: Jannis Leidel <jannis@leidel.info>\n"
"POT-Creation-Date: 2013-05-02 16:18+0200\n"
"PO-Revision-Date: 2010-05-13 15:35+0200\n"
"Last-Translator: Django team\n"
"Language-Team: English <en@li.org>\n"
"Language: en\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: admin.py:41
msgid "Personal info"
msgstr "Personal info"
msgstr ""
#: admin.py:42
msgid "Permissions"
msgstr "Permissions"
msgstr ""
#: admin.py:44
msgid "Important dates"
msgstr "Important dates"
msgstr ""
#: admin.py:132
msgid "Password changed successfully."
msgstr "Password changed successfully."
msgstr ""
#: admin.py:142
#, python-format
msgid "Change password: %s"
msgstr "Change password: %s"
msgstr ""
#: forms.py:33 tests/forms.py:261 tests/forms.py:266 tests/forms.py:407
#: forms.py:33 tests/test_forms.py:261 tests/test_forms.py:266
#: tests/test_forms.py:407
msgid "No password set."
msgstr "No password set."
msgstr ""
#: forms.py:39 tests/forms.py:271 tests/forms.py:277
#: forms.py:39 tests/test_forms.py:271 tests/test_forms.py:277
msgid "Invalid password format or unknown hashing algorithm."
msgstr "Invalid password format or unknown hashing algorithm."
msgstr ""
#: forms.py:72
msgid "A user with that username already exists."
msgstr "A user with that username already exists."
msgstr ""
#: forms.py:73 forms.py:254 forms.py:314
msgid "The two password fields didn't match."
msgstr "The two password fields didn't match."
msgstr ""
#: forms.py:75 forms.py:120
msgid "Username"
msgstr "Username"
msgstr ""
#: forms.py:77 forms.py:121
msgid "Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only."
msgstr "Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only."
msgstr ""
#: forms.py:80 forms.py:124
msgid "This value may contain only letters, numbers and @/./+/-/_ characters."
msgstr "This value may contain only letters, numbers and @/./+/-/_ characters."
msgstr ""
#: forms.py:82 forms.py:126 forms.py:153 forms.py:316
msgid "Password"
msgstr "Password"
msgstr ""
#: forms.py:84
msgid "Password confirmation"
msgstr "Password confirmation"
msgstr ""
#: forms.py:86
msgid "Enter the same password as above, for verification."
msgstr "Enter the same password as above, for verification."
msgstr ""
#: forms.py:127
msgid ""
@ -83,9 +81,6 @@ msgid ""
"password, but you can change the password using <a href=\"password/\">this "
"form</a>."
msgstr ""
"Raw passwords are not stored, so there is no way to see this user's "
"password, but you can change the password using <a href=\"password/\">this "
"form</a>."
#: forms.py:156
#, python-format
@ -93,208 +88,177 @@ msgid ""
"Please enter a correct %(username)s and password. Note that both fields may "
"be case-sensitive."
msgstr ""
"Please enter a correct %(username)s and password. Note that both fields may "
"be case-sensitive."
#: forms.py:158
msgid "This account is inactive."
msgstr "This account is inactive."
msgstr ""
#: forms.py:206
msgid "Email"
msgstr "Email"
msgstr ""
#: forms.py:256
msgid "New password"
msgstr "New password"
msgstr ""
#: forms.py:258
msgid "New password confirmation"
msgstr "New password confirmation"
msgstr ""
#: forms.py:287
msgid "Your old password was entered incorrectly. Please enter it again."
msgstr "Your old password was entered incorrectly. Please enter it again."
msgstr ""
#: forms.py:290
msgid "Old password"
msgstr "Old password"
msgstr ""
#: forms.py:318
msgid "Password (again)"
msgstr "Password (again)"
msgstr ""
#: hashers.py:243 hashers.py:317 hashers.py:365 hashers.py:393 hashers.py:426
#: hashers.py:459 hashers.py:493
msgid "algorithm"
msgstr "algorithm"
msgstr ""
#: hashers.py:244
msgid "iterations"
msgstr "iterations"
msgstr ""
#: hashers.py:245 hashers.py:319 hashers.py:366 hashers.py:394 hashers.py:494
msgid "salt"
msgstr "salt"
msgstr ""
#: hashers.py:246 hashers.py:367 hashers.py:395 hashers.py:427 hashers.py:460
#: hashers.py:495
msgid "hash"
msgstr "hash"
msgstr ""
#: hashers.py:318
msgid "work factor"
msgstr "work factor"
msgstr ""
#: hashers.py:320
msgid "checksum"
msgstr "checksum"
msgstr ""
#: models.py:72 models.py:121
msgid "name"
msgstr "name"
msgstr ""
#: models.py:74
msgid "codename"
msgstr "codename"
msgstr ""
#: models.py:78
msgid "permission"
msgstr "permission"
msgstr ""
#: models.py:79 models.py:123
msgid "permissions"
msgstr "permissions"
msgstr ""
#: models.py:128
msgid "group"
msgstr "group"
msgstr ""
#: models.py:129 models.py:301
#: models.py:129 models.py:294
msgid "groups"
msgstr "groups"
msgstr ""
#: models.py:200
msgid "password"
msgstr "password"
msgstr ""
#: models.py:201
msgid "last login"
msgstr "last login"
msgstr ""
#: models.py:298
#: models.py:291
msgid "superuser status"
msgstr "superuser status"
msgstr ""
#: models.py:292
msgid ""
"Designates that this user has all permissions without explicitly assigning "
"them."
msgstr ""
#: models.py:295
msgid ""
"The groups this user belongs to. A user will get all permissions granted to "
"each of his/her group."
msgstr ""
#: models.py:299
msgid ""
"Designates that this user has all permissions without explicitly assigning "
"them."
msgstr ""
"Designates that this user has all permissions without explicitly assigning "
"them."
#: models.py:302
msgid ""
"The groups this user belongs to. A user will get all permissions granted to "
"each of his/her group."
msgstr ""
"The groups this user belongs to. A user will get all permissions granted to "
"each of his/her group."
#: models.py:306
msgid "user permissions"
msgstr "user permissions"
msgstr ""
#: models.py:377
#: models.py:366
msgid "username"
msgstr "username"
msgstr ""
#: models.py:367
msgid ""
"Required. 30 characters or fewer. Letters, numbers and @/./+/-/_ characters"
msgstr ""
#: models.py:370
msgid "Enter a valid username."
msgstr ""
#: models.py:372
msgid "first name"
msgstr ""
#: models.py:373
msgid "last name"
msgstr ""
#: models.py:374
msgid "email address"
msgstr ""
#: models.py:375
msgid "staff status"
msgstr ""
#: models.py:376
msgid "Designates whether the user can log into this admin site."
msgstr ""
#: models.py:378
msgid ""
"Required. 30 characters or fewer. Letters, numbers and @/./+/-/_ characters"
msgid "active"
msgstr ""
#: models.py:379
msgid ""
"Designates whether this user should be treated as active. Unselect this "
"instead of deleting accounts."
msgstr ""
"Required. 30 characters or fewer. Letters, numbers and @/./+/-/_ characters"
#: models.py:381
msgid "Enter a valid username."
msgstr "Enter a valid username."
#: models.py:383
msgid "first name"
msgstr "first name"
#: models.py:384
msgid "last name"
msgstr "last name"
#: models.py:385
msgid "email address"
msgstr "email address"
#: models.py:386
msgid "staff status"
msgstr "staff status"
#: models.py:387
msgid "Designates whether the user can log into this admin site."
msgstr "Designates whether the user can log into this admin site."
msgid "date joined"
msgstr ""
#: models.py:389
msgid "active"
msgstr "active"
msgid "user"
msgstr ""
#: models.py:390
msgid ""
"Designates whether this user should be treated as active. Unselect this "
"instead of deleting accounts."
msgstr ""
"Designates whether this user should be treated as active. Unselect this "
"instead of deleting accounts."
#: models.py:392
msgid "date joined"
msgstr "date joined"
#: models.py:400
msgid "user"
msgstr "user"
#: models.py:401
msgid "users"
msgstr "users"
msgstr ""
#: views.py:89
msgid "Logged out"
msgstr "Logged out"
msgstr ""
#: templates/registration/password_reset_subject.txt:2
#, python-format
msgid "Password reset on %(site_name)s"
msgstr "Password reset on %(site_name)s"
msgstr ""
#: tests/forms.py:325
#, fuzzy
#: tests/test_forms.py:325
msgid "Enter a valid email address."
msgstr "Enter a valid username."
#~ msgid ""
#~ "Your Web browser doesn't appear to have cookies enabled. Cookies are "
#~ "required for logging in."
#~ msgstr ""
#~ "Your Web browser doesn't appear to have cookies enabled. Cookies are "
#~ "required for logging in."
#~ msgid ""
#~ "That email address doesn't have an associated user account. Are you sure "
#~ "you've registered?"
#~ msgstr ""
#~ "That email address doesn't have an associated user account. Are you sure "
#~ "you've registered?"
#~ msgid ""
#~ "The user account associated with this email address cannot reset the "
#~ "password."
#~ msgstr ""
#~ "The user account associated with this email address cannot reset the "
#~ "password."
msgstr ""

View File

@ -1,182 +1,171 @@
# This file is distributed under the same license as the Django package.
#
# Translators:
# Jannis Leidel <jannis@leidel.info>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-03-28 10:04+0100\n"
"PO-Revision-Date: 2012-02-14 13:24+0000\n"
"Last-Translator: Jannis Leidel <jannis@leidel.info>\n"
"POT-Creation-Date: 2013-05-02 16:18+0200\n"
"PO-Revision-Date: 2010-05-13 15:35+0200\n"
"Last-Translator: Django team\n"
"Language-Team: English <en@li.org>\n"
"Language: en\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: admin.py:25
msgid "Content"
msgstr "Content"
msgstr ""
#: admin.py:28
msgid "Metadata"
msgstr "Metadata"
msgstr ""
#: admin.py:55
#, fuzzy, python-format
#, python-format
msgid "%d comment was successfully flagged"
msgid_plural "%d comments were successfully flagged"
msgstr[0] "1 comment was successfully %(action)s."
msgstr[1] "%(count)s comments were successfully %(action)s."
msgstr[0] ""
msgstr[1] ""
#: admin.py:57
msgid "Flag selected comments"
msgstr "Flag selected comments"
msgstr ""
#: admin.py:61
#, fuzzy, python-format
#, python-format
msgid "%d comment was successfully approved"
msgid_plural "%d comments were successfully approved"
msgstr[0] "1 comment was successfully %(action)s."
msgstr[1] "%(count)s comments were successfully %(action)s."
msgstr[0] ""
msgstr[1] ""
#: admin.py:63
msgid "Approve selected comments"
msgstr "Approve selected comments"
msgstr ""
#: admin.py:67
#, fuzzy, python-format
#, python-format
msgid "%d comment was successfully removed"
msgid_plural "%d comments were successfully removed"
msgstr[0] "1 comment was successfully %(action)s."
msgstr[1] "%(count)s comments were successfully %(action)s."
msgstr[0] ""
msgstr[1] ""
#: admin.py:69
msgid "Remove selected comments"
msgstr "Remove selected comments"
msgstr ""
#: feeds.py:14
#, python-format
msgid "%(site_name)s comments"
msgstr "%(site_name)s comments"
msgstr ""
#: feeds.py:20
#, python-format
msgid "Latest comments on %(site_name)s"
msgstr "Latest comments on %(site_name)s"
msgstr ""
#: forms.py:96
msgid "Name"
msgstr "Name"
msgstr ""
#: forms.py:97
msgid "Email address"
msgstr "Email address"
msgstr ""
#: forms.py:98
msgid "URL"
msgstr "URL"
msgstr ""
#: forms.py:99
msgid "Comment"
msgstr "Comment"
msgstr ""
#: forms.py:177
#, python-format
msgid "Watch your mouth! The word %s is not allowed here."
msgid_plural "Watch your mouth! The words %s are not allowed here."
msgstr[0] "Watch your mouth! The word %s is not allowed here."
msgstr[1] "Watch your mouth! The words %s are not allowed here."
msgstr[0] ""
msgstr[1] ""
#: forms.py:181 templates/comments/preview.html:16
msgid "and"
msgstr "and"
msgstr ""
#: forms.py:186
msgid ""
"If you enter anything in this field your comment will be treated as spam"
msgstr ""
"If you enter anything in this field your comment will be treated as spam"
#: models.py:23
msgid "content type"
msgstr "content type"
msgstr ""
#: models.py:25
msgid "object ID"
msgstr "object ID"
msgstr ""
#: models.py:53 models.py:177
msgid "user"
msgstr "user"
msgstr ""
#: models.py:55
msgid "user's name"
msgstr "user's name"
msgstr ""
#: models.py:56
msgid "user's email address"
msgstr "user's email address"
msgstr ""
#: models.py:57
msgid "user's URL"
msgstr "user's URL"
msgstr ""
#: models.py:59 models.py:79 models.py:178
msgid "comment"
msgstr "comment"
msgstr ""
#: models.py:62
msgid "date/time submitted"
msgstr "date/time submitted"
msgstr ""
#: models.py:63
msgid "IP address"
msgstr "IP address"
msgstr ""
#: models.py:64
msgid "is public"
msgstr "is public"
msgstr ""
#: models.py:65
msgid ""
"Uncheck this box to make the comment effectively disappear from the site."
msgstr ""
"Uncheck this box to make the comment effectively disappear from the site."
#: models.py:67
msgid "is removed"
msgstr "is removed"
msgstr ""
#: models.py:68
msgid ""
"Check this box if the comment is inappropriate. A \"This comment has been "
"removed\" message will be displayed instead."
msgstr ""
"Check this box if the comment is inappropriate. A \"This comment has been "
"removed\" message will be displayed instead."
#: models.py:80
msgid "comments"
msgstr "comments"
msgstr ""
#: models.py:124
msgid ""
"This comment was posted by an authenticated user and thus the name is read-"
"only."
msgstr ""
"This comment was posted by an authenticated user and thus the name is read-"
"only."
#: models.py:134
msgid ""
"This comment was posted by an authenticated user and thus the email is read-"
"only."
msgstr ""
"This comment was posted by an authenticated user and thus the email is read-"
"only."
#: models.py:160
#, python-format
@ -187,128 +176,107 @@ msgid ""
"\n"
"http://%(domain)s%(url)s"
msgstr ""
"Posted by %(user)s at %(date)s\n"
"\n"
"%(comment)s\n"
"\n"
"http://%(domain)s%(url)s"
#: models.py:179
msgid "flag"
msgstr "flag"
msgstr ""
#: models.py:180
msgid "date"
msgstr "date"
msgstr ""
#: models.py:190
msgid "comment flag"
msgstr "comment flag"
msgstr ""
#: models.py:191
msgid "comment flags"
msgstr "comment flags"
msgstr ""
#: templates/comments/approve.html:4
msgid "Approve a comment"
msgstr "Approve a comment"
msgstr ""
#: templates/comments/approve.html:7
msgid "Really make this comment public?"
msgstr "Really make this comment public?"
msgstr ""
#: templates/comments/approve.html:12
msgid "Approve"
msgstr "Approve"
msgstr ""
#: templates/comments/approved.html:4
msgid "Thanks for approving"
msgstr "Thanks for approving"
msgstr ""
#: templates/comments/approved.html:7 templates/comments/deleted.html:7
#: templates/comments/flagged.html:7
msgid ""
"Thanks for taking the time to improve the quality of discussion on our site"
msgstr ""
"Thanks for taking the time to improve the quality of discussion on our site"
#: templates/comments/delete.html:4
msgid "Remove a comment"
msgstr "Remove a comment"
msgstr ""
#: templates/comments/delete.html:7
msgid "Really remove this comment?"
msgstr "Really remove this comment?"
msgstr ""
#: templates/comments/delete.html:12
msgid "Remove"
msgstr "Remove"
msgstr ""
#: templates/comments/deleted.html:4
msgid "Thanks for removing"
msgstr "Thanks for removing"
msgstr ""
#: templates/comments/flag.html:4
msgid "Flag this comment"
msgstr "Flag this comment"
msgstr ""
#: templates/comments/flag.html:7
msgid "Really flag this comment?"
msgstr "Really flag this comment?"
msgstr ""
#: templates/comments/flag.html:12
msgid "Flag"
msgstr "Flag"
msgstr ""
#: templates/comments/flagged.html:4
msgid "Thanks for flagging"
msgstr "Thanks for flagging"
msgstr ""
#: templates/comments/form.html:17 templates/comments/preview.html:32
msgid "Post"
msgstr "Post"
msgstr ""
#: templates/comments/form.html:18 templates/comments/preview.html:33
msgid "Preview"
msgstr "Preview"
msgstr ""
#: templates/comments/posted.html:4
msgid "Thanks for commenting"
msgstr "Thanks for commenting"
msgstr ""
#: templates/comments/posted.html:7
msgid "Thank you for your comment"
msgstr "Thank you for your comment"
msgstr ""
#: templates/comments/preview.html:4 templates/comments/preview.html.py:13
msgid "Preview your comment"
msgstr "Preview your comment"
msgstr ""
#: templates/comments/preview.html:11
msgid "Please correct the error below"
msgid_plural "Please correct the errors below"
msgstr[0] "Please correct the error below"
msgstr[1] "Please correct the errors below"
msgstr[0] ""
msgstr[1] ""
#: templates/comments/preview.html:16
msgid "Post your comment"
msgstr "Post your comment"
msgstr ""
#: templates/comments/preview.html:16
msgid "or make changes"
msgstr "or make changes"
#~ msgid "flagged"
#~ msgid_plural "flagged"
#~ msgstr[0] "flagged"
#~ msgstr[1] "flagged"
#~ msgid "approved"
#~ msgid_plural "approved"
#~ msgstr[0] "approved"
#~ msgstr[1] "approved"
#~ msgid "removed"
#~ msgid_plural "removed"
#~ msgstr[0] "removed"
#~ msgstr[1] "removed"
msgstr ""

View File

@ -13,8 +13,9 @@ from django.db.models import signals
from django.db.models.fields.related import ForeignObject, ForeignObjectRel
from django.db.models.related import PathInfo
from django.db.models.sql.where import Constraint
from django.forms import ModelForm
from django.forms.models import BaseModelFormSet, modelformset_factory, save_instance
from django.forms import ModelForm, ALL_FIELDS
from django.forms.models import (BaseModelFormSet, modelformset_factory, save_instance,
modelform_defines_fields)
from django.contrib.admin.options import InlineModelAdmin, flatten_fieldsets
from django.contrib.contenttypes.models import ContentType
from django.utils import six
@ -137,9 +138,6 @@ class GenericForeignKey(six.with_metaclass(RenameGenericForeignKeyMethods)):
return rel_obj
def __set__(self, instance, value):
if instance is None:
raise AttributeError("%s must be accessed via instance" % self.related.opts.object_name)
ct = None
fk = None
if value is not None:
@ -280,9 +278,6 @@ class ReverseGenericRelatedObjectsDescriptor(object):
return manager
def __set__(self, instance, value):
if instance is None:
raise AttributeError("Manager must be accessed via instance")
manager = self.__get__(instance)
manager.clear()
for obj in value:
@ -486,6 +481,10 @@ class GenericInlineModelAdmin(InlineModelAdmin):
"exclude": exclude
}
defaults.update(kwargs)
if defaults['fields'] is None and not modelform_defines_fields(defaults['form']):
defaults['fields'] = ALL_FIELDS
return generic_inlineformset_factory(self.model, **defaults)
class GenericStackedInline(GenericInlineModelAdmin):

View File

@ -1,44 +1,41 @@
# This file is distributed under the same license as the Django package.
#
# Translators:
# Jannis Leidel <jannis@leidel.info>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-03-28 10:04+0100\n"
"PO-Revision-Date: 2012-03-08 11:45+0000\n"
"Last-Translator: Jannis Leidel <jannis@leidel.info>\n"
"POT-Creation-Date: 2013-05-02 16:18+0200\n"
"PO-Revision-Date: 2010-05-13 15:35+0200\n"
"Last-Translator: Django team\n"
"Language-Team: English <en@li.org>\n"
"Language: en\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: models.py:130
msgid "python model class name"
msgstr "python model class name"
msgstr ""
#: models.py:134
msgid "content type"
msgstr "content type"
msgstr ""
#: models.py:135
msgid "content types"
msgstr "content types"
msgstr ""
#: views.py:17
#, python-format
msgid "Content type %(ct_id)s object has no associated model"
msgstr "Content type %(ct_id)s object has no associated model"
msgstr ""
#: views.py:21
#, python-format
msgid "Content type %(ct_id)s object %(obj_id)s doesn't exist"
msgstr "Content type %(ct_id)s object %(obj_id)s doesn't exist"
msgstr ""
#: views.py:27
#, python-format
msgid "%(ct_name)s objects don't have a get_absolute_url() method"
msgstr "%(ct_name)s objects don't have a get_absolute_url() method"
msgstr ""

View File

@ -12,6 +12,7 @@ class FlatpageForm(forms.ModelForm):
class Meta:
model = FlatPage
fields = '__all__'
def clean_url(self):
url = self.cleaned_data['url']

View File

@ -1,97 +1,88 @@
# This file is distributed under the same license as the Django package.
#
# Translators:
# Jannis Leidel <jannis@leidel.info>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-03-28 10:04+0100\n"
"PO-Revision-Date: 2012-10-18 10:56+0000\n"
"Last-Translator: Jannis Leidel <jannis@leidel.info>\n"
"POT-Creation-Date: 2013-05-02 16:18+0200\n"
"PO-Revision-Date: 2010-05-13 15:35+0200\n"
"Last-Translator: Django team\n"
"Language-Team: English <en@li.org>\n"
"Language: en\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: admin.py:10
msgid "Advanced options"
msgstr "Advanced options"
msgstr ""
#: forms.py:7 models.py:11
msgid "URL"
msgstr "URL"
msgstr ""
#: forms.py:8
msgid ""
"Example: '/about/contact/'. Make sure to have leading and trailing slashes."
msgstr ""
"Example: '/about/contact/'. Make sure to have leading and trailing slashes."
#: forms.py:10
msgid ""
"This value must contain only letters, numbers, dots, underscores, dashes, "
"slashes or tildes."
msgstr ""
"This value must contain only letters, numbers, dots, underscores, dashes, "
"slashes or tildes."
#: forms.py:19
msgid "URL is missing a leading slash."
msgstr "URL is missing a leading slash."
msgstr ""
#: forms.py:23
msgid "URL is missing a trailing slash."
msgstr "URL is missing a trailing slash."
msgstr ""
#: forms.py:38
#, python-format
msgid "Flatpage with url %(url)s already exists for site %(site)s"
msgstr "Flatpage with url %(url)s already exists for site %(site)s"
msgstr ""
#: models.py:12
msgid "title"
msgstr "title"
msgstr ""
#: models.py:13
msgid "content"
msgstr "content"
msgstr ""
#: models.py:14
msgid "enable comments"
msgstr "enable comments"
msgstr ""
#: models.py:15
msgid "template name"
msgstr "template name"
msgstr ""
#: models.py:16
msgid ""
"Example: 'flatpages/contact_page.html'. If this isn't provided, the system "
"will use 'flatpages/default.html'."
msgstr ""
"Example: 'flatpages/contact_page.html'. If this isn't provided, the system "
"will use 'flatpages/default.html'."
#: models.py:17
msgid "registration required"
msgstr "registration required"
msgstr ""
#: models.py:18
msgid "If this is checked, only logged-in users will be able to view the page."
msgstr ""
"If this is checked, only logged-in users will be able to view the page."
#: models.py:24
msgid "flat page"
msgstr "flat page"
msgstr ""
#: models.py:25
msgid "flat pages"
msgstr "flat pages"
msgstr ""
#: tests/forms.py:98
#: tests/test_forms.py:98
msgid "This field is required."
msgstr "This field is required."
msgstr ""

View File

@ -1,36 +1,26 @@
# This file is distributed under the same license as the Django package.
#
# Translators:
# Jannis Leidel <jannis@leidel.info>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-03-28 10:04+0100\n"
"PO-Revision-Date: 2012-02-14 13:42+0000\n"
"Last-Translator: Jannis Leidel <jannis@leidel.info>\n"
"POT-Creation-Date: 2013-05-02 16:18+0200\n"
"PO-Revision-Date: 2010-05-13 15:35+0200\n"
"Last-Translator: Django team\n"
"Language-Team: English <en@li.org>\n"
"Language: en\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: templates/formtools/wizard/wizard_form.html:15
msgid "first step"
msgstr "first step"
msgstr ""
#: templates/formtools/wizard/wizard_form.html:16
msgid "prev step"
msgstr "prev step"
msgstr ""
#: templates/formtools/wizard/wizard_form.html:18
msgid "submit"
msgstr "submit"
#~ msgid ""
#~ "We apologize, but your form has expired. Please continue filling out the "
#~ "form from this page."
#~ msgstr ""
#~ "We apologize, but your form has expired. Please continue filling out the "
#~ "form from this page."
msgstr ""

View File

@ -60,9 +60,11 @@ class TestModel(models.Model):
class TestModelForm(forms.ModelForm):
class Meta:
model = TestModel
fields = '__all__'
TestModelFormSet = forms.models.modelformset_factory(TestModel, form=TestModelForm, extra=2)
TestModelFormSet = forms.models.modelformset_factory(TestModel, form=TestModelForm, extra=2,
fields='__all__')
class TestWizard(WizardView):

View File

@ -15,6 +15,7 @@ from django.utils._os import upath
class UserForm(forms.ModelForm):
class Meta:
model = User
fields = '__all__'
UserFormSet = forms.models.modelformset_factory(User, form=UserForm, extra=2)

View File

@ -3,10 +3,12 @@ Base/mixin classes for the spatial backend database operations and the
`SpatialRefSys` model the backend.
"""
import re
from django.contrib.gis import gdal
from django.utils import six
from django.utils.encoding import python_2_unicode_compatible
class BaseSpatialOperations(object):
"""
This module holds the base `BaseSpatialBackend` object, which is
@ -18,7 +20,7 @@ class BaseSpatialOperations(object):
geometry_operators = {}
geography_operators = {}
geography_functions = {}
gis_terms = {}
gis_terms = set()
truncate_params = {}
# Quick booleans for the type of this spatial backend, and

View File

@ -3,7 +3,6 @@ from django.db.backends.mysql.base import DatabaseOperations
from django.contrib.gis.db.backends.adapter import WKTAdapter
from django.contrib.gis.db.backends.base import BaseSpatialOperations
from django.utils import six
class MySQLOperations(DatabaseOperations, BaseSpatialOperations):
@ -18,21 +17,21 @@ class MySQLOperations(DatabaseOperations, BaseSpatialOperations):
Adaptor = Adapter # Backwards-compatibility alias.
geometry_functions = {
'bbcontains' : 'MBRContains', # For consistency w/PostGIS API
'bboverlaps' : 'MBROverlaps', # .. ..
'contained' : 'MBRWithin', # .. ..
'contains' : 'MBRContains',
'disjoint' : 'MBRDisjoint',
'equals' : 'MBREqual',
'exact' : 'MBREqual',
'intersects' : 'MBRIntersects',
'overlaps' : 'MBROverlaps',
'same_as' : 'MBREqual',
'touches' : 'MBRTouches',
'within' : 'MBRWithin',
}
'bbcontains': 'MBRContains', # For consistency w/PostGIS API
'bboverlaps': 'MBROverlaps', # .. ..
'contained': 'MBRWithin', # .. ..
'contains': 'MBRContains',
'disjoint': 'MBRDisjoint',
'equals': 'MBREqual',
'exact': 'MBREqual',
'intersects': 'MBRIntersects',
'overlaps': 'MBROverlaps',
'same_as': 'MBREqual',
'touches': 'MBRTouches',
'within': 'MBRWithin',
}
gis_terms = dict([(term, None) for term in list(geometry_functions) + ['isnull']])
gis_terms = set(geometry_functions) | set(['isnull'])
def geo_db_type(self, f):
return f.geom_type

View File

@ -18,6 +18,7 @@ from django.contrib.gis.geometry.backend import Geometry
from django.contrib.gis.measure import Distance
from django.utils import six
class SDOOperation(SpatialFunction):
"Base class for SDO* Oracle operations."
sql_template = "%(function)s(%(geo_col)s, %(geometry)s) %(operator)s '%(result)s'"
@ -32,6 +33,7 @@ class SDODistance(SpatialFunction):
sql_template = ('%(function)s(%(geo_col)s, %(geometry)s, %(tolerance)s) '
'%(operator)s %(result)s')
dist_func = 'SDO_GEOM.SDO_DISTANCE'
def __init__(self, op, tolerance=0.05):
super(SDODistance, self).__init__(self.dist_func,
tolerance=tolerance,
@ -40,6 +42,7 @@ class SDODistance(SpatialFunction):
class SDODWithin(SpatialFunction):
dwithin_func = 'SDO_WITHIN_DISTANCE'
sql_template = "%(function)s(%(geo_col)s, %(geometry)s, %%s) = 'TRUE'"
def __init__(self):
super(SDODWithin, self).__init__(self.dwithin_func)
@ -48,6 +51,7 @@ class SDOGeomRelate(SpatialFunction):
relate_func = 'SDO_GEOM.RELATE'
sql_template = ("%(function)s(%(geo_col)s, '%(mask)s', %(geometry)s, "
"%(tolerance)s) %(operator)s '%(mask)s'")
def __init__(self, mask, tolerance=0.05):
# SDO_GEOM.RELATE(...) has a peculiar argument order: column, mask, geom, tolerance.
# Moreover, the runction result is the mask (e.g., 'DISJOINT' instead of 'TRUE').
@ -60,6 +64,7 @@ class SDORelate(SpatialFunction):
mask_regex = re.compile(r'^(%s)(\+(%s))*$' % (masks, masks), re.I)
sql_template = "%(function)s(%(geo_col)s, %(geometry)s, 'mask=%(mask)s') = 'TRUE'"
relate_func = 'SDO_RELATE'
def __init__(self, mask):
if not self.mask_regex.match(mask):
raise ValueError('Invalid %s mask: "%s"' % (self.relate_func, mask))
@ -79,12 +84,12 @@ class OracleOperations(DatabaseOperations, BaseSpatialOperations):
Adaptor = Adapter # Backwards-compatibility alias.
area = 'SDO_GEOM.SDO_AREA'
gml= 'SDO_UTIL.TO_GMLGEOMETRY'
gml = 'SDO_UTIL.TO_GMLGEOMETRY'
centroid = 'SDO_GEOM.SDO_CENTROID'
difference = 'SDO_GEOM.SDO_DIFFERENCE'
distance = 'SDO_GEOM.SDO_DISTANCE'
extent= 'SDO_AGGR_MBR'
intersection= 'SDO_GEOM.SDO_INTERSECTION'
extent = 'SDO_AGGR_MBR'
intersection = 'SDO_GEOM.SDO_INTERSECTION'
length = 'SDO_GEOM.SDO_LENGTH'
num_geom = 'SDO_UTIL.GETNUMELEM'
num_points = 'SDO_UTIL.GETNUMVERTICES'
@ -127,9 +132,8 @@ class OracleOperations(DatabaseOperations, BaseSpatialOperations):
}
geometry_functions.update(distance_functions)
gis_terms = ['isnull']
gis_terms += list(geometry_functions)
gis_terms = dict([(term, None) for term in gis_terms])
gis_terms = set(['isnull'])
gis_terms.update(geometry_functions)
truncate_params = {'relate' : None}
@ -272,7 +276,8 @@ class OracleOperations(DatabaseOperations, BaseSpatialOperations):
given Aggregate instance.
"""
agg_name = agg.__class__.__name__.lower()
if agg_name == 'union' : agg_name += 'agg'
if agg_name == 'union':
agg_name += 'agg'
if agg.is_extent:
sql_template = '%(function)s(%(field)s)'
else:
@ -295,5 +300,5 @@ class OracleOperations(DatabaseOperations, BaseSpatialOperations):
"""
# This code doesn't work for bulk insert cases.
assert len(placeholders) == 1
return [[param for pholder,param
return [[param for pholder, param
in six.moves.zip(placeholders[0], params[0]) if pholder != 'NULL'], ]

View File

@ -208,23 +208,22 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
# for the geography type.
self.geography_functions = self.distance_functions.copy()
self.geography_functions.update({
'coveredby' : self.geometry_functions['coveredby'],
'covers' : self.geometry_functions['covers'],
'intersects' : self.geometry_functions['intersects'],
})
'coveredby': self.geometry_functions['coveredby'],
'covers': self.geometry_functions['covers'],
'intersects': self.geometry_functions['intersects'],
})
self.geography_operators = {
'bboverlaps' : PostGISOperator('&&'),
}
'bboverlaps': PostGISOperator('&&'),
}
# Native geometry type support added in PostGIS 2.0.
if version >= (2, 0, 0):
self.geometry = True
# Creating a dictionary lookup of all GIS terms for PostGIS.
gis_terms = ['isnull']
gis_terms += list(self.geometry_operators)
gis_terms += list(self.geometry_functions)
self.gis_terms = dict([(term, None) for term in gis_terms])
self.gis_terms = set(['isnull'])
self.gis_terms.update(self.geometry_operators)
self.gis_terms.update(self.geometry_functions)
self.area = prefix + 'Area'
self.bounding_circle = BOUNDINGCIRCLE
@ -247,7 +246,7 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
self.makeline = prefix + 'MakeLine'
self.mem_size = prefix + 'mem_size'
self.num_geom = prefix + 'NumGeometries'
self.num_points =prefix + 'npoints'
self.num_points = prefix + 'npoints'
self.perimeter = prefix + 'Perimeter'
self.point_on_surface = prefix + 'PointOnSurface'
self.polygonize = prefix + 'Polygonize'
@ -324,7 +323,7 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
raise NotImplementedError('PostGIS 1.5 supports geography columns '
'only with an SRID of 4326.')
return 'geography(%s,%d)'% (f.geom_type, f.srid)
return 'geography(%s,%d)' % (f.geom_type, f.srid)
elif self.geometry:
# Postgis 2.0 supports type-based geometries.
# TODO: Support 'M' extension.
@ -565,7 +564,8 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations):
if not self.check_aggregate_support(agg):
raise NotImplementedError('%s spatial aggregate is not implmented for this backend.' % agg_name)
agg_name = agg_name.lower()
if agg_name == 'union': agg_name += 'agg'
if agg_name == 'union':
agg_name += 'agg'
sql_template = '%(function)s(%(field)s)'
sql_function = getattr(self, agg_name)
return sql_template, sql_function

View File

@ -117,9 +117,8 @@ class SpatiaLiteOperations(DatabaseOperations, BaseSpatialOperations):
super(DatabaseOperations, self).__init__(connection)
# Creating the GIS terms dictionary.
gis_terms = ['isnull']
gis_terms += self.geometry_functions.keys()
self.gis_terms = dict([(term, None) for term in gis_terms])
self.gis_terms = set(['isnull'])
self.gis_terms.update(self.geometry_functions)
@cached_property
def spatial_version(self):

View File

@ -11,6 +11,7 @@ from django.contrib.gis.geoip.prototypes import (
GeoIP_country_name_by_addr, GeoIP_country_name_by_name)
from django.utils import six
from django.utils.encoding import force_bytes
# Regular expressions for recognizing the GeoIP free database editions.
free_regex = re.compile(r'^GEO-\d{3}FREE')
@ -97,18 +98,18 @@ class GeoIP(object):
# and/or city datasets exist, then try and open them.
country_db = os.path.join(path, country or GEOIP_SETTINGS.get('GEOIP_COUNTRY', 'GeoIP.dat'))
if os.path.isfile(country_db):
self._country = GeoIP_open(country_db, cache)
self._country = GeoIP_open(force_bytes(country_db), cache)
self._country_file = country_db
city_db = os.path.join(path, city or GEOIP_SETTINGS.get('GEOIP_CITY', 'GeoLiteCity.dat'))
if os.path.isfile(city_db):
self._city = GeoIP_open(city_db, cache)
self._city = GeoIP_open(force_bytes(city_db), cache)
self._city_file = city_db
elif os.path.isfile(path):
# Otherwise, some detective work will be needed to figure
# out whether the given database path is for the GeoIP country
# or city databases.
ptr = GeoIP_open(path, cache)
ptr = GeoIP_open(force_bytes(path), cache)
info = GeoIP_database_info(ptr)
if lite_regex.match(info):
# GeoLite City database detected.
@ -136,9 +137,6 @@ class GeoIP(object):
if not isinstance(query, six.string_types):
raise TypeError('GeoIP query must be a string, not type %s' % type(query).__name__)
# GeoIP only takes ASCII-encoded strings.
query = query.encode('ascii')
# Extra checks for the existence of country and city databases.
if city_or_country and not (self._country or self._city):
raise GeoIPException('Invalid GeoIP country and city data files.')
@ -147,8 +145,8 @@ class GeoIP(object):
elif city and not self._city:
raise GeoIPException('Invalid GeoIP city data file: %s' % self._city_file)
# Return the query string back to the caller.
return query
# Return the query string back to the caller. GeoIP only takes bytestrings.
return force_bytes(query)
def city(self, query):
"""
@ -156,33 +154,33 @@ class GeoIP(object):
Fully Qualified Domain Name (FQDN). Some information in the dictionary
may be undefined (None).
"""
query = self._check_query(query, city=True)
enc_query = self._check_query(query, city=True)
if ipv4_re.match(query):
# If an IP address was passed in
return GeoIP_record_by_addr(self._city, c_char_p(query))
return GeoIP_record_by_addr(self._city, c_char_p(enc_query))
else:
# If a FQDN was passed in.
return GeoIP_record_by_name(self._city, c_char_p(query))
return GeoIP_record_by_name(self._city, c_char_p(enc_query))
def country_code(self, query):
"Returns the country code for the given IP Address or FQDN."
query = self._check_query(query, city_or_country=True)
enc_query = self._check_query(query, city_or_country=True)
if self._country:
if ipv4_re.match(query):
return GeoIP_country_code_by_addr(self._country, query)
return GeoIP_country_code_by_addr(self._country, enc_query)
else:
return GeoIP_country_code_by_name(self._country, query)
return GeoIP_country_code_by_name(self._country, enc_query)
else:
return self.city(query)['country_code']
def country_name(self, query):
"Returns the country name for the given IP Address or FQDN."
query = self._check_query(query, city_or_country=True)
enc_query = self._check_query(query, city_or_country=True)
if self._country:
if ipv4_re.match(query):
return GeoIP_country_name_by_addr(self._country, query)
return GeoIP_country_name_by_addr(self._country, enc_query)
else:
return GeoIP_country_name_by_name(self._country, query)
return GeoIP_country_name_by_name(self._country, enc_query)
else:
return self.city(query)['country_name']

View File

@ -92,7 +92,7 @@ def check_string(result, func, cargs):
free(result)
else:
s = ''
return s
return s.decode()
GeoIP_database_info = lgeoip.GeoIP_database_info
GeoIP_database_info.restype = geoip_char_p
@ -100,7 +100,12 @@ GeoIP_database_info.errcheck = check_string
# String output routines.
def string_output(func):
def _err_check(result, func, cargs):
if result:
return result.decode()
return result
func.restype = c_char_p
func.errcheck = _err_check
return func
GeoIP_country_code_by_addr = string_output(lgeoip.GeoIP_country_code_by_addr)

View File

@ -103,14 +103,8 @@ class GeoIPTest(unittest.TestCase):
def test05_unicode_response(self):
"Testing that GeoIP strings are properly encoded, see #16553."
g = GeoIP()
d = g.city('62.224.93.23')
self.assertEqual('Schümberg', d['city'])
def test06_unicode_query(self):
"Testing that GeoIP accepts unicode string queries, see #17059."
g = GeoIP()
d = g.country('whitehouse.gov')
self.assertEqual('US', d['country_code'])
d = g.city("www.osnabrueck.de")
self.assertEqual('Osnabrück', d['city'])
def suite():

View File

@ -1,93 +1,88 @@
# This file is distributed under the same license as the Django package.
#
# Translators:
# Jannis Leidel <jannis@leidel.info>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-03-28 10:04+0100\n"
"PO-Revision-Date: 2012-03-08 12:32+0000\n"
"Last-Translator: Jannis Leidel <jannis@leidel.info>\n"
"POT-Creation-Date: 2013-05-02 16:18+0200\n"
"PO-Revision-Date: 2010-05-13 15:35+0200\n"
"Last-Translator: Django team\n"
"Language-Team: English <en@li.org>\n"
"Language: en\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: views.py:9
msgid "No feeds are registered."
msgstr "No feeds are registered."
msgstr ""
#: views.py:19
#, python-format
msgid "Slug %r isn't registered."
msgstr "Slug %r isn't registered."
msgstr ""
#: db/models/fields.py:51
msgid "The base GIS field -- maps to the OpenGIS Specification Geometry type."
msgstr "The base GIS field -- maps to the OpenGIS Specification Geometry type."
msgstr ""
#: db/models/fields.py:270
msgid "Point"
msgstr "Point"
msgstr ""
#: db/models/fields.py:274
msgid "Line string"
msgstr "Line string"
msgstr ""
#: db/models/fields.py:278
msgid "Polygon"
msgstr "Polygon"
msgstr ""
#: db/models/fields.py:282
msgid "Multi-point"
msgstr "Multi-point"
msgstr ""
#: db/models/fields.py:286
msgid "Multi-line string"
msgstr "Multi-line string"
msgstr ""
#: db/models/fields.py:290
msgid "Multi polygon"
msgstr "Multi polygon"
msgstr ""
#: db/models/fields.py:294
msgid "Geometry collection"
msgstr "Geometry collection"
msgstr ""
#: forms/fields.py:23
msgid "No geometry value provided."
msgstr "No geometry value provided."
msgstr ""
#: forms/fields.py:24
msgid "Invalid geometry value."
msgstr "Invalid geometry value."
msgstr ""
#: forms/fields.py:25
msgid "Invalid geometry type."
msgstr "Invalid geometry type."
msgstr ""
#: forms/fields.py:26
msgid ""
"An error occurred when transforming the geometry to the SRID of the geometry "
"form field."
msgstr ""
"An error occurred when transforming the geometry to the SRID of the geometry "
"form field."
#: sitemaps/views.py:46
#, python-format
msgid "No sitemap available for section: %r"
msgstr "No sitemap available for section: %r"
msgstr ""
#: sitemaps/views.py:60
#, python-format
msgid "Page %s empty"
msgstr "Page %s empty"
msgstr ""
#: sitemaps/views.py:62
#, python-format
msgid "No page '%s'"
msgstr "No page '%s'"
msgstr ""

View File

@ -297,7 +297,7 @@ class GeoLookupTest(TestCase):
# The left/right lookup tests are known failures on PostGIS 2.0/2.0.1
# http://trac.osgeo.org/postgis/ticket/2035
if (2, 0, 0) <= connection.ops.spatial_version <= (2, 0, 1):
if connection.ops.postgis and (2, 0, 0) <= connection.ops.spatial_version <= (2, 0, 1):
test_left_right_lookups = unittest.expectedFailure(test_left_right_lookups)
def test_equals_lookups(self):

View File

@ -1,293 +1,290 @@
# This file is distributed under the same license as the Django package.
#
# Translators:
# Jannis Leidel <jannis@leidel.info>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-03-28 10:04+0100\n"
"PO-Revision-Date: 2012-02-14 13:08+0000\n"
"Last-Translator: Jannis Leidel <jannis@leidel.info>\n"
"POT-Creation-Date: 2013-05-02 16:18+0200\n"
"PO-Revision-Date: 2010-05-13 15:35+0200\n"
"Last-Translator: Django team\n"
"Language-Team: English <en@li.org>\n"
"Language: en\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: tests.py:131 templatetags/humanize.py:168
#: tests.py:135 templatetags/humanize.py:168
msgid "today"
msgstr "today"
msgstr ""
#: tests.py:131 templatetags/humanize.py:172
#: tests.py:135 templatetags/humanize.py:172
msgid "yesterday"
msgstr "yesterday"
msgstr ""
#: tests.py:131 templatetags/humanize.py:170
#: tests.py:135 templatetags/humanize.py:170
msgid "tomorrow"
msgstr "tomorrow"
msgstr ""
#: templatetags/humanize.py:26
msgid "th"
msgstr "th"
msgstr ""
#: templatetags/humanize.py:26
msgid "st"
msgstr "st"
msgstr ""
#: templatetags/humanize.py:26
msgid "nd"
msgstr "nd"
msgstr ""
#: templatetags/humanize.py:26
msgid "rd"
msgstr "rd"
msgstr ""
#: templatetags/humanize.py:55
#, python-format
msgid "%(value).1f million"
msgid_plural "%(value).1f million"
msgstr[0] "%(value).1f million"
msgstr[1] "%(value).1f million"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:56
#, python-format
msgid "%(value)s million"
msgid_plural "%(value)s million"
msgstr[0] "%(value)s million"
msgstr[1] "%(value)s million"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:59
#, python-format
msgid "%(value).1f billion"
msgid_plural "%(value).1f billion"
msgstr[0] "%(value).1f billion"
msgstr[1] "%(value).1f billion"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:60
#, python-format
msgid "%(value)s billion"
msgid_plural "%(value)s billion"
msgstr[0] "%(value)s billion"
msgstr[1] "%(value)s billion"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:63
#, python-format
msgid "%(value).1f trillion"
msgid_plural "%(value).1f trillion"
msgstr[0] "%(value).1f trillion"
msgstr[1] "%(value).1f trillion"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:64
#, python-format
msgid "%(value)s trillion"
msgid_plural "%(value)s trillion"
msgstr[0] "%(value)s trillion"
msgstr[1] "%(value)s trillion"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:67
#, python-format
msgid "%(value).1f quadrillion"
msgid_plural "%(value).1f quadrillion"
msgstr[0] "%(value).1f quadrillion"
msgstr[1] "%(value).1f quadrillion"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:68
#, python-format
msgid "%(value)s quadrillion"
msgid_plural "%(value)s quadrillion"
msgstr[0] "%(value)s quadrillion"
msgstr[1] "%(value)s quadrillion"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:71
#, python-format
msgid "%(value).1f quintillion"
msgid_plural "%(value).1f quintillion"
msgstr[0] "%(value).1f quintillion"
msgstr[1] "%(value).1f quintillion"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:72
#, python-format
msgid "%(value)s quintillion"
msgid_plural "%(value)s quintillion"
msgstr[0] "%(value)s quintillion"
msgstr[1] "%(value)s quintillion"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:75
#, python-format
msgid "%(value).1f sextillion"
msgid_plural "%(value).1f sextillion"
msgstr[0] "%(value).1f sextillion"
msgstr[1] "%(value).1f sextillion"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:76
#, python-format
msgid "%(value)s sextillion"
msgid_plural "%(value)s sextillion"
msgstr[0] "%(value)s sextillion"
msgstr[1] "%(value)s sextillion"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:79
#, python-format
msgid "%(value).1f septillion"
msgid_plural "%(value).1f septillion"
msgstr[0] "%(value).1f septillion"
msgstr[1] "%(value).1f septillion"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:80
#, python-format
msgid "%(value)s septillion"
msgid_plural "%(value)s septillion"
msgstr[0] "%(value)s septillion"
msgstr[1] "%(value)s septillion"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:83
#, python-format
msgid "%(value).1f octillion"
msgid_plural "%(value).1f octillion"
msgstr[0] "%(value).1f octillion"
msgstr[1] "%(value).1f octillion"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:84
#, python-format
msgid "%(value)s octillion"
msgid_plural "%(value)s octillion"
msgstr[0] "%(value)s octillion"
msgstr[1] "%(value)s octillion"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:87
#, python-format
msgid "%(value).1f nonillion"
msgid_plural "%(value).1f nonillion"
msgstr[0] "%(value).1f nonillion"
msgstr[1] "%(value).1f nonillion"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:88
#, python-format
msgid "%(value)s nonillion"
msgid_plural "%(value)s nonillion"
msgstr[0] "%(value)s nonillion"
msgstr[1] "%(value)s nonillion"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:91
#, python-format
msgid "%(value).1f decillion"
msgid_plural "%(value).1f decillion"
msgstr[0] "%(value).1f decillion"
msgstr[1] "%(value).1f decillion"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:92
#, python-format
msgid "%(value)s decillion"
msgid_plural "%(value)s decillion"
msgstr[0] "%(value)s decillion"
msgstr[1] "%(value)s decillion"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:95
#, python-format
msgid "%(value).1f googol"
msgid_plural "%(value).1f googol"
msgstr[0] "%(value).1f googol"
msgstr[1] "%(value).1f googol"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:96
#, python-format
msgid "%(value)s googol"
msgid_plural "%(value)s googol"
msgstr[0] "%(value)s googol"
msgstr[1] "%(value)s googol"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:145
msgid "one"
msgstr "one"
msgstr ""
#: templatetags/humanize.py:145
msgid "two"
msgstr "two"
msgstr ""
#: templatetags/humanize.py:145
msgid "three"
msgstr "three"
msgstr ""
#: templatetags/humanize.py:145
msgid "four"
msgstr "four"
msgstr ""
#: templatetags/humanize.py:145
msgid "five"
msgstr "five"
msgstr ""
#: templatetags/humanize.py:145
msgid "six"
msgstr "six"
msgstr ""
#: templatetags/humanize.py:145
msgid "seven"
msgstr "seven"
msgstr ""
#: templatetags/humanize.py:145
msgid "eight"
msgstr "eight"
msgstr ""
#: templatetags/humanize.py:145
msgid "nine"
msgstr "nine"
msgstr ""
#: templatetags/humanize.py:191
#, python-format
msgctxt "naturaltime"
msgid "%(delta)s ago"
msgstr "%(delta)s ago"
msgstr ""
#: templatetags/humanize.py:194 templatetags/humanize.py:216
msgid "now"
msgstr "now"
msgstr ""
#: templatetags/humanize.py:197
#, python-format
msgid "a second ago"
msgid_plural "%(count)s seconds ago"
msgstr[0] "a second ago"
msgstr[1] "%(count)s seconds ago"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:202
#, python-format
msgid "a minute ago"
msgid_plural "%(count)s minutes ago"
msgstr[0] "a minute ago"
msgstr[1] "%(count)s minutes ago"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:207
#, python-format
msgid "an hour ago"
msgid_plural "%(count)s hours ago"
msgstr[0] "an hour ago"
msgstr[1] "%(count)s hours ago"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:213
#, python-format
msgctxt "naturaltime"
msgid "%(delta)s from now"
msgstr "%(delta)s from now"
msgstr ""
#: templatetags/humanize.py:219
#, python-format
msgid "a second from now"
msgid_plural "%(count)s seconds from now"
msgstr[0] "a second from now"
msgstr[1] "%(count)s seconds from now"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:224
#, python-format
msgid "a minute from now"
msgid_plural "%(count)s minutes from now"
msgstr[0] "a minute from now"
msgstr[1] "%(count)s minutes from now"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:229
#, python-format
msgid "an hour from now"
msgid_plural "%(count)s hours from now"
msgstr[0] "an hour from now"
msgstr[1] "%(count)s hours from now"
msgstr[0] ""
msgstr[1] ""

View File

@ -1,21 +1,18 @@
# This file is distributed under the same license as the Django package.
#
# Translators:
# Jannis Leidel <jannis@leidel.info>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-03-28 10:04+0100\n"
"PO-Revision-Date: 2012-02-14 13:16+0000\n"
"Last-Translator: Jannis Leidel <jannis@leidel.info>\n"
"POT-Creation-Date: 2013-05-02 16:18+0200\n"
"PO-Revision-Date: 2010-05-13 15:35+0200\n"
"Last-Translator: Django team\n"
"Language-Team: English <en@li.org>\n"
"Language: en\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: tests/base.py:101
#: tests/base.py:100
msgid "lazy message"
msgstr "lazy message"
msgstr ""

View File

@ -1,49 +1,42 @@
# This file is distributed under the same license as the Django package.
#
# Translators:
# Jannis Leidel <jannis@leidel.info>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-03-28 10:04+0100\n"
"PO-Revision-Date: 2012-02-14 13:39+0000\n"
"Last-Translator: Jannis Leidel <jannis@leidel.info>\n"
"POT-Creation-Date: 2013-05-02 16:18+0200\n"
"PO-Revision-Date: 2010-05-13 15:35+0200\n"
"Last-Translator: Django team\n"
"Language-Team: English <en@li.org>\n"
"Language: en\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: models.py:9
msgid "redirect from"
msgstr "redirect from"
msgstr ""
#: models.py:10
msgid ""
"This should be an absolute path, excluding the domain name. Example: '/"
"events/search/'."
msgstr ""
"This should be an absolute path, excluding the domain name. Example: '/"
"events/search/'."
#: models.py:11
msgid "redirect to"
msgstr "redirect to"
msgstr ""
#: models.py:12
msgid ""
"This can be either an absolute path (as above) or a full URL starting with "
"'http://'."
msgstr ""
"This can be either an absolute path (as above) or a full URL starting with "
"'http://'."
#: models.py:15
msgid "redirect"
msgstr "redirect"
msgstr ""
#: models.py:16
msgid "redirects"
msgstr "redirects"
msgstr ""

View File

@ -1,37 +1,34 @@
# This file is distributed under the same license as the Django package.
#
# Translators:
# Jannis Leidel <jannis@leidel.info>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-03-28 10:04+0100\n"
"PO-Revision-Date: 2012-02-14 13:40+0000\n"
"Last-Translator: Jannis Leidel <jannis@leidel.info>\n"
"POT-Creation-Date: 2013-05-02 16:18+0200\n"
"PO-Revision-Date: 2010-05-13 15:35+0200\n"
"Last-Translator: Django team\n"
"Language-Team: English <en@li.org>\n"
"Language: en\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: models.py:38
msgid "session key"
msgstr "session key"
msgstr ""
#: models.py:40
msgid "session data"
msgstr "session data"
msgstr ""
#: models.py:41
msgid "expire date"
msgstr "expire date"
msgstr ""
#: models.py:46
msgid "session"
msgstr "session"
msgstr ""
#: models.py:47
msgid "sessions"
msgstr "sessions"
msgstr ""

View File

@ -144,3 +144,10 @@ class HTTPSitemapTests(SitemapTestsBase):
</sitemapindex>
""" % self.base_url
self.assertXMLEqual(response.content.decode('utf-8'), expected_content)
def test_x_robots_sitemap(self):
response = self.client.get('/simple/index.xml')
self.assertEqual(response['X-Robots-Tag'], 'noindex, noodp, noarchive')
response = self.client.get('/simple/sitemap.xml')
self.assertEqual(response['X-Robots-Tag'], 'noindex, noodp, noarchive')

View File

@ -1,4 +1,5 @@
import warnings
from functools import wraps
from django.contrib.sites.models import get_current_site
from django.core import urlresolvers
@ -7,6 +8,15 @@ from django.http import Http404
from django.template.response import TemplateResponse
from django.utils import six
def x_robots_tag(func):
@wraps(func)
def inner(request, *args, **kwargs):
response = func(request, *args, **kwargs)
response['X-Robots-Tag'] = 'noindex, noodp, noarchive'
return response
return inner
@x_robots_tag
def index(request, sitemaps,
template_name='sitemap_index.xml', content_type='application/xml',
sitemap_url_name='django.contrib.sitemaps.views.sitemap',
@ -35,6 +45,7 @@ def index(request, sitemaps,
return TemplateResponse(request, template_name, {'sitemaps': sites},
content_type=content_type)
@x_robots_tag
def sitemap(request, sitemaps, section=None,
template_name='sitemap.xml', content_type='application/xml',
mimetype=None):

View File

@ -1,20 +1,17 @@
# This file is distributed under the same license as the Django package.
#
# Translators:
# Jannis Leidel <jannis@leidel.info>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-03-28 10:04+0100\n"
"PO-Revision-Date: 2012-02-14 13:49+0000\n"
"Last-Translator: Jannis Leidel <jannis@leidel.info>\n"
"POT-Creation-Date: 2013-05-02 16:18+0200\n"
"PO-Revision-Date: 2010-05-13 15:35+0200\n"
"Last-Translator: Django team\n"
"Language-Team: English <en@li.org>\n"
"Language: en\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: models.py:25
msgid "The domain name cannot contain any spaces or tabs."
@ -22,16 +19,16 @@ msgstr ""
#: models.py:58
msgid "domain name"
msgstr "domain name"
msgstr ""
#: models.py:60
msgid "display name"
msgstr "display name"
msgstr ""
#: models.py:65
msgid "site"
msgstr "site"
msgstr ""
#: models.py:66
msgid "sites"
msgstr "sites"
msgstr ""

View File

@ -116,6 +116,12 @@ class Command(NoArgsCommand):
processor = self.storage.post_process(found_files,
dry_run=self.dry_run)
for original_path, processed_path, processed in processor:
if isinstance(processed, Exception):
self.stderr.write("Post-processing '%s' failed!" % original_path)
# Add a blank line before the traceback, otherwise it's
# too easy to miss the relevant part of the error message.
self.stderr.write("")
raise processed
if processed:
self.log("Post-processed '%s' as '%s'" %
(original_path, processed_path), level=1)

View File

@ -251,7 +251,10 @@ class CachedFilesMixin(object):
for patterns in self._patterns.values():
for pattern, template in patterns:
converter = self.url_converter(name, template)
content = pattern.sub(converter, content)
try:
content = pattern.sub(converter, content)
except ValueError as exc:
yield name, None, exc
if hashed_file_exists:
self.delete(hashed_name)
# then save the processed result

View File

@ -237,7 +237,7 @@ def get_path_info(environ):
"""
path_info = environ.get('PATH_INFO', str('/'))
# Under Python 3, strings in environ are decoded with ISO-8859-1;
# re-encode to recover the original bytestring provided by the webserver.
# re-encode to recover the original bytestring provided by the web server.
if six.PY3:
path_info = path_info.encode('iso-8859-1')
# It'd be better to implement URI-to-IRI decoding, see #19508.
@ -266,7 +266,7 @@ def get_script_name(environ):
else:
script_name = environ.get('SCRIPT_NAME', str(''))
# Under Python 3, strings in environ are decoded with ISO-8859-1;
# re-encode to recover the original bytestring provided by the webserver.
# re-encode to recover the original bytestring provided by the web server.
if six.PY3:
script_name = script_name.encode('iso-8859-1')
# It'd be better to implement URI-to-IRI decoding, see #19508.

View File

@ -57,6 +57,7 @@ STATUS_CODE_TEXT = {
415: 'UNSUPPORTED MEDIA TYPE',
416: 'REQUESTED RANGE NOT SATISFIABLE',
417: 'EXPECTATION FAILED',
418: "I'M A TEAPOT",
422: 'UNPROCESSABLE ENTITY',
423: 'LOCKED',
424: 'FAILED DEPENDENCY',

View File

@ -294,7 +294,10 @@ class Command(NoArgsCommand):
os.unlink(potfile)
for f in file_list:
f.process(self, potfile, self.domain, self.keep_pot)
try:
f.process(self, potfile, self.domain, self.keep_pot)
except UnicodeDecodeError:
self.stdout.write("UnicodeDecodeError: skipped file %s in %s" % (f.file, f.dirpath))
return potfile
def find_files(self, root):

View File

@ -43,7 +43,7 @@ class TemplateCommand(BaseCommand):
option_list = BaseCommand.option_list + (
make_option('--template',
action='store', dest='template',
help='The dotted import path to load the template from.'),
help='The path or URL to load the template from.'),
make_option('--extension', '-e', dest='extensions',
action='append', default=['py'],
help='The file extension(s) to render (default: "py"). '

View File

@ -108,6 +108,8 @@ class ServerHandler(simple_server.ServerHandler, object):
class WSGIServer(simple_server.WSGIServer, object):
"""BaseHTTPServer that implements the Python WSGI protocol"""
request_queue_size = 10
def __init__(self, *args, **kwargs):
if kwargs.pop('ipv6', False):
self.address_family = socket.AF_INET6

View File

@ -30,6 +30,11 @@ if (version < (1, 2, 1) or (version[:3] == (1, 2, 1) and
from MySQLdb.converters import conversions, Thing2Literal
from MySQLdb.constants import FIELD_TYPE, CLIENT
try:
import pytz
except ImportError:
pytz = None
from django.conf import settings
from django.db import utils
from django.db.backends import *
@ -123,7 +128,7 @@ class CursorWrapper(object):
except Database.OperationalError as e:
# Map some error codes to IntegrityError, since they seem to be
# misclassified and Django would prefer the more logical place.
if e[0] in self.codes_for_integrityerror:
if e.args[0] in self.codes_for_integrityerror:
six.reraise(utils.IntegrityError, utils.IntegrityError(*tuple(e.args)), sys.exc_info()[2])
raise
@ -133,7 +138,7 @@ class CursorWrapper(object):
except Database.OperationalError as e:
# Map some error codes to IntegrityError, since they seem to be
# misclassified and Django would prefer the more logical place.
if e[0] in self.codes_for_integrityerror:
if e.args[0] in self.codes_for_integrityerror:
six.reraise(utils.IntegrityError, utils.IntegrityError(*tuple(e.args)), sys.exc_info()[2])
raise
@ -190,6 +195,15 @@ class DatabaseFeatures(BaseDatabaseFeatures):
@cached_property
def has_zoneinfo_database(self):
# MySQL accepts full time zones names (eg. Africa/Nairobi) but rejects
# abbreviations (eg. EAT). When pytz isn't installed and the current
# time zone is LocalTimezone (the only sensible value in this
# context), the current time zone name will be an abbreviation. As a
# consequence, MySQL cannot perform time zone conversions reliably.
if pytz is None:
return False
# Test if the time zone definitions are installed.
cursor = self.connection.cursor()
cursor.execute("SELECT 1 FROM mysql.time_zone LIMIT 1")
return cursor.fetchone() is not None
@ -395,8 +409,9 @@ class DatabaseWrapper(BaseDatabaseWrapper):
kwargs = {
'conv': django_conversions,
'charset': 'utf8',
'use_unicode': True,
}
if not six.PY3:
kwargs['use_unicode'] = True
settings_dict = self.settings_dict
if settings_dict['USER']:
kwargs['user'] = settings_dict['USER']

View File

@ -10,6 +10,7 @@ class DatabaseValidation(BaseDatabaseValidation):
from django.db import models
varchar_fields = (models.CharField, models.CommaSeparatedIntegerField,
models.SlugField)
if isinstance(f, varchar_fields) and f.max_length > 255 and f.unique:
if (isinstance(f, varchar_fields) and f.unique
and (f.max_length is None or int(f.max_length) > 255)):
msg = '"%(name)s": %(cls)s cannot have a "max_length" greater than 255 when using "unique=True".'
errors.add(opts, msg % {'name': f.name, 'cls': f.__class__.__name__})

View File

@ -1,3 +1,5 @@
from functools import wraps
from django.core.exceptions import ObjectDoesNotExist, ImproperlyConfigured
from django.db.models.loading import get_apps, get_app, get_models, get_model, register_models
from django.db.models.query import Q
@ -11,7 +13,6 @@ from django.db.models.fields.files import FileField, ImageField
from django.db.models.fields.related import ForeignKey, ForeignObject, OneToOneField, ManyToManyField, ManyToOneRel, ManyToManyRel, OneToOneRel
from django.db.models.deletion import CASCADE, PROTECT, SET, SET_NULL, SET_DEFAULT, DO_NOTHING, ProtectedError
from django.db.models import signals
from django.utils.decorators import wraps
def permalink(func):

View File

@ -204,9 +204,6 @@ class SingleRelatedObjectDescriptor(six.with_metaclass(RenameRelatedObjectDescri
return rel_obj
def __set__(self, instance, value):
if instance is None:
raise AttributeError("%s must be accessed via instance" % self.related.opts.object_name)
# The similarity of the code below to the code in
# ReverseSingleRelatedObjectDescriptor is annoying, but there's a bunch
# of small differences that would make a common base class convoluted.
@ -310,9 +307,6 @@ class ReverseSingleRelatedObjectDescriptor(six.with_metaclass(RenameRelatedObjec
return rel_obj
def __set__(self, instance, value):
if instance is None:
raise AttributeError("%s must be accessed via instance" % self.field.name)
# If null=True, we can assign null here, but otherwise the value needs
# to be an instance of the related class.
if value is None and self.field.null == False:
@ -382,9 +376,6 @@ class ForeignRelatedObjectsDescriptor(object):
return self.related_manager_cls(instance)
def __set__(self, instance, value):
if instance is None:
raise AttributeError("Manager must be accessed via instance")
manager = self.__get__(instance)
# If the foreign key can support nulls, then completely clear the related set.
# Otherwise, just move the named objects into the set.
@ -765,9 +756,6 @@ class ManyRelatedObjectsDescriptor(object):
return manager
def __set__(self, instance, value):
if instance is None:
raise AttributeError("Manager must be accessed via instance")
if not self.related.field.rel.through._meta.auto_created:
opts = self.related.field.rel.through._meta
raise AttributeError("Cannot set values on a ManyToManyField which specifies an intermediary model. Use %s.%s's Manager instead." % (opts.app_label, opts.object_name))
@ -822,9 +810,6 @@ class ReverseManyRelatedObjectsDescriptor(object):
return manager
def __set__(self, instance, value):
if instance is None:
raise AttributeError("Manager must be accessed via instance")
if not self.field.rel.through._meta.auto_created:
opts = self.field.rel.through._meta
raise AttributeError("Cannot set values on a ManyToManyField which specifies an intermediary model. Use %s.%s's Manager instead." % (opts.app_label, opts.object_name))

View File

@ -312,11 +312,7 @@ class QuerySet(object):
if skip:
obj = model_cls(**dict(zip(init_list, row_data)))
else:
try:
obj = model(*row_data)
except IndexError:
import ipdb; ipdb.set_trace()
pass
obj = model(*row_data)
# Store the source database of the object
obj._state.db = db

View File

@ -102,7 +102,7 @@ class DeferredAttribute(object):
f = [f for f in opts.fields
if f.attname == self.field_name][0]
name = f.name
# Lets see if the field is part of the parent chain. If so we
# Let's see if the field is part of the parent chain. If so we
# might be able to reuse the already loaded value. Refs #18343.
val = self._check_parent_chain(instance, name)
if val is None:
@ -194,8 +194,7 @@ def deferred_class_factory(model, attrs):
name = "%s_Deferred_%s" % (model.__name__, '_'.join(sorted(list(attrs))))
name = util.truncate_name(name, 80, 32)
overrides = dict([(attr, DeferredAttribute(attr, model))
for attr in attrs])
overrides = dict((attr, DeferredAttribute(attr, model)) for attr in attrs)
overrides["Meta"] = Meta
overrides["__module__"] = model.__module__
overrides["_deferred"] = True

View File

@ -1092,7 +1092,7 @@ class SQLDateTimeCompiler(SQLCompiler):
if datetime is None:
raise ValueError("Database returned an invalid value "
"in QuerySet.dates(). Are time zone "
"definitions installed?")
"definitions and pytz installed?")
datetime = datetime.replace(tzinfo=None)
datetime = timezone.make_aware(datetime, self.query.tzinfo)
yield datetime

View File

@ -169,7 +169,7 @@ class ConnectionHandler(object):
conn.setdefault('ENGINE', 'django.db.backends.dummy')
if conn['ENGINE'] == 'django.db.backends.' or not conn['ENGINE']:
conn['ENGINE'] = 'django.db.backends.dummy'
conn.setdefault('CONN_MAX_AGE', 600)
conn.setdefault('CONN_MAX_AGE', 0)
conn.setdefault('OPTIONS', {})
conn.setdefault('TIME_ZONE', 'UTC' if settings.USE_TZ else settings.TIME_ZONE)
for setting in ['NAME', 'USER', 'PASSWORD', 'HOST', 'PORT']:

View File

@ -9,7 +9,7 @@ from django.utils.encoding import python_2_unicode_compatible
from django.utils.safestring import mark_safe
from django.utils import six
from django.utils.six.moves import xrange
from django.utils.translation import ugettext as _
from django.utils.translation import ungettext, ugettext as _
__all__ = ('BaseFormSet', 'all_valid')
@ -302,7 +302,9 @@ class BaseFormSet(object):
try:
if (self.validate_max and self.total_form_count() > self.max_num) or \
self.management_form.cleaned_data[TOTAL_FORM_COUNT] > self.absolute_max:
raise ValidationError(_("Please submit %s or fewer forms." % self.max_num))
raise ValidationError(ungettext(
"Please submit %d or fewer forms.",
"Please submit %d or fewer forms.", self.max_num) % self.max_num)
# Give self.clean() a chance to do cross-form validation.
self.clean()
except ValidationError as e:

View File

@ -5,6 +5,8 @@ and database field objects.
from __future__ import absolute_import, unicode_literals
import warnings
from django.core.exceptions import ValidationError, NON_FIELD_ERRORS, FieldError
from django.forms.fields import Field, ChoiceField
from django.forms.forms import BaseForm, get_declared_fields
@ -22,8 +24,12 @@ from django.utils.translation import ugettext_lazy as _, ugettext
__all__ = (
'ModelForm', 'BaseModelForm', 'model_to_dict', 'fields_for_model',
'save_instance', 'ModelChoiceField', 'ModelMultipleChoiceField',
'ALL_FIELDS',
)
ALL_FIELDS = '__all__'
def construct_instance(form, instance, fields=None, exclude=None):
"""
Constructs and returns a model instance from the bound ``form``'s
@ -211,7 +217,7 @@ class ModelFormMetaclass(type):
# of ('foo',)
for opt in ['fields', 'exclude']:
value = getattr(opts, opt)
if isinstance(value, six.string_types):
if isinstance(value, six.string_types) and value != ALL_FIELDS:
msg = ("%(model)s.Meta.%(opt)s cannot be a string. "
"Did you mean to type: ('%(value)s',)?" % {
'model': new_class.__name__,
@ -222,6 +228,20 @@ class ModelFormMetaclass(type):
if opts.model:
# If a model is defined, extract form fields from it.
if opts.fields is None and opts.exclude is None:
# This should be some kind of assertion error once deprecation
# cycle is complete.
warnings.warn("Creating a ModelForm without either the 'fields' attribute "
"or the 'exclude' attribute is deprecated - form %s "
"needs updating" % name,
PendingDeprecationWarning)
if opts.fields == ALL_FIELDS:
# sentinel for fields_for_model to indicate "get the list of
# fields from the model"
opts.fields = None
fields = fields_for_model(opts.model, opts.fields,
opts.exclude, opts.widgets, formfield_callback)
# make sure opts.fields doesn't specify an invalid field
@ -394,7 +414,8 @@ def modelform_factory(model, form=ModelForm, fields=None, exclude=None,
Returns a ModelForm containing form fields for the given model.
``fields`` is an optional list of field names. If provided, only the named
fields will be included in the returned fields.
fields will be included in the returned fields. If omitted or '__all__',
all fields will be used.
``exclude`` is an optional list of field names. If provided, the named
fields will be excluded from the returned fields, even if they are listed
@ -434,6 +455,15 @@ def modelform_factory(model, form=ModelForm, fields=None, exclude=None,
'formfield_callback': formfield_callback
}
# The ModelFormMetaclass will trigger a similar warning/error, but this will
# be difficult to debug for code that needs updating, so we produce the
# warning here too.
if (getattr(Meta, 'fields', None) is None and
getattr(Meta, 'exclude', None) is None):
warnings.warn("Calling modelform_factory without defining 'fields' or "
"'exclude' explicitly is deprecated",
PendingDeprecationWarning, stacklevel=2)
# Instatiate type(form) in order to use the same metaclass as form.
return type(form)(class_name, (form,), form_class_attrs)
@ -701,6 +731,21 @@ def modelformset_factory(model, form=ModelForm, formfield_callback=None,
"""
Returns a FormSet class for the given Django model class.
"""
# modelform_factory will produce the same warning/error, but that will be
# difficult to debug for code that needs upgrading, so we produce the
# warning here too. This logic is reproducing logic inside
# modelform_factory, but it can be removed once the deprecation cycle is
# complete, since the validation exception will produce a helpful
# stacktrace.
meta = getattr(form, 'Meta', None)
if meta is None:
meta = type(str('Meta'), (object,), {})
if (getattr(meta, 'fields', fields) is None and
getattr(meta, 'exclude', exclude) is None):
warnings.warn("Calling modelformset_factory without defining 'fields' or "
"'exclude' explicitly is deprecated",
PendingDeprecationWarning, stacklevel=2)
form = modelform_factory(model, form=form, fields=fields, exclude=exclude,
formfield_callback=formfield_callback,
widgets=widgets)
@ -1091,3 +1136,11 @@ class ModelMultipleChoiceField(ModelChoiceField):
initial_set = set([force_text(value) for value in self.prepare_value(initial)])
data_set = set([force_text(value) for value in data])
return data_set != initial_set
def modelform_defines_fields(form_class):
return (form_class is not None and (
hasattr(form_class, '_meta') and
(form_class._meta.fields is not None or
form_class._meta.exclude is not None)
))

View File

@ -1,5 +1,6 @@
import re
import warnings
from functools import wraps
from xml.dom.minidom import parseString, Node
from django.conf import settings, UserSettingsHolder
@ -10,7 +11,6 @@ from django.template import Template, loader, TemplateDoesNotExist
from django.template.loaders import cached
from django.test.signals import template_rendered, setting_changed
from django.utils.encoding import force_str
from django.utils.functional import wraps
from django.utils import six
from django.utils.translation import deactivate

View File

@ -14,13 +14,19 @@ class MergeDict(object):
def __init__(self, *dicts):
self.dicts = dicts
def __bool__(self):
return any(self.dicts)
def __nonzero__(self):
return type(self).__bool__(self)
def __getitem__(self, key):
for dict_ in self.dicts:
try:
return dict_[key]
except KeyError:
pass
raise KeyError
raise KeyError(key)
def __copy__(self):
return self.__class__(*self.dicts)

View File

@ -346,6 +346,7 @@ class SimpleLazyObject(LazyObject):
# care about this (especially in equality tests)
__class__ = property(new_method_proxy(operator.attrgetter("__class__")))
__eq__ = new_method_proxy(operator.eq)
__ne__ = new_method_proxy(operator.ne)
__hash__ = new_method_proxy(hash)
__bool__ = new_method_proxy(bool) # Python 3
__nonzero__ = __bool__ # Python 2

View File

@ -1,3 +1,5 @@
import warnings
from django.forms import models as model_forms
from django.core.exceptions import ImproperlyConfigured
from django.http import HttpResponseRedirect
@ -95,7 +97,14 @@ class ModelFormMixin(FormMixin, SingleObjectMixin):
# Try to get a queryset and extract the model class
# from that
model = self.get_queryset().model
return model_forms.modelform_factory(model)
fields = getattr(self, 'fields', None)
if fields is None:
warnings.warn("Using ModelFormMixin (base class of %s) without "
"the 'fields' attribute is deprecated." % self.__class__.__name__,
PendingDeprecationWarning)
return model_forms.modelform_factory(model, fields=fields)
def get_form_kwargs(self):
"""

View File

@ -6,7 +6,7 @@ from django import http
from django.conf import settings
from django.template import Context, Template
from django.utils import importlib
from django.utils.translation import check_for_language, activate, to_locale, get_language
from django.utils.translation import check_for_language, to_locale, get_language
from django.utils.encoding import smart_text
from django.utils.formats import get_format_modules, get_format
from django.utils._os import upath
@ -205,17 +205,18 @@ def javascript_catalog(request, domain='djangojs', packages=None):
go to the djangojs domain. But this might be needed if you
deliver your JavaScript source from Django templates.
"""
if request.GET:
if 'language' in request.GET:
if check_for_language(request.GET['language']):
activate(request.GET['language'])
default_locale = to_locale(settings.LANGUAGE_CODE)
locale = to_locale(get_language())
if request.GET and 'language' in request.GET:
if check_for_language(request.GET['language']):
locale = to_locale(request.GET['language'])
if packages is None:
packages = ['django.conf']
if isinstance(packages, six.string_types):
packages = packages.split('+')
packages = [p for p in packages if p == 'django.conf' or p in settings.INSTALLED_APPS]
default_locale = to_locale(settings.LANGUAGE_CODE)
locale = to_locale(get_language())
t = {}
paths = []
en_selected = locale.startswith('en')

View File

@ -5,9 +5,7 @@ import json
import os
import re
from docutils import nodes, transforms
from sphinx import addnodes, roles, __version__ as sphinx_ver
from sphinx import addnodes, __version__ as sphinx_ver
from sphinx.builders.html import StandaloneHTMLBuilder
from sphinx.writers.html import SmartyPantsHTMLTranslator
from sphinx.util.console import bold
@ -64,21 +62,25 @@ class VersionDirective(Directive):
option_spec = {}
def run(self):
if len(self.arguments) > 1:
msg = """Only one argument accepted for directive '{directive_name}::'.
Comments should be provided as content,
not as an extra argument.""".format(directive_name=self.name)
raise self.error(msg)
env = self.state.document.settings.env
ret = []
node = addnodes.versionmodified()
ret.append(node)
if self.arguments[0] == env.config.django_next_version:
node['version'] = "Development version"
else:
node['version'] = self.arguments[0]
node['type'] = self.name
if len(self.arguments) == 2:
inodes, messages = self.state.inline_text(self.arguments[1], self.lineno+1)
node.extend(inodes)
if self.content:
self.state.nested_parse(self.content, self.content_offset, node)
ret = ret + messages
if self.content:
self.state.nested_parse(self.content, self.content_offset, node)
env.note_versionchange(node['type'], node['version'], node, self.lineno)
return ret

View File

@ -256,7 +256,7 @@ All attributes can be set in your derived class and can be used in
.. versionadded:: 1.6
The ``leave_locale_alone`` option was added in Django 1.6.
The ``leave_locale_alone`` option was added in Django 1.6.
Methods
-------

View File

@ -157,6 +157,15 @@ Performance optimizations
Setting :setting:`DEBUG = False <DEBUG>` disables several features that are
only useful in development. In addition, you can tune the following settings.
:setting:`CONN_MAX_AGE`
-----------------------
Enabling `persistent database connections <persistent-database-connections>`_
can result in a nice speed-up when connecting to the database accounts for a
significant part of the request processing time.
This helps a lot on virtualized hosts with limited network performance.
:setting:`TEMPLATE_LOADERS`
---------------------------

View File

@ -112,7 +112,7 @@ Running a preforked server on a Unix domain socket::
.. admonition:: Socket security
Django's default umask requires that the webserver and the Django fastcgi
Django's default umask requires that the web server and the Django fastcgi
process be run with the same group **and** user. For increased security,
you can run them under the same group but as different users. If you do
this, you will need to set the umask to 0002 using the ``umask`` argument

View File

@ -61,7 +61,7 @@ this generated model definition:
class Person(models.Model):
id = models.IntegerField(primary_key=True)
first_name = models.ChaField(max_length=70)
first_name = models.CharField(max_length=70)
class Meta:
**managed = False**
db_table = 'CENSUS_PERSONS'
@ -75,8 +75,8 @@ access to your precious data on a model by model basis.
.. versionchanged:: 1.6
The behavior by which introspected models are created as unmanaged ones is new
in Django 1.6.
The behavior by which introspected models are created as unmanaged ones is new
in Django 1.6.
Install the core Django tables
==============================

View File

@ -32,7 +32,7 @@ Configuring static files
{% load staticfiles %}
<img src="{% static "my_app/myexample.jpg" %}" alt="My image"/>
3. Store your static files in a folder called ``static`` in your app. For
4. Store your static files in a folder called ``static`` in your app. For
example ``my_app/static/my_app/myimage.jpg``.
Now, if you use ``./manage.py runserver``, all static files should be served
@ -106,7 +106,7 @@ for gathering static files in a single directory so you can serve them easily.
This will copy all files from your static folders into the
:setting:`STATIC_ROOT` directory.
3. Use a webserver of your choice to serve the
3. Use a web server of your choice to serve the
files. :doc:`/howto/static-files/deployment` covers some common deployment
strategies for static files.

View File

@ -15,7 +15,7 @@ Journal-World`_ of Lawrence, Kansas, USA.
He was lead developer at World Online for 2.5 years, during which time
Django was developed and implemented on World Online's sites. He was the
leader and founder of EveryBlock_, a "news feed for your block." He now
leader and founder of EveryBlock_, a "news feed for your block." He now
develops for Soundslice_.
Adrian lives in Chicago, USA.
@ -41,7 +41,7 @@ Journal-World`_ of Lawrence, Kansas, USA.
`Wilson Miner`_
Wilson's design-fu is what makes Django look so nice. He designed the
Web site you're looking at right now, as well as Django's acclaimed admin
interface. Wilson was the designer for EveryBlock and Rdio_. He now
interface. Wilson was the designer for EveryBlock and Rdio_. He now
designs for Facebook.
Wilson lives in San Francisco, USA.
@ -105,8 +105,8 @@ Malcolm Tredinnick
.. _russell keith-magee: http://cecinestpasun.com/
Joseph Kocherhans
Joseph was the director of lead development at EveryBlock and previously
developed at the Lawrence Journal-World. He is treasurer of the `Django
Joseph was the director of lead development at EveryBlock and previously
developed at the Lawrence Journal-World. He is treasurer of the `Django
Software Foundation`_. He often disappears for several days into the woods,
attempts to teach himself computational linguistics, and annoys his
neighbors with his Charango_ playing.
@ -386,17 +386,17 @@ Florian Apolloner
.. _Ubuntuusers webteam: http://wiki.ubuntuusers.de/ubuntuusers/Webteam
Jeremy Dunck
Jeremy was rescued from corporate IT drudgery by Free Software and, in part,
Jeremy was rescued from corporate IT drudgery by Free Software and, in part,
Django. Many of Jeremy's interests center around access to information.
Jeremy was the lead developer of Pegasus News, one of the first uses of
Django outside World Online, and has since joined Votizen, a startup intent
Jeremy was the lead developer of Pegasus News, one of the first uses of
Django outside World Online, and has since joined Votizen, a startup intent
on reducing the influence of money in politics.
He serves as DSF Secretary, organizes and helps organize sprints, cares
about the health and equity of the Django community. He has gone an
He serves as DSF Secretary, organizes and helps organize sprints, cares
about the health and equity of the Django community. He has gone an
embarrassingly long time without a working blog.
Jeremy lives in Mountain View, CA, USA.
`Bryan Veloso`_
@ -441,6 +441,20 @@ Jeremy Dunck
.. _Ultimate Frisbee: http://www.montrealultimate.ca
.. _Reptiletech: http://www.reptiletech.com
`Daniel Lindsley`_
Pythonista since 2003, Djangonaut since 2006. Daniel started with Django
just after the v0.90 release (back when ``Manipulators`` looked good) & fell
in love. Since then, he wrote third-party apps like Haystack & Tastypie
& has run the annual Django Dash since 2007. One of the testing faithful,
Daniel's contributions include rewriting the ``Forms`` test suite & the
addition of ``request.is_ajax``. Daniel currently works as a Python
developer at `Amazon Web Services`_ on the ``boto`` library.
Daniel lives in Seattle, WA, USA.
.. _`Daniel Lindsley`: http://toastdriven.com/
.. _`Amazon Web Services`: https://aws.amazon.com/
Specialists
-----------

View File

@ -62,5 +62,5 @@ Django source tree, as for any code change:
.. _Transifex: https://www.transifex.com/
.. _Django i18n mailing list: http://groups.google.com/group/django-i18n/
.. _Django project page: https://www.transifex.com/projects/p/django/
.. _Django project page: https://www.transifex.com/projects/p/django-core/
.. _Transifex User Guide: http://help.transifex.com/

View File

@ -188,8 +188,8 @@ Our policy for new features is:
release, not the development version.
Our preferred way for marking new features is by prefacing the features'
documentation with: "``.. versionadded:: X.Y``", followed by an optional one
line comment and a mandatory blank line.
documentation with: "``.. versionadded:: X.Y``", followed by a a mandatory
blank line and an optional content (indented).
General improvements, or other changes to the APIs that should be emphasized
should use the "``.. versionchanged:: X.Y``" directive (with the same format

View File

@ -175,13 +175,13 @@ OK, this is the fun part, where we actually push out a release!
#. Make sure you have an absolutely clean tree by running ``git clean -dfx``.
#. Run ``python setup.py sdist`` to generate the release package. This will
create the release package in a ``dist/`` directory.
#. Run ``make -f extras/Makefile`` to generate the release packages. This will
create the release packages in a ``dist/`` directory.
#. Generate the hashes of the release package::
#. Generate the hashes of the release packages::
$ md5sum dist/Django-<version>.tar.gz
$ sha1sum dist/Django-<version>.tar.gz
$ md5sum dist/Django-*
$ sha1sum dist/Django-*
*FIXME: perhaps we should switch to sha256?*
@ -221,6 +221,9 @@ Now you're ready to actually put the release out there. To do this:
$ mktmpenv
$ pip install https://www.djangoproject.com/m/releases/1.5/Django-1.5.1.tar.gz
$ deactivate
$ mktmpenv
$ pip install https://www.djangoproject.com/m/releases/1.5/Django-1.5.1-py2.py3-none-any.whl
$ deactivate
This just tests that the tarballs are available (i.e. redirects are up) and
that they install correctly, but it'll catch silly mistakes.

View File

@ -389,8 +389,8 @@ This is a new feature, so it should be documented. Add the following on line
.. versionadded:: 1.5
The current value of the field will be displayed as a clickable link above the
input widget.
The current value of the field will be displayed as a clickable link above the
input widget.
For more information on writing documentation, including an explanation of what
the ``versionadded`` bit is all about, see

View File

@ -66,16 +66,17 @@ After the previous tutorials, our project should look like this::
__init__.py
admin.py
models.py
tests.py
static/
style.css
images/
background.gif
polls
images/
background.gif
style.css
templates/
polls/
detail.html
index.html
results.html
tests.py
urls.py
views.py
templates/
@ -129,7 +130,7 @@ this. For a small app like polls, this process isn't too difficult.
2. Move the ``polls`` directory into the ``django-polls`` directory.
3. Create a file ``django-polls/README.txt`` with the following contents::
3. Create a file ``django-polls/README.rst`` with the following contents::
=====
Polls
@ -157,7 +158,7 @@ this. For a small app like polls, this process isn't too difficult.
3. Run `python manage.py syncdb` to create the polls models.
4. Start the development server and visit http://127.0.0.1:8000/admin/
to create a poll (you'll need the Admin app enabled).
to create a poll (you'll need the Admin app enabled).
5. Visit http://127.0.0.1:8000/polls/ to participate in the poll.
@ -177,23 +178,23 @@ Create a file ``django-polls/setup.py`` with the following contents::
import os
from setuptools import setup
README = open(os.path.join(os.path.dirname(__file__), 'README.txt')).read()
README = open(os.path.join(os.path.dirname(__file__), 'README.rst')).read()
# allow setup.py to be run from any path
os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir)))
setup(
name = 'django-polls',
version = '0.1',
packages = ['polls'],
include_package_data = True,
license = 'BSD License', # example license
description = 'A simple Django app to conduct Web-based polls.',
long_description = README,
url = 'http://www.example.com/',
author = 'Your Name',
author_email = 'yourname@example.com',
classifiers = [
name='django-polls',
version='0.1',
packages=['polls'],
include_package_data=True,
license='BSD License', # example license
description='A simple Django app to conduct Web-based polls.',
long_description=README,
url='http://www.example.com/',
author='Your Name',
author_email='yourname@example.com',
classifiers=[
'Environment :: Web Environment',
'Framework :: Django',
'Intended Audience :: Developers',
@ -216,10 +217,13 @@ Create a file ``django-polls/setup.py`` with the following contents::
6. Only Python modules and packages are included in the package by default. To
include additional files, we'll need to create a ``MANIFEST.in`` file. The
distribute docs referred to in the previous step discuss this file in more
details. To include the templates and our LICENSE file, create a file
``django-polls/MANIFEST.in`` with the following contents::
details. To include the templates, the ``README.rst`` and our ``LICENSE``
file, create a file ``django-polls/MANIFEST.in`` with the following
contents::
include LICENSE
include README.rst
recursive-include polls/static *
recursive-include polls/templates *
7. It's optional, but recommended, to include detailed documentation with your

View File

@ -23,7 +23,8 @@ If Django is installed, you should see the version of your installation. If it
isn't, you'll get an error telling "No module named django".
This tutorial is written for Django |version| and Python 2.x. If the Django
version doesn't match, you can refer to the tutorial for your version of Django
version doesn't match, you can refer to the tutorial for your version of
Django by using the version switcher at the bottom right corner of this page,
or update Django to the newest version. If you are using Python 3.x, be aware
that your code may need to differ from what is in the tutorial and you should
continue using the tutorial only if you know what you are doing with Python
@ -122,7 +123,7 @@ These files are:
"table of contents" of your Django-powered site. You can read more about
URLs in :doc:`/topics/http/urls`.
* :file:`mysite/wsgi.py`: An entry-point for WSGI-compatible webservers to
* :file:`mysite/wsgi.py`: An entry-point for WSGI-compatible web servers to
serve your project. See :doc:`/howto/deployment/wsgi/index` for more details.
.. _more about packages: http://docs.python.org/tutorial/modules.html#packages
@ -242,9 +243,6 @@ come with Django:
* :mod:`django.contrib.sessions` -- A session framework.
* :mod:`django.contrib.sites` -- A framework for managing multiple sites
with one Django installation.
* :mod:`django.contrib.messages` -- A messaging framework.
* :mod:`django.contrib.staticfiles` -- A framework for managing
@ -252,7 +250,7 @@ come with Django:
These applications are included by default as a convenience for the common case.
Each of these applications makes use of at least one database table, though,
Some of these applications makes use of at least one database table, though,
so we need to create the tables in the database before we can use them. To do
that, run the following command:
@ -581,27 +579,32 @@ Wait a minute. ``<Poll: Poll object>`` is, utterly, an unhelpful representation
of this object. Let's fix that by editing the polls model (in the
``polls/models.py`` file) and adding a
:meth:`~django.db.models.Model.__unicode__` method to both ``Poll`` and
``Choice``::
``Choice``. On Python 3, simply replace ``__unicode__`` by ``__str__`` in the
following example::
class Poll(models.Model):
# ...
def __unicode__(self):
def __unicode__(self): # Python 3: def __str__(self):
return self.question
class Choice(models.Model):
# ...
def __unicode__(self):
def __unicode__(self): # Python 3: def __str__(self):
return self.choice_text
It's important to add :meth:`~django.db.models.Model.__unicode__` methods to
your models, not only for your own sanity when dealing with the interactive
prompt, but also because objects' representations are used throughout Django's
automatically-generated admin.
It's important to add :meth:`~django.db.models.Model.__unicode__` methods (or
:meth:`~django.db.models.Model.__str__` on Python 3) to your models, not only
for your own sanity when dealing with the interactive prompt, but also because
objects' representations are used throughout Django's automatically-generated
admin.
.. admonition:: Why :meth:`~django.db.models.Model.__unicode__` and not
:meth:`~django.db.models.Model.__str__`?
.. admonition:: `__unicode__` or `__str__`?
If you're familiar with Python, you might be in the habit of adding
On Python 3, things are simpler, just use
:meth:`~django.db.models.Model.__str__` and forget about
:meth:`~django.db.models.Model.__unicode__`.
If you're familiar with Python 2, you might be in the habit of adding
:meth:`~django.db.models.Model.__str__` methods to your classes, not
:meth:`~django.db.models.Model.__unicode__` methods. We use
:meth:`~django.db.models.Model.__unicode__` here because Django models deal

View File

@ -15,9 +15,9 @@ What are automated tests?
Tests are simple routines that check the operation of your code.
Testing operates at different levels. Some tests might apply to a tiny detail
- *does a particular model method return values as expected?*, while others
examine the overall operation of the software - *does a sequence of user inputs
on the site produce the desired result?* That's no different from the kind of
(*does a particular model method return values as expected?*) while others
examine the overall operation of the software (*does a sequence of user inputs
on the site produce the desired result?*). That's no different from the kind of
testing you did earlier in :doc:`Tutorial 1 </intro/tutorial01>`, using the
shell to examine the behavior of a method, or running the application and
entering data to check how it behaves.
@ -326,6 +326,13 @@ in the shell::
>>> from django.test.utils import setup_test_environment
>>> setup_test_environment()
:meth:`~django.test.utils.setup_test_environment` installs a template renderer
which will allow us to examine some additional attributes on responses such as
``response.context`` that otherwise wouldn't be available. Note that this
method *does not* setup a test database, so the following will be run against
the existing database and the output may differ slightly depending on what
polls you already created.
Next we need to import the test client class (later in ``tests.py`` we will use
the :class:`django.test.TestCase` class, which comes with its own client, so
this won't be required)::

View File

@ -108,7 +108,7 @@ loaded in the bottom right of the screen.
These are the **basics**. For more details on settings and other bits included
with the framework see
:doc:`the static files howto </howto/static-files/index>` and the
:doc:`the static files howto </howto/static-files/index>` and
:doc:`the staticfiles reference </ref/contrib/staticfiles>`. :doc:`Deploying
static files </howto/static-files/deployment>` discusses how to use static
files on a real server.

View File

@ -105,6 +105,7 @@ TemplateView
in the URL.
.. versionchanged:: 1.5
The context used to be populated with a ``{{ params }}`` dictionary of
the parameters captured in the URL. Now those parameters are first-level
context variables.

View File

@ -142,7 +142,7 @@ YearArchiveView
.. versionchanged:: 1.5
Previously, this returned a string.
Previously, this returned a string.
* ``next_year``: A :class:`~datetime.date` object
representing the first day of the next year, according to

View File

@ -110,6 +110,7 @@ CreateView
class AuthorCreate(CreateView):
model = Author
fields = ['name']
UpdateView
----------
@ -152,6 +153,7 @@ UpdateView
class AuthorUpdate(UpdateView):
model = Author
fields = ['name']
DeleteView
----------

View File

@ -330,5 +330,6 @@ BaseDateListView
:meth:`QuerySet.dates()<django.db.models.query.QuerySet.dates>`.
.. versionchanged:: 1.5
The ``ordering`` parameter was added, and the default order was
changed to ascending.

View File

@ -116,6 +116,18 @@ ModelFormMixin
by examining ``self.object`` or
:attr:`~django.views.generic.detail.SingleObjectMixin.queryset`.
.. attribute:: fields
.. versionadded:: 1.6
A list of names of fields. This is interpreted the same way as the
``Meta.fields`` attribute of :class:`~django.forms.ModelForm`.
This is a required attribute if you are generating the form class
automatically (e.g. using ``model``). Omitting this attribute will
result in all fields being used, but this behaviour is deprecated
and will be removed in Django 1.8.
.. attribute:: success_url
The URL to redirect to when the form is successfully processed.
@ -206,10 +218,10 @@ ProcessFormView
.. versionadded:: 1.6
``success_url`` may contain dictionary string formatting, which
will be interpolated against the object's field attributes. For
example, you could use ``success_url="/parent/%(parent_id)s/"`` to
redirect to a URL composed out of the ``parent_id`` field on a model.
``success_url`` may contain dictionary string formatting, which
will be interpolated against the object's field attributes. For
example, you could use ``success_url="/parent/%(parent_id)s/"`` to
redirect to a URL composed out of the ``parent_id`` field on a model.
.. method:: get_success_url()

View File

@ -67,7 +67,6 @@ TemplateResponseMixin
.. attribute:: content_type
.. versionadded:: 1.5
The ``content_type`` attribute was added.
The content type to use for the response. ``content_type`` is passed
as a keyword argument to ``response_class``. Default is ``None`` --

View File

@ -62,6 +62,7 @@ To set the same ``X-Frame-Options`` value for all responses in your site, put
)
.. versionchanged:: 1.6
This middleware is enabled in the settings file generated by
:djadmin:`startproject`.

View File

@ -18,6 +18,7 @@ The admin is enabled in the default project template used by
:djadmin:`startproject`.
.. versionchanged:: 1.6
In previous versions, the admin wasn't enabled by default.
For reference, here are the requirements:
@ -334,6 +335,22 @@ subclass::
For an example see the section `Adding custom validation to the admin`_.
.. admonition:: Note
.. versionchanged:: 1.6
If you define the ``Meta.model`` attribute on a
:class:`~django.forms.ModelForm`, you must also define the
``Meta.fields`` attribute (or the ``Meta.exclude`` attribute). However,
since the admin has its own way of defining fields, the ``Meta.fields``
attribute will be ignored.
If the ``ModelForm`` is only going to be used for the admin, the easiest
solution is to omit the ``Meta.model`` attribute, since ``ModelAdmin``
will provide the correct model to use. Alternatively, you can set
``fields = []`` in the ``Meta`` class to satisfy the validation on the
``ModelForm``.
.. admonition:: Note
If your ``ModelForm`` and ``ModelAdmin`` both define an ``exclude``
@ -1282,13 +1299,24 @@ templates used by the :class:`ModelAdmin` views:
on the changelist page. To use a custom form, for example::
class MyForm(forms.ModelForm):
class Meta:
model = MyModel
pass
class MyModelAdmin(admin.ModelAdmin):
def get_changelist_form(self, request, **kwargs):
return MyForm
.. admonition:: Note
.. versionchanged:: 1.6
If you define the ``Meta.model`` attribute on a
:class:`~django.forms.ModelForm`, you must also define the
``Meta.fields`` attribute (or the ``Meta.exclude`` attribute). However,
``ModelAdmin`` ignores this value, overriding it with the
:attr:`ModelAdmin.list_editable` attribute. The easiest solution is to
omit the ``Meta.model`` attribute, since ``ModelAdmin`` will provide the
correct model to use.
.. method:: ModelAdmin.get_changelist_formset(self, request, **kwargs)
Returns a :ref:`ModelFormSet <model-formsets>` class for use on the
@ -1341,6 +1369,7 @@ templates used by the :class:`ModelAdmin` views:
return qs.filter(author=request.user)
.. versionchanged:: 1.6
The ``get_queryset`` method was previously named ``queryset``.
.. method:: ModelAdmin.message_user(request, message, level=messages.INFO, extra_tags='', fail_silently=False)
@ -1348,7 +1377,9 @@ templates used by the :class:`ModelAdmin` views:
Sends a message to the user using the :mod:`django.contrib.messages`
backend. See the :ref:`custom ModelAdmin example <custom-admin-action>`.
.. versionadded:: 1.5
.. versionchanged:: 1.5
Keyword arguments were added in Django 1.5.
Keyword arguments allow you to change the message level, add extra CSS
tags, or fail silently if the ``contrib.messages`` framework is not
@ -1451,6 +1482,7 @@ in your own admin JavaScript without including a second copy, you can use the
``django.jQuery`` object on changelist and add/edit views.
.. versionchanged:: 1.6
The embedded jQuery has been upgraded from 1.4.2 to 1.9.1.
The :class:`ModelAdmin` class requires jQuery by default, so there is no need
@ -1485,9 +1517,6 @@ needed. Now within your form you can add your own custom validation for
any field::
class MyArticleAdminForm(forms.ModelForm):
class Meta:
model = Article
def clean_name(self):
# do something that validates your data
return self.cleaned_data["name"]

View File

@ -234,18 +234,18 @@ lookup::
.. versionadded:: 1.5
Prior to Django 1.5,
:meth:`~django.contrib.contenttypes.models.ContentTypeManager.get_for_model` and
:meth:`~django.contrib.contenttypes.models.ContentTypeManager.get_for_models`
always returned the :class:`~django.contrib.contenttypes.models.ContentType`
associated with the concrete model of the specified one(s). That means there
was no way to retrieve the
:class:`~django.contrib.contenttypes.models.ContentType` of a proxy model
using those methods. As of Django 1.5 you can now pass a boolean flag
``for_concrete_model`` and ``for_concrete_models`` respectively to specify
wether or not you want to retrieve the
:class:`~django.contrib.contenttypes.models.ContentType` for the concrete or
direct model.
Prior to Django 1.5,
:meth:`~django.contrib.contenttypes.models.ContentTypeManager.get_for_model` and
:meth:`~django.contrib.contenttypes.models.ContentTypeManager.get_for_models`
always returned the :class:`~django.contrib.contenttypes.models.ContentType`
associated with the concrete model of the specified one(s). That means there
was no way to retrieve the
:class:`~django.contrib.contenttypes.models.ContentType` of a proxy model
using those methods. As of Django 1.5 you can now pass a boolean flag
``for_concrete_model`` and ``for_concrete_models`` respectively to specify
wether or not you want to retrieve the
:class:`~django.contrib.contenttypes.models.ContentType` for the concrete or
direct model.
Generic relations
=================

View File

@ -950,6 +950,7 @@ __ http://geohash.org/
*Availability*: PostGIS, SpatiaLite
.. versionchanged:: 1.5
``geojson`` support for Spatialite > 3.0 has been added.
Attaches a ``geojson`` attribute to every model in the queryset that contains the

View File

@ -845,7 +845,7 @@ include the SRID value (in other words, EWKB).
.. class:: WKBWriter
``WKBWriter`` provides the most control over its output. By default it
returns OGC-compliant WKB when it's ``write`` method is called. However,
returns OGC-compliant WKB when its ``write`` method is called. However,
it has properties that allow for the creation of EWKB, a superset of the
WKB standard that includes additional information.

View File

@ -194,7 +194,7 @@ Configure, make and install::
.. note::
Because GeoDjango has it's own Python interface, the preceding instructions
Because GeoDjango has its own Python interface, the preceding instructions
do not build GDAL's own Python bindings. The bindings may be built by
adding the ``--with-python`` flag when running ``configure``. See
`GDAL/OGR In Python`__ for more information on GDAL's bindings.

View File

@ -252,6 +252,7 @@ Enabling the sites framework
============================
.. versionchanged:: 1.6
In previous versions, the sites framework was enabled by default.
To enable the sites framework, follow these steps:

Some files were not shown because too many files have changed in this diff Show More