Fixed #30400 -- Improved typography of user facing strings.
Thanks Claude Paroz for assistance with translations.
This commit is contained in:
parent
2b03e8e9e8
commit
42b9a23267
Binary file not shown.
|
@ -131,7 +131,7 @@ msgid "Added \"%(object)s\"."
|
|||
msgstr "Ajout de « %(object)s »."
|
||||
|
||||
#, python-format
|
||||
msgid "Changed \"%(object)s\" - %(changes)s"
|
||||
msgid "Changed “%(object)s” - %(changes)s"
|
||||
msgstr "Modification de « %(object)s » - %(changes)s"
|
||||
|
||||
#, python-format
|
||||
|
@ -142,7 +142,7 @@ msgid "LogEntry Object"
|
|||
msgstr "Objet de journal"
|
||||
|
||||
#, python-brace-format
|
||||
msgid "Added {name} \"{object}\"."
|
||||
msgid "Added {name} “{object}”."
|
||||
msgstr "Ajout de {name} « {object} »."
|
||||
|
||||
msgid "Added."
|
||||
|
@ -152,7 +152,7 @@ msgid "and"
|
|||
msgstr "et"
|
||||
|
||||
#, python-brace-format
|
||||
msgid "Changed {fields} for {name} \"{object}\"."
|
||||
msgid "Changed {fields} for {name} “{object}”."
|
||||
msgstr "Modification de {fields} pour l'objet {name} « {object} »."
|
||||
|
||||
#, python-brace-format
|
||||
|
@ -160,7 +160,7 @@ msgid "Changed {fields}."
|
|||
msgstr "Modification de {fields}."
|
||||
|
||||
#, python-brace-format
|
||||
msgid "Deleted {name} \"{object}\"."
|
||||
msgid "Deleted {name} “{object}”."
|
||||
msgstr "Suppression de {name} « {object} »."
|
||||
|
||||
msgid "No fields changed."
|
||||
|
|
|
@ -73,14 +73,14 @@ class LogEntry(models.Model):
|
|||
|
||||
def __str__(self):
|
||||
if self.is_addition():
|
||||
return gettext('Added "%(object)s".') % {'object': self.object_repr}
|
||||
return gettext('Added “%(object)s”.') % {'object': self.object_repr}
|
||||
elif self.is_change():
|
||||
return gettext('Changed "%(object)s" - %(changes)s') % {
|
||||
return gettext('Changed “%(object)s” — %(changes)s') % {
|
||||
'object': self.object_repr,
|
||||
'changes': self.get_change_message(),
|
||||
}
|
||||
elif self.is_deletion():
|
||||
return gettext('Deleted "%(object)s."') % {'object': self.object_repr}
|
||||
return gettext('Deleted “%(object)s.”') % {'object': self.object_repr}
|
||||
|
||||
return gettext('LogEntry Object')
|
||||
|
||||
|
@ -108,7 +108,7 @@ class LogEntry(models.Model):
|
|||
if 'added' in sub_message:
|
||||
if sub_message['added']:
|
||||
sub_message['added']['name'] = gettext(sub_message['added']['name'])
|
||||
messages.append(gettext('Added {name} "{object}".').format(**sub_message['added']))
|
||||
messages.append(gettext('Added {name} “{object}”.').format(**sub_message['added']))
|
||||
else:
|
||||
messages.append(gettext('Added.'))
|
||||
|
||||
|
@ -118,7 +118,7 @@ class LogEntry(models.Model):
|
|||
)
|
||||
if 'name' in sub_message['changed']:
|
||||
sub_message['changed']['name'] = gettext(sub_message['changed']['name'])
|
||||
messages.append(gettext('Changed {fields} for {name} "{object}".').format(
|
||||
messages.append(gettext('Changed {fields} for {name} “{object}”.').format(
|
||||
**sub_message['changed']
|
||||
))
|
||||
else:
|
||||
|
@ -126,7 +126,7 @@ class LogEntry(models.Model):
|
|||
|
||||
elif 'deleted' in sub_message:
|
||||
sub_message['deleted']['name'] = gettext(sub_message['deleted']['name'])
|
||||
messages.append(gettext('Deleted {name} "{object}".').format(**sub_message['deleted']))
|
||||
messages.append(gettext('Deleted {name} “{object}”.').format(**sub_message['deleted']))
|
||||
|
||||
change_message = ' '.join(msg[0].upper() + msg[1:] for msg in messages)
|
||||
return change_message or gettext('No fields changed.')
|
||||
|
|
|
@ -269,7 +269,7 @@ class BaseModelAdmin(metaclass=forms.MediaDefiningClass):
|
|||
form_field = db_field.formfield(**kwargs)
|
||||
if (isinstance(form_field.widget, SelectMultiple) and
|
||||
not isinstance(form_field.widget, (CheckboxSelectMultiple, AutocompleteSelectMultiple))):
|
||||
msg = _('Hold down "Control", or "Command" on a Mac, to select more than one.')
|
||||
msg = _('Hold down “Control”, or “Command” on a Mac, to select more than one.')
|
||||
help_text = form_field.help_text
|
||||
form_field.help_text = format_lazy('{} {}', help_text, msg) if help_text else msg
|
||||
return form_field
|
||||
|
@ -1202,7 +1202,7 @@ class ModelAdmin(BaseModelAdmin):
|
|||
"_saveasnew" in request.POST and self.save_as_continue and
|
||||
self.has_change_permission(request, obj)
|
||||
):
|
||||
msg = _('The {name} "{obj}" was added successfully.')
|
||||
msg = _('The {name} “{obj}” was added successfully.')
|
||||
if self.has_change_permission(request, obj):
|
||||
msg += ' ' + _('You may edit it again below.')
|
||||
self.message_user(request, format_html(msg, **msg_dict), messages.SUCCESS)
|
||||
|
@ -1216,7 +1216,7 @@ class ModelAdmin(BaseModelAdmin):
|
|||
|
||||
elif "_addanother" in request.POST:
|
||||
msg = format_html(
|
||||
_('The {name} "{obj}" was added successfully. You may add another {name} below.'),
|
||||
_('The {name} “{obj}” was added successfully. You may add another {name} below.'),
|
||||
**msg_dict
|
||||
)
|
||||
self.message_user(request, msg, messages.SUCCESS)
|
||||
|
@ -1226,7 +1226,7 @@ class ModelAdmin(BaseModelAdmin):
|
|||
|
||||
else:
|
||||
msg = format_html(
|
||||
_('The {name} "{obj}" was added successfully.'),
|
||||
_('The {name} “{obj}” was added successfully.'),
|
||||
**msg_dict
|
||||
)
|
||||
self.message_user(request, msg, messages.SUCCESS)
|
||||
|
@ -1266,7 +1266,7 @@ class ModelAdmin(BaseModelAdmin):
|
|||
}
|
||||
if "_continue" in request.POST:
|
||||
msg = format_html(
|
||||
_('The {name} "{obj}" was changed successfully. You may edit it again below.'),
|
||||
_('The {name} “{obj}” was changed successfully. You may edit it again below.'),
|
||||
**msg_dict
|
||||
)
|
||||
self.message_user(request, msg, messages.SUCCESS)
|
||||
|
@ -1276,7 +1276,7 @@ class ModelAdmin(BaseModelAdmin):
|
|||
|
||||
elif "_saveasnew" in request.POST:
|
||||
msg = format_html(
|
||||
_('The {name} "{obj}" was added successfully. You may edit it again below.'),
|
||||
_('The {name} “{obj}” was added successfully. You may edit it again below.'),
|
||||
**msg_dict
|
||||
)
|
||||
self.message_user(request, msg, messages.SUCCESS)
|
||||
|
@ -1289,7 +1289,7 @@ class ModelAdmin(BaseModelAdmin):
|
|||
|
||||
elif "_addanother" in request.POST:
|
||||
msg = format_html(
|
||||
_('The {name} "{obj}" was changed successfully. You may add another {name} below.'),
|
||||
_('The {name} “{obj}” was changed successfully. You may add another {name} below.'),
|
||||
**msg_dict
|
||||
)
|
||||
self.message_user(request, msg, messages.SUCCESS)
|
||||
|
@ -1301,7 +1301,7 @@ class ModelAdmin(BaseModelAdmin):
|
|||
|
||||
else:
|
||||
msg = format_html(
|
||||
_('The {name} "{obj}" was changed successfully.'),
|
||||
_('The {name} “{obj}” was changed successfully.'),
|
||||
**msg_dict
|
||||
)
|
||||
self.message_user(request, msg, messages.SUCCESS)
|
||||
|
@ -1422,7 +1422,7 @@ class ModelAdmin(BaseModelAdmin):
|
|||
|
||||
self.message_user(
|
||||
request,
|
||||
_('The %(name)s "%(obj)s" was deleted successfully.') % {
|
||||
_('The %(name)s “%(obj)s” was deleted successfully.') % {
|
||||
'name': opts.verbose_name,
|
||||
'obj': obj_display,
|
||||
},
|
||||
|
@ -1501,7 +1501,7 @@ class ModelAdmin(BaseModelAdmin):
|
|||
Create a message informing the user that the object doesn't exist
|
||||
and return a redirect to the admin index page.
|
||||
"""
|
||||
msg = _("""%(name)s with ID "%(key)s" doesn't exist. Perhaps it was deleted?""") % {
|
||||
msg = _('%(name)s with ID “%(key)s” doesn’t exist. Perhaps it was deleted?') % {
|
||||
'name': opts.verbose_name,
|
||||
'key': unquote(object_id),
|
||||
}
|
||||
|
|
|
@ -7,6 +7,6 @@
|
|||
|
||||
<h2>{% trans 'Page not found' %}</h2>
|
||||
|
||||
<p>{% trans "We're sorry, but the requested page could not be found." %}</p>
|
||||
<p>{% trans 'We’re sorry, but the requested page could not be found.' %}</p>
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
@ -12,6 +12,6 @@
|
|||
|
||||
{% block content %}
|
||||
<h1>{% trans 'Server Error <em>(500)</em>' %}</h1>
|
||||
<p>{% trans "There's been an error. It's been reported to the site administrators via email and should be fixed shortly. Thanks for your patience." %}</p>
|
||||
<p>{% trans 'There’s been an error. It’s been reported to the site administrators via email and should be fixed shortly. Thanks for your patience.' %}</p>
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
{% block form_top %}
|
||||
{% if not is_popup %}
|
||||
<p>{% trans "First, enter a username and password. Then, you'll be able to edit more user options." %}</p>
|
||||
<p>{% trans 'First, enter a username and password. Then, you’ll be able to edit more user options.' %}</p>
|
||||
{% else %}
|
||||
<p>{% trans "Enter a username and password." %}</p>
|
||||
{% endif %}
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
<input type="hidden" name="post" value="yes">
|
||||
{% if is_popup %}<input type="hidden" name="{{ is_popup_var }}" value="1">{% endif %}
|
||||
{% if to_field %}<input type="hidden" name="{{ to_field_var }}" value="{{ to_field }}">{% endif %}
|
||||
<input type="submit" value="{% trans "Yes, I'm sure" %}">
|
||||
<input type="submit" value="{% trans 'Yes, I’m sure' %}">
|
||||
<a href="#" class="button cancel-link">{% trans "No, take me back" %}</a>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
{% endfor %}
|
||||
<input type="hidden" name="action" value="delete_selected">
|
||||
<input type="hidden" name="post" value="yes">
|
||||
<input type="submit" value="{% trans "Yes, I'm sure" %}">
|
||||
<input type="submit" value="{% trans 'Yes, I’m sure' %}">
|
||||
<a href="#" class="button cancel-link">{% trans "No, take me back" %}</a>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<p>{% trans "You don't have permission to view or edit anything." %}</p>
|
||||
<p>{% trans 'You don’t have permission to view or edit anything.' %}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
@ -9,5 +9,5 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<p>{% trans "Something's wrong with your database installation. Make sure the appropriate database tables have been created, and make sure the database is readable by the appropriate user." %}</p>
|
||||
<p>{% trans 'Something’s wrong with your database installation. Make sure the appropriate database tables have been created, and make sure the database is readable by the appropriate user.' %}</p>
|
||||
{% endblock %}
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
<p>{% trans "This object doesn't have a change history. It probably wasn't added via this admin site." %}</p>
|
||||
<p>{% trans 'This object doesn’t have a change history. It probably wasn’t added via this admin site.' %}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
{% endif %}
|
||||
|
||||
|
||||
<p>{% trans "Please enter your old password, for security's sake, and then enter your new password twice so we can verify you typed it in correctly." %}</p>
|
||||
<p>{% trans 'Please enter your old password, for security’s sake, and then enter your new password twice so we can verify you typed it in correctly.' %}</p>
|
||||
|
||||
<fieldset class="module aligned wide">
|
||||
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
{% block content_title %}<h1>{{ title }}</h1>{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
<p>{% trans "We've emailed you instructions for setting your password, if an account exists with the email you entered. You should receive them shortly." %}</p>
|
||||
<p>{% trans 'We’ve emailed you instructions for setting your password, if an account exists with the email you entered. You should receive them shortly.' %}</p>
|
||||
|
||||
<p>{% trans "If you don't receive an email, please make sure you've entered the address you registered with, and check your spam folder." %}</p>
|
||||
<p>{% trans 'If you don’t receive an email, please make sure you’ve entered the address you registered with, and check your spam folder.' %}</p>
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
{% block reset_link %}
|
||||
{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
|
||||
{% endblock %}
|
||||
{% trans "Your username, in case you've forgotten:" %} {{ user.get_username }}
|
||||
{% trans 'Your username, in case you’ve forgotten:' %} {{ user.get_username }}
|
||||
|
||||
{% trans "Thanks for using our site!" %}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
{% block content_title %}<h1>{{ title }}</h1>{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
<p>{% trans "Forgotten your password? Enter your email address below, and we'll email instructions for setting a new one." %}</p>
|
||||
<p>{% trans 'Forgotten your password? Enter your email address below, and we’ll email instructions for setting a new one.' %}</p>
|
||||
|
||||
<form method="post">{% csrf_token %}
|
||||
<fieldset class="module aligned">
|
||||
|
|
|
@ -13,10 +13,10 @@
|
|||
{% block title %}{% blocktrans %}Template: {{ name }}{% endblocktrans %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>{% blocktrans %}Template: "{{ name }}"{% endblocktrans %}</h1>
|
||||
<h1>{% blocktrans %}Template: <q>{{ name }}</q>{% endblocktrans %}</h1>
|
||||
|
||||
{# Translators: Search is not a verb here, it qualifies path (a search path) #}
|
||||
<h2>{% blocktrans %}Search path for template "{{ name }}":{% endblocktrans %}</h2>
|
||||
<h2>{% blocktrans %}Search path for template <q>{{ name }}</q>:{% endblocktrans %}</h2>
|
||||
<ol>
|
||||
{% for template in templates|dictsort:"order" %}
|
||||
<li><code>{{ template.file }}</code>{% if not template.exists %} <em>{% trans '(does not exist)' %}</em>{% endif %}</li>
|
||||
|
|
|
@ -73,7 +73,7 @@ class UserCreationForm(forms.ModelForm):
|
|||
password.
|
||||
"""
|
||||
error_messages = {
|
||||
'password_mismatch': _("The two password fields didn't match."),
|
||||
'password_mismatch': _('The two password fields didn’t match.'),
|
||||
}
|
||||
password1 = forms.CharField(
|
||||
label=_("Password"),
|
||||
|
@ -134,9 +134,9 @@ class UserChangeForm(forms.ModelForm):
|
|||
password = ReadOnlyPasswordHashField(
|
||||
label=_("Password"),
|
||||
help_text=_(
|
||||
"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=\"{}\">this form</a>."
|
||||
'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="{}">this form</a>.'
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -314,7 +314,7 @@ class SetPasswordForm(forms.Form):
|
|||
password
|
||||
"""
|
||||
error_messages = {
|
||||
'password_mismatch': _("The two password fields didn't match."),
|
||||
'password_mismatch': _('The two password fields didn’t match.'),
|
||||
}
|
||||
new_password1 = forms.CharField(
|
||||
label=_("New password"),
|
||||
|
@ -387,7 +387,7 @@ class AdminPasswordChangeForm(forms.Form):
|
|||
A form used to change the password of a user in the admin interface.
|
||||
"""
|
||||
error_messages = {
|
||||
'password_mismatch': _("The two password fields didn't match."),
|
||||
'password_mismatch': _('The two password fields didn’t match.'),
|
||||
}
|
||||
required_css_class = 'required'
|
||||
password1 = forms.CharField(
|
||||
|
|
Binary file not shown.
|
@ -253,7 +253,7 @@ msgstr[1] ""
|
|||
msgid "The password is too similar to the %(verbose_name)s."
|
||||
msgstr "Le mot de passe est trop semblable au champ « %(verbose_name)s »."
|
||||
|
||||
msgid "Your password can't be too similar to your other personal information."
|
||||
msgid "Your password can’t be too similar to your other personal information."
|
||||
msgstr ""
|
||||
"Votre mot de passe ne peut pas trop ressembler à vos autres informations "
|
||||
"personnelles."
|
||||
|
@ -261,14 +261,14 @@ msgstr ""
|
|||
msgid "This password is too common."
|
||||
msgstr "Ce mot de passe est trop courant."
|
||||
|
||||
msgid "Your password can't be a commonly used password."
|
||||
msgid "Your password can’t be a commonly used password."
|
||||
msgstr ""
|
||||
"Votre mot de passe ne peut pas être un mot de passe couramment utilisé."
|
||||
|
||||
msgid "This password is entirely numeric."
|
||||
msgstr "Ce mot de passe est entièrement numérique."
|
||||
|
||||
msgid "Your password can't be entirely numeric."
|
||||
msgid "Your password can’t be entirely numeric."
|
||||
msgstr "Votre mot de passe ne peut pas être entièrement numérique."
|
||||
|
||||
#, python-format
|
||||
|
|
|
@ -154,7 +154,7 @@ class UserAttributeSimilarityValidator:
|
|||
)
|
||||
|
||||
def get_help_text(self):
|
||||
return _("Your password can't be too similar to your other personal information.")
|
||||
return _('Your password can’t be too similar to your other personal information.')
|
||||
|
||||
|
||||
class CommonPasswordValidator:
|
||||
|
@ -185,7 +185,7 @@ class CommonPasswordValidator:
|
|||
)
|
||||
|
||||
def get_help_text(self):
|
||||
return _("Your password can't be a commonly used password.")
|
||||
return _('Your password can’t be a commonly used password.')
|
||||
|
||||
|
||||
class NumericPasswordValidator:
|
||||
|
@ -200,4 +200,4 @@ class NumericPasswordValidator:
|
|||
)
|
||||
|
||||
def get_help_text(self):
|
||||
return _("Your password can't be entirely numeric.")
|
||||
return _('Your password can’t be entirely numeric.')
|
||||
|
|
|
@ -21,7 +21,7 @@ def shortcut(request, content_type_id, object_id):
|
|||
obj = content_type.get_object_for_this_type(pk=object_id)
|
||||
except (ObjectDoesNotExist, ValueError):
|
||||
raise Http404(
|
||||
_("Content type %(ct_id)s object %(obj_id)s doesn't exist") %
|
||||
_('Content type %(ct_id)s object %(obj_id)s doesn’t exist') %
|
||||
{'ct_id': content_type_id, 'obj_id': object_id}
|
||||
)
|
||||
|
||||
|
@ -29,7 +29,7 @@ def shortcut(request, content_type_id, object_id):
|
|||
get_absolute_url = obj.get_absolute_url
|
||||
except AttributeError:
|
||||
raise Http404(
|
||||
_("%(ct_name)s objects don't have a get_absolute_url() method") %
|
||||
_('%(ct_name)s objects don’t have a get_absolute_url() method') %
|
||||
{'ct_name': content_type.name}
|
||||
)
|
||||
absurl = get_absolute_url()
|
||||
|
|
|
@ -9,7 +9,7 @@ class FlatpageForm(forms.ModelForm):
|
|||
label=_("URL"),
|
||||
max_length=100,
|
||||
regex=r'^[-\w/\.~]+$',
|
||||
help_text=_("Example: '/about/contact/'. Make sure to have leading and trailing slashes."),
|
||||
help_text=_('Example: “/about/contact/”. Make sure to have leading and trailing slashes.'),
|
||||
error_messages={
|
||||
"invalid": _(
|
||||
"This value must contain only letters, numbers, dots, "
|
||||
|
@ -26,7 +26,7 @@ class FlatpageForm(forms.ModelForm):
|
|||
super().__init__(*args, **kwargs)
|
||||
if not self._trailing_slash_required():
|
||||
self.fields['url'].help_text = _(
|
||||
"Example: '/about/contact'. Make sure to have a leading slash."
|
||||
'Example: “/about/contact”. Make sure to have a leading slash.'
|
||||
)
|
||||
|
||||
def _trailing_slash_required(self):
|
||||
|
|
|
@ -18,8 +18,8 @@ class Migration(migrations.Migration):
|
|||
('enable_comments', models.BooleanField(default=False, verbose_name='enable comments')),
|
||||
('template_name', models.CharField(
|
||||
help_text=(
|
||||
"Example: 'flatpages/contact_page.html'. If this isn't provided, the system will use "
|
||||
"'flatpages/default.html'."
|
||||
'Example: “flatpages/contact_page.html”. If this isn’t provided, the system will use '
|
||||
'“flatpages/default.html”.'
|
||||
), max_length=70, verbose_name='template name', blank=True
|
||||
)),
|
||||
('registration_required', models.BooleanField(
|
||||
|
|
|
@ -15,8 +15,8 @@ class FlatPage(models.Model):
|
|||
max_length=70,
|
||||
blank=True,
|
||||
help_text=_(
|
||||
"Example: 'flatpages/contact_page.html'. If this isn't provided, "
|
||||
"the system will use 'flatpages/default.html'."
|
||||
'Example: “flatpages/contact_page.html”. If this isn’t provided, '
|
||||
'the system will use “flatpages/default.html”.'
|
||||
),
|
||||
)
|
||||
registration_required = models.BooleanField(
|
||||
|
|
|
@ -198,7 +198,7 @@ class GeometryField(BaseSpatialField):
|
|||
"""
|
||||
The base Geometry field -- maps to the OpenGIS Specification Geometry type.
|
||||
"""
|
||||
description = _("The base Geometry field -- maps to the OpenGIS Specification Geometry type.")
|
||||
description = _('The base Geometry field — maps to the OpenGIS Specification Geometry type.')
|
||||
form_class = forms.GeometryField
|
||||
# The OpenGIS Geometry name.
|
||||
geom_type = 'GEOMETRY'
|
||||
|
|
|
@ -11,7 +11,7 @@ def feed(request, url, feed_dict=None):
|
|||
try:
|
||||
f = feed_dict[slug]
|
||||
except KeyError:
|
||||
raise Http404(_("Slug %r isn't registered.") % slug)
|
||||
raise Http404(_('Slug %r isn’t registered.') % slug)
|
||||
|
||||
instance = f()
|
||||
instance.feed_url = getattr(f, 'feed_url', None) or request.path
|
||||
|
|
|
@ -15,7 +15,7 @@ class HStoreField(CheckFieldDefaultMixin, Field):
|
|||
empty_strings_allowed = False
|
||||
description = _('Map of strings to strings/nulls')
|
||||
default_error_messages = {
|
||||
'not_a_string': _('The value of "%(key)s" is not a string or null.'),
|
||||
'not_a_string': _('The value of “%(key)s” is not a string or null.'),
|
||||
}
|
||||
_default_hint = ('dict', '{}')
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ class JSONString(str):
|
|||
|
||||
class JSONField(forms.CharField):
|
||||
default_error_messages = {
|
||||
'invalid': _("'%(value)s' value must be valid JSON."),
|
||||
'invalid': _('“%(value)s” value must be valid JSON.'),
|
||||
}
|
||||
widget = forms.Textarea
|
||||
|
||||
|
|
|
@ -20,11 +20,11 @@ class Migration(migrations.Migration):
|
|||
)),
|
||||
('old_path', models.CharField(
|
||||
help_text=(
|
||||
"This should be an absolute path, excluding the domain name. Example: '/events/search/'."
|
||||
'This should be an absolute path, excluding the domain name. Example: “/events/search/”.'
|
||||
), max_length=200, verbose_name='redirect from', db_index=True
|
||||
)),
|
||||
('new_path', models.CharField(
|
||||
help_text="This can be either an absolute path (as above) or a full URL starting with 'http://'.",
|
||||
help_text='This can be either an absolute path (as above) or a full URL starting with “http://”.',
|
||||
max_length=200, verbose_name='redirect to', blank=True
|
||||
)),
|
||||
],
|
||||
|
|
|
@ -9,13 +9,13 @@ class Redirect(models.Model):
|
|||
_('redirect from'),
|
||||
max_length=200,
|
||||
db_index=True,
|
||||
help_text=_("This should be an absolute path, excluding the domain name. Example: '/events/search/'."),
|
||||
help_text=_('This should be an absolute path, excluding the domain name. Example: “/events/search/”.'),
|
||||
)
|
||||
new_path = models.CharField(
|
||||
_('redirect to'),
|
||||
max_length=200,
|
||||
blank=True,
|
||||
help_text=_("This can be either an absolute path (as above) or a full URL starting with 'http://'."),
|
||||
help_text=_('This can be either an absolute path (as above) or a full URL starting with “http://”.'),
|
||||
)
|
||||
|
||||
class Meta:
|
||||
|
|
|
@ -236,14 +236,14 @@ slug_re = _lazy_re_compile(r'^[-a-zA-Z0-9_]+\Z')
|
|||
validate_slug = RegexValidator(
|
||||
slug_re,
|
||||
# Translators: "letters" means latin letters: a-z and A-Z.
|
||||
_("Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens."),
|
||||
_('Enter a valid “slug” consisting of letters, numbers, underscores or hyphens.'),
|
||||
'invalid'
|
||||
)
|
||||
|
||||
slug_unicode_re = _lazy_re_compile(r'^[-\w]+\Z')
|
||||
validate_unicode_slug = RegexValidator(
|
||||
slug_unicode_re,
|
||||
_("Enter a valid 'slug' consisting of Unicode letters, numbers, underscores, or hyphens."),
|
||||
_('Enter a valid “slug” consisting of Unicode letters, numbers, underscores, or hyphens.'),
|
||||
'invalid'
|
||||
)
|
||||
|
||||
|
@ -466,8 +466,8 @@ class DecimalValidator:
|
|||
@deconstructible
|
||||
class FileExtensionValidator:
|
||||
message = _(
|
||||
"File extension '%(extension)s' is not allowed. "
|
||||
"Allowed extensions are: '%(allowed_extensions)s'."
|
||||
'File extension “%(extension)s” is not allowed. '
|
||||
'Allowed extensions are: %(allowed_extensions)s.'
|
||||
)
|
||||
code = 'invalid_extension'
|
||||
|
||||
|
|
|
@ -899,7 +899,7 @@ class AutoField(Field):
|
|||
|
||||
empty_strings_allowed = False
|
||||
default_error_messages = {
|
||||
'invalid': _("'%(value)s' value must be an integer."),
|
||||
'invalid': _('“%(value)s” value must be an integer.'),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
@ -986,8 +986,8 @@ class BigAutoField(AutoField):
|
|||
class BooleanField(Field):
|
||||
empty_strings_allowed = False
|
||||
default_error_messages = {
|
||||
'invalid': _("'%(value)s' value must be either True or False."),
|
||||
'invalid_nullable': _("'%(value)s' value must be either True, False, or None."),
|
||||
'invalid': _('“%(value)s” value must be either True or False.'),
|
||||
'invalid_nullable': _('“%(value)s” value must be either True, False, or None.'),
|
||||
}
|
||||
description = _("Boolean (Either True or False)")
|
||||
|
||||
|
@ -1143,10 +1143,10 @@ class DateTimeCheckMixin:
|
|||
class DateField(DateTimeCheckMixin, Field):
|
||||
empty_strings_allowed = False
|
||||
default_error_messages = {
|
||||
'invalid': _("'%(value)s' value has an invalid date format. It must be "
|
||||
"in YYYY-MM-DD format."),
|
||||
'invalid_date': _("'%(value)s' value has the correct format (YYYY-MM-DD) "
|
||||
"but it is an invalid date."),
|
||||
'invalid': _('“%(value)s” value has an invalid date format. It must be '
|
||||
'in YYYY-MM-DD format.'),
|
||||
'invalid_date': _('“%(value)s” value has the correct format (YYYY-MM-DD) '
|
||||
'but it is an invalid date.'),
|
||||
}
|
||||
description = _("Date (without time)")
|
||||
|
||||
|
@ -1286,13 +1286,13 @@ class DateField(DateTimeCheckMixin, Field):
|
|||
class DateTimeField(DateField):
|
||||
empty_strings_allowed = False
|
||||
default_error_messages = {
|
||||
'invalid': _("'%(value)s' value has an invalid format. It must be in "
|
||||
"YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] format."),
|
||||
'invalid_date': _("'%(value)s' value has the correct format "
|
||||
'invalid': _('“%(value)s” value has an invalid format. It must be in '
|
||||
'YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] format.'),
|
||||
'invalid_date': _("“%(value)s” value has the correct format "
|
||||
"(YYYY-MM-DD) but it is an invalid date."),
|
||||
'invalid_datetime': _("'%(value)s' value has the correct format "
|
||||
"(YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]) "
|
||||
"but it is an invalid date/time."),
|
||||
'invalid_datetime': _('“%(value)s” value has the correct format '
|
||||
'(YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]) '
|
||||
'but it is an invalid date/time.'),
|
||||
}
|
||||
description = _("Date (with time)")
|
||||
|
||||
|
@ -1442,7 +1442,7 @@ class DateTimeField(DateField):
|
|||
class DecimalField(Field):
|
||||
empty_strings_allowed = False
|
||||
default_error_messages = {
|
||||
'invalid': _("'%(value)s' value must be a decimal number."),
|
||||
'invalid': _('“%(value)s” value must be a decimal number.'),
|
||||
}
|
||||
description = _("Decimal number")
|
||||
|
||||
|
@ -1583,8 +1583,8 @@ class DurationField(Field):
|
|||
"""
|
||||
empty_strings_allowed = False
|
||||
default_error_messages = {
|
||||
'invalid': _("'%(value)s' value has an invalid format. It must be in "
|
||||
"[DD] [[HH:]MM:]ss[.uuuuuu] format.")
|
||||
'invalid': _('“%(value)s” value has an invalid format. It must be in '
|
||||
'[DD] [[HH:]MM:]ss[.uuuuuu] format.')
|
||||
}
|
||||
description = _("Duration")
|
||||
|
||||
|
@ -1725,7 +1725,7 @@ class FilePathField(Field):
|
|||
class FloatField(Field):
|
||||
empty_strings_allowed = False
|
||||
default_error_messages = {
|
||||
'invalid': _("'%(value)s' value must be a float."),
|
||||
'invalid': _('“%(value)s” value must be a float.'),
|
||||
}
|
||||
description = _("Floating point number")
|
||||
|
||||
|
@ -1760,7 +1760,7 @@ class FloatField(Field):
|
|||
class IntegerField(Field):
|
||||
empty_strings_allowed = False
|
||||
default_error_messages = {
|
||||
'invalid': _("'%(value)s' value must be an integer."),
|
||||
'invalid': _('“%(value)s” value must be an integer.'),
|
||||
}
|
||||
description = _("Integer")
|
||||
|
||||
|
@ -1967,8 +1967,8 @@ class GenericIPAddressField(Field):
|
|||
|
||||
class NullBooleanField(BooleanField):
|
||||
default_error_messages = {
|
||||
'invalid': _("'%(value)s' value must be either None, True or False."),
|
||||
'invalid_nullable': _("'%(value)s' value must be either None, True or False."),
|
||||
'invalid': _('“%(value)s” value must be either None, True or False.'),
|
||||
'invalid_nullable': _('“%(value)s” value must be either None, True or False.'),
|
||||
}
|
||||
description = _("Boolean (Either True, False or None)")
|
||||
|
||||
|
@ -2099,10 +2099,10 @@ class TextField(Field):
|
|||
class TimeField(DateTimeCheckMixin, Field):
|
||||
empty_strings_allowed = False
|
||||
default_error_messages = {
|
||||
'invalid': _("'%(value)s' value has an invalid format. It must be in "
|
||||
"HH:MM[:ss[.uuuuuu]] format."),
|
||||
'invalid_time': _("'%(value)s' value has the correct format "
|
||||
"(HH:MM[:ss[.uuuuuu]]) but it is an invalid time."),
|
||||
'invalid': _('“%(value)s” value has an invalid format. It must be in '
|
||||
'HH:MM[:ss[.uuuuuu]] format.'),
|
||||
'invalid_time': _('“%(value)s” value has the correct format '
|
||||
'(HH:MM[:ss[.uuuuuu]]) but it is an invalid time.'),
|
||||
}
|
||||
description = _("Time")
|
||||
|
||||
|
@ -2317,7 +2317,7 @@ class BinaryField(Field):
|
|||
|
||||
class UUIDField(Field):
|
||||
default_error_messages = {
|
||||
'invalid': _("'%(value)s' is not a valid UUID."),
|
||||
'invalid': _('“%(value)s” is not a valid UUID.'),
|
||||
}
|
||||
description = _('Universally unique identifier')
|
||||
empty_strings_allowed = False
|
||||
|
|
|
@ -1272,7 +1272,7 @@ class ModelMultipleChoiceField(ModelChoiceField):
|
|||
'list': _('Enter a list of values.'),
|
||||
'invalid_choice': _('Select a valid choice. %(value)s is not one of the'
|
||||
' available choices.'),
|
||||
'invalid_pk_value': _('"%(pk)s" is not a valid value.')
|
||||
'invalid_pk_value': _('“%(pk)s” is not a valid value.')
|
||||
}
|
||||
|
||||
def __init__(self, queryset, **kwargs):
|
||||
|
|
|
@ -159,7 +159,7 @@ def from_current_timezone(value):
|
|||
return timezone.make_aware(value, current_timezone)
|
||||
except Exception as exc:
|
||||
raise ValidationError(
|
||||
_('%(datetime)s couldn\'t be interpreted '
|
||||
_('%(datetime)s couldn’t be interpreted '
|
||||
'in time zone %(current_timezone)s; it '
|
||||
'may be ambiguous or it may not exist.'),
|
||||
code='ambiguous_timezone',
|
||||
|
|
|
@ -112,21 +112,21 @@ def csrf_failure(request, reason="", template_name=CSRF_FAILURE_TEMPLATE_NAME):
|
|||
'reason': reason,
|
||||
'no_referer': reason == REASON_NO_REFERER,
|
||||
'no_referer1': _(
|
||||
"You are seeing this message because this HTTPS site requires a "
|
||||
"'Referer header' to be sent by your Web browser, but none was "
|
||||
"sent. This header is required for security reasons, to ensure "
|
||||
"that your browser is not being hijacked by third parties."),
|
||||
'You are seeing this message because this HTTPS site requires a '
|
||||
'“Referer header” to be sent by your Web browser, but none was '
|
||||
'sent. This header is required for security reasons, to ensure '
|
||||
'that your browser is not being hijacked by third parties.'),
|
||||
'no_referer2': _(
|
||||
"If you have configured your browser to disable 'Referer' headers, "
|
||||
"please re-enable them, at least for this site, or for HTTPS "
|
||||
"connections, or for 'same-origin' requests."),
|
||||
'If you have configured your browser to disable “Referer” headers, '
|
||||
'please re-enable them, at least for this site, or for HTTPS '
|
||||
'connections, or for “same-origin” requests.'),
|
||||
'no_referer3': _(
|
||||
"If you are using the <meta name=\"referrer\" "
|
||||
"content=\"no-referrer\"> tag or including the 'Referrer-Policy: "
|
||||
"no-referrer' header, please remove them. The CSRF protection "
|
||||
"requires the 'Referer' header to do strict referer checking. If "
|
||||
"you're concerned about privacy, use alternatives like "
|
||||
"<a rel=\"noreferrer\" ...> for links to third-party sites."),
|
||||
'If you are using the <meta name="referrer" '
|
||||
'content=\"no-referrer\"> tag or including the “Referrer-Policy: '
|
||||
'no-referrer” header, please remove them. The CSRF protection '
|
||||
'requires the “Referer” header to do strict referer checking. If '
|
||||
'you’re concerned about privacy, use alternatives like '
|
||||
'<a rel=\"noreferrer\" …> for links to third-party sites.'),
|
||||
'no_cookie': reason == REASON_NO_CSRF_COOKIE,
|
||||
'no_cookie1': _(
|
||||
"You are seeing this message because this site requires a CSRF "
|
||||
|
@ -134,9 +134,9 @@ def csrf_failure(request, reason="", template_name=CSRF_FAILURE_TEMPLATE_NAME):
|
|||
"security reasons, to ensure that your browser is not being "
|
||||
"hijacked by third parties."),
|
||||
'no_cookie2': _(
|
||||
"If you have configured your browser to disable cookies, please "
|
||||
"re-enable them, at least for this site, or for 'same-origin' "
|
||||
"requests."),
|
||||
'If you have configured your browser to disable cookies, please '
|
||||
're-enable them, at least for this site, or for “same-origin” '
|
||||
'requests.'),
|
||||
'DEBUG': settings.DEBUG,
|
||||
'docs_version': get_docs_version(),
|
||||
'more': _("More information is available with DEBUG=True."),
|
||||
|
|
|
@ -620,7 +620,7 @@ def _date_from_string(year, year_format, month='', month_format='', day='', day_
|
|||
try:
|
||||
return datetime.datetime.strptime(datestr, format).date()
|
||||
except ValueError:
|
||||
raise Http404(_("Invalid date string '%(datestr)s' given format '%(format)s'") % {
|
||||
raise Http404(_('Invalid date string “%(datestr)s” given format “%(format)s”') % {
|
||||
'datestr': datestr,
|
||||
'format': format,
|
||||
})
|
||||
|
|
|
@ -64,7 +64,7 @@ class MultipleObjectMixin(ContextMixin):
|
|||
if page == 'last':
|
||||
page_number = paginator.num_pages
|
||||
else:
|
||||
raise Http404(_("Page is not 'last', nor can it be converted to an int."))
|
||||
raise Http404(_('Page is not “last”, nor can it be converted to an int.'))
|
||||
try:
|
||||
page = paginator.page(page_number)
|
||||
return (paginator, page, page.object_list, page.has_other_pages())
|
||||
|
@ -151,7 +151,7 @@ class BaseListView(MultipleObjectMixin, View):
|
|||
else:
|
||||
is_empty = not self.object_list
|
||||
if is_empty:
|
||||
raise Http404(_("Empty list and '%(class_name)s.allow_empty' is False.") % {
|
||||
raise Http404(_('Empty list and “%(class_name)s.allow_empty” is False.') % {
|
||||
'class_name': self.__class__.__name__,
|
||||
})
|
||||
context = self.get_context_data()
|
||||
|
|
|
@ -39,7 +39,7 @@ def serve(request, path, document_root=None, show_indexes=False):
|
|||
return directory_index(path, fullpath)
|
||||
raise Http404(_("Directory indexes are not allowed here."))
|
||||
if not fullpath.exists():
|
||||
raise Http404(_('"%(path)s" does not exist') % {'path': fullpath})
|
||||
raise Http404(_('“%(path)s” does not exist') % {'path': fullpath})
|
||||
# Respect the If-Modified-Since header.
|
||||
statobj = fullpath.stat()
|
||||
if not was_modified_since(request.META.get('HTTP_IF_MODIFIED_SINCE'),
|
||||
|
|
|
@ -382,7 +382,7 @@
|
|||
</svg>
|
||||
<div>
|
||||
<h4>{% trans "Django Documentation" %}</h4>
|
||||
<p>{% trans "Topics, references, & how-to's" %}</p>
|
||||
<p>{% trans 'Topics, references, & how-to’s' %}</p>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
|
|
@ -1115,7 +1115,7 @@ class GetAdminLogTests(TestCase):
|
|||
'{{ entry|safe }}'
|
||||
'{% endfor %}'
|
||||
)
|
||||
self.assertEqual(t.render(Context({})), 'Added "<User: jondoe>".')
|
||||
self.assertEqual(t.render(Context({})), 'Added “<User: jondoe>”.')
|
||||
|
||||
def test_missing_args(self):
|
||||
msg = "'get_admin_log' statements require two arguments"
|
||||
|
|
|
@ -105,7 +105,7 @@ class AdminDocViewTests(TestDataMixin, AdminDocsTestCase):
|
|||
|
||||
def test_template_detail(self):
|
||||
response = self.client.get(reverse('django-admindocs-templates', args=['admin_doc/template_detail.html']))
|
||||
self.assertContains(response, '<h1>Template: "admin_doc/template_detail.html"</h1>', html=True)
|
||||
self.assertContains(response, '<h1>Template: <q>admin_doc/template_detail.html</q></h1>', html=True)
|
||||
|
||||
def test_missing_docutils(self):
|
||||
utils.docutils_is_available = False
|
||||
|
|
|
@ -131,9 +131,9 @@ class LogEntryTests(TestCase):
|
|||
)
|
||||
self.assertEqual(
|
||||
logentry.get_change_message(),
|
||||
'Changed Domain. Added article "Added article". '
|
||||
'Changed Title and not_a_form_field for article "Changed Title". '
|
||||
'Deleted article "Title second article".'
|
||||
'Changed Domain. Added article “Added article”. '
|
||||
'Changed Title and not_a_form_field for article “Changed Title”. '
|
||||
'Deleted article “Title second article”.'
|
||||
)
|
||||
|
||||
with translation.override('fr'):
|
||||
|
|
|
@ -899,7 +899,7 @@ class StateAdminForm(forms.ModelForm):
|
|||
class Meta:
|
||||
model = State
|
||||
fields = '__all__'
|
||||
labels = {"name": "State name (from form's Meta.labels)"}
|
||||
labels = {'name': 'State name (from form’s Meta.labels)'}
|
||||
|
||||
@property
|
||||
def changed_data(self):
|
||||
|
|
|
@ -39,7 +39,7 @@ class AdminHistoryViewTests(TestCase):
|
|||
logentry = LogEntry.objects.filter(content_type__model__iexact='state').latest('id')
|
||||
self.assertEqual(
|
||||
logentry.get_change_message(),
|
||||
'Changed State name (from form\'s Meta.labels), '
|
||||
'Changed State name (from form’s Meta.labels), '
|
||||
'nolabel_form_field and not_a_form_field. '
|
||||
'Changed City verbose_name for city "%s".' % city
|
||||
'Changed City verbose_name for city “%s”.' % city
|
||||
)
|
||||
|
|
|
@ -227,7 +227,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase):
|
|||
self.assertRedirects(response, reverse('admin:index'))
|
||||
self.assertEqual(
|
||||
[m.message for m in response.context['messages']],
|
||||
["""section with ID "abc/<b>" doesn't exist. Perhaps it was deleted?"""]
|
||||
['section with ID “abc/<b>” doesn’t exist. Perhaps it was deleted?']
|
||||
)
|
||||
|
||||
def test_basic_edit_GET_old_url_redirect(self):
|
||||
|
@ -248,7 +248,7 @@ class AdminViewBasicTest(AdminViewBasicTestCase):
|
|||
self.assertRedirects(response, reverse('admin:index'))
|
||||
self.assertEqual(
|
||||
[m.message for m in response.context['messages']],
|
||||
["""super villain with ID "abc" doesn't exist. Perhaps it was deleted?"""]
|
||||
['super villain with ID “abc” doesn’t exist. Perhaps it was deleted?']
|
||||
)
|
||||
|
||||
def test_basic_add_POST(self):
|
||||
|
@ -1705,7 +1705,7 @@ class AdminViewPermissionsTest(TestCase):
|
|||
self.assertEqual(Article.objects.count(), 4)
|
||||
article = Article.objects.latest('pk')
|
||||
response = self.client.get(reverse('admin:admin_views_article_change', args=(article.pk,)))
|
||||
self.assertContains(response, '<li class="success">The article "Døm ikke" was added successfully.</li>')
|
||||
self.assertContains(response, '<li class="success">The article “Døm ikke” was added successfully.</li>')
|
||||
article.delete()
|
||||
self.client.get(reverse('admin:logout'))
|
||||
|
||||
|
@ -2113,7 +2113,7 @@ class AdminViewPermissionsTest(TestCase):
|
|||
self.assertRedirects(response, reverse('admin:index'))
|
||||
self.assertEqual(
|
||||
[m.message for m in response.context['messages']],
|
||||
["""article with ID "nonexistent" doesn't exist. Perhaps it was deleted?"""]
|
||||
['article with ID “nonexistent” doesn’t exist. Perhaps it was deleted?']
|
||||
)
|
||||
|
||||
def test_history_view(self):
|
||||
|
@ -2170,7 +2170,7 @@ class AdminViewPermissionsTest(TestCase):
|
|||
self.assertRedirects(response, reverse('admin:index'))
|
||||
self.assertEqual(
|
||||
[m.message for m in response.context['messages']],
|
||||
["""article with ID "foo" doesn't exist. Perhaps it was deleted?"""]
|
||||
['article with ID “foo” doesn’t exist. Perhaps it was deleted?']
|
||||
)
|
||||
|
||||
def test_conditionally_show_add_section_link(self):
|
||||
|
@ -2399,7 +2399,7 @@ class AdminViewPermissionsTest(TestCase):
|
|||
response = self.client.post(reverse('admin:admin_views_article_add'), post_data, follow=True)
|
||||
self.assertContains(
|
||||
response,
|
||||
'<li class="success">The article "Fun & games" was added successfully.</li>',
|
||||
'<li class="success">The article “Fun & games” was added successfully.</li>',
|
||||
html=True
|
||||
)
|
||||
|
||||
|
@ -3689,7 +3689,7 @@ class AdminCustomQuerysetTest(TestCase):
|
|||
self.assertRedirects(response, reverse('admin:index'))
|
||||
self.assertEqual(
|
||||
[m.message for m in response.context['messages']],
|
||||
["""empty model with ID "1" doesn't exist. Perhaps it was deleted?"""]
|
||||
['empty model with ID “1” doesn’t exist. Perhaps it was deleted?']
|
||||
)
|
||||
|
||||
def test_add_model_modeladmin_defer_qs(self):
|
||||
|
@ -3709,8 +3709,8 @@ class AdminCustomQuerysetTest(TestCase):
|
|||
pk = CoverLetter.objects.all()[0].pk
|
||||
self.assertContains(
|
||||
response,
|
||||
'<li class="success">The cover letter "<a href="%s">'
|
||||
'Candidate, Best</a>" was added successfully.</li>' %
|
||||
'<li class="success">The cover letter “<a href="%s">'
|
||||
'Candidate, Best</a>” was added successfully.</li>' %
|
||||
reverse('admin:admin_views_coverletter_change', args=(pk,)), html=True
|
||||
)
|
||||
|
||||
|
@ -3728,8 +3728,8 @@ class AdminCustomQuerysetTest(TestCase):
|
|||
sm = ShortMessage.objects.all()[0]
|
||||
self.assertContains(
|
||||
response,
|
||||
'<li class="success">The short message "<a href="%s">'
|
||||
'%s</a>" was added successfully.</li>' %
|
||||
'<li class="success">The short message “<a href="%s">'
|
||||
'%s</a>” was added successfully.</li>' %
|
||||
(reverse('admin:admin_views_shortmessage_change', args=(sm.pk,)), sm), html=True
|
||||
)
|
||||
|
||||
|
@ -3750,8 +3750,8 @@ class AdminCustomQuerysetTest(TestCase):
|
|||
pk = Telegram.objects.all()[0].pk
|
||||
self.assertContains(
|
||||
response,
|
||||
'<li class="success">The telegram "<a href="%s">'
|
||||
'Urgent telegram</a>" was added successfully.</li>' %
|
||||
'<li class="success">The telegram “<a href="%s">'
|
||||
'Urgent telegram</a>” was added successfully.</li>' %
|
||||
reverse('admin:admin_views_telegram_change', args=(pk,)), html=True
|
||||
)
|
||||
|
||||
|
@ -3769,8 +3769,8 @@ class AdminCustomQuerysetTest(TestCase):
|
|||
p = Paper.objects.all()[0]
|
||||
self.assertContains(
|
||||
response,
|
||||
'<li class="success">The paper "<a href="%s">'
|
||||
'%s</a>" was added successfully.</li>' %
|
||||
'<li class="success">The paper “<a href="%s">'
|
||||
'%s</a>” was added successfully.</li>' %
|
||||
(reverse('admin:admin_views_paper_change', args=(p.pk,)), p), html=True
|
||||
)
|
||||
|
||||
|
@ -3795,8 +3795,8 @@ class AdminCustomQuerysetTest(TestCase):
|
|||
# representation is set by model's __str__()
|
||||
self.assertContains(
|
||||
response,
|
||||
'<li class="success">The cover letter "<a href="%s">'
|
||||
'John Doe II</a>" was changed successfully.</li>' %
|
||||
'<li class="success">The cover letter “<a href="%s">'
|
||||
'John Doe II</a>” was changed successfully.</li>' %
|
||||
reverse('admin:admin_views_coverletter_change', args=(cl.pk,)), html=True
|
||||
)
|
||||
|
||||
|
@ -3818,8 +3818,8 @@ class AdminCustomQuerysetTest(TestCase):
|
|||
# instance representation is set by __str__().
|
||||
self.assertContains(
|
||||
response,
|
||||
'<li class="success">The short message "<a href="%s">'
|
||||
'%s</a>" was changed successfully.</li>' %
|
||||
'<li class="success">The short message “<a href="%s">'
|
||||
'%s</a>” was changed successfully.</li>' %
|
||||
(reverse('admin:admin_views_shortmessage_change', args=(sm.pk,)), sm), html=True
|
||||
)
|
||||
|
||||
|
@ -3843,8 +3843,8 @@ class AdminCustomQuerysetTest(TestCase):
|
|||
# representation is set by model's __str__()
|
||||
self.assertContains(
|
||||
response,
|
||||
'<li class="success">The telegram "<a href="%s">'
|
||||
'Telegram without typo</a>" was changed successfully.</li>' %
|
||||
'<li class="success">The telegram “<a href="%s">'
|
||||
'Telegram without typo</a>” was changed successfully.</li>' %
|
||||
reverse('admin:admin_views_telegram_change', args=(t.pk,)), html=True
|
||||
)
|
||||
|
||||
|
@ -3865,8 +3865,8 @@ class AdminCustomQuerysetTest(TestCase):
|
|||
# instance representation is set by __str__().
|
||||
self.assertContains(
|
||||
response,
|
||||
'<li class="success">The paper "<a href="%s">'
|
||||
'%s</a>" was changed successfully.</li>' %
|
||||
'<li class="success">The paper “<a href="%s">'
|
||||
'%s</a>” was changed successfully.</li>' %
|
||||
(reverse('admin:admin_views_paper_change', args=(p.pk,)), p), html=True
|
||||
)
|
||||
|
||||
|
@ -5161,8 +5161,8 @@ class UserAdminTest(TestCase):
|
|||
response = self.client.get(new_user_url)
|
||||
self.assertContains(
|
||||
response,
|
||||
'<li class="success">The user "<a href="%s">'
|
||||
'%s</a>" was added successfully. You may edit it again below.</li>'
|
||||
'<li class="success">The user “<a href="%s">'
|
||||
'%s</a>” was added successfully. You may edit it again below.</li>'
|
||||
% (new_user_url, new_user),
|
||||
html=True,
|
||||
)
|
||||
|
@ -5175,7 +5175,7 @@ class UserAdminTest(TestCase):
|
|||
})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertFormError(response, 'adminform', 'password', [])
|
||||
self.assertFormError(response, 'adminform', 'password2', ["The two password fields didn't match."])
|
||||
self.assertFormError(response, 'adminform', 'password2', ['The two password fields didn’t match.'])
|
||||
|
||||
def test_user_fk_add_popup(self):
|
||||
"""User addition through a FK popup should return the appropriate JavaScript response."""
|
||||
|
|
|
@ -181,7 +181,7 @@ class AdminFormfieldForDBFieldTests(SimpleTestCase):
|
|||
f = ma.formfield_for_dbfield(Advisor._meta.get_field('companies'), request=None)
|
||||
self.assertEqual(
|
||||
f.help_text,
|
||||
'Hold down "Control", or "Command" on a Mac, to select more than one.'
|
||||
'Hold down “Control”, or “Command” on a Mac, to select more than one.'
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -236,7 +236,7 @@ class UserCreationFormTest(TestDataMixin, TestCase):
|
|||
form = UserCreationForm()
|
||||
self.assertEqual(
|
||||
form.fields['password1'].help_text,
|
||||
'<ul><li>Your password can't be too similar to your other personal information.</li></ul>'
|
||||
'<ul><li>Your password can’t be too similar to your other personal information.</li></ul>'
|
||||
)
|
||||
|
||||
@override_settings(AUTH_PASSWORD_VALIDATORS=[
|
||||
|
|
|
@ -178,7 +178,7 @@ class UserAttributeSimilarityValidatorTest(TestCase):
|
|||
def test_help_text(self):
|
||||
self.assertEqual(
|
||||
UserAttributeSimilarityValidator().get_help_text(),
|
||||
"Your password can't be too similar to your other personal information."
|
||||
'Your password can’t be too similar to your other personal information.'
|
||||
)
|
||||
|
||||
|
||||
|
@ -210,7 +210,7 @@ class CommonPasswordValidatorTest(SimpleTestCase):
|
|||
def test_help_text(self):
|
||||
self.assertEqual(
|
||||
CommonPasswordValidator().get_help_text(),
|
||||
"Your password can't be a commonly used password."
|
||||
'Your password can’t be a commonly used password.'
|
||||
)
|
||||
|
||||
|
||||
|
@ -227,7 +227,7 @@ class NumericPasswordValidatorTest(SimpleTestCase):
|
|||
def test_help_text(self):
|
||||
self.assertEqual(
|
||||
NumericPasswordValidator().get_help_text(),
|
||||
"Your password can't be entirely numeric."
|
||||
'Your password can’t be entirely numeric.'
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -51,8 +51,8 @@ class FlatpageAdminFormTests(TestCase):
|
|||
with translation.override('en'):
|
||||
self.assertEqual(
|
||||
form.fields['url'].help_text,
|
||||
"Example: '/about/contact/'. Make sure to have leading and "
|
||||
"trailing slashes."
|
||||
'Example: “/about/contact/”. Make sure to have leading and '
|
||||
'trailing slashes.'
|
||||
)
|
||||
self.assertFalse(form.is_valid())
|
||||
self.assertEqual(form.errors['url'], ["URL is missing a trailing slash."])
|
||||
|
@ -64,7 +64,7 @@ class FlatpageAdminFormTests(TestCase):
|
|||
with translation.override('en'):
|
||||
self.assertEqual(
|
||||
form.fields['url'].help_text,
|
||||
"Example: '/about/contact'. Make sure to have a leading slash."
|
||||
'Example: “/about/contact”. Make sure to have a leading slash.'
|
||||
)
|
||||
|
||||
def test_flatpage_admin_form_url_uniqueness_validation(self):
|
||||
|
|
|
@ -66,7 +66,7 @@ class ImageFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
|
|||
with open(img_path, 'rb') as img_file:
|
||||
img_data = img_file.read()
|
||||
img_file = SimpleUploadedFile('1x1.txt', img_data)
|
||||
with self.assertRaisesMessage(ValidationError, "File extension 'txt' is not allowed."):
|
||||
with self.assertRaisesMessage(ValidationError, 'File extension “txt” is not allowed.'):
|
||||
f.clean(img_file)
|
||||
|
||||
def test_widget_attrs_default_accept(self):
|
||||
|
|
|
@ -276,7 +276,7 @@ class FormsErrorMessagesTestCase(SimpleTestCase, AssertFormErrorsMixin):
|
|||
self.assertHTMLEqual(
|
||||
t.render(Context({'form': f})),
|
||||
'<ul class="errorlist"><li>field<ul class="errorlist">'
|
||||
'<li>"<script>" is not a valid value.</li>'
|
||||
'<li>“<script>” is not a valid value.</li>'
|
||||
'</ul></li></ul>'
|
||||
)
|
||||
|
||||
|
|
|
@ -1275,7 +1275,7 @@ class AutodetectorTests(TestCase):
|
|||
"testapp", "model", [("id", models.AutoField(primary_key=True, validators=[
|
||||
RegexValidator(
|
||||
re.compile('^[-a-zA-Z0-9_]+\\Z'),
|
||||
"Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens.",
|
||||
'Enter a valid “slug” consisting of letters, numbers, underscores or hyphens.',
|
||||
'invalid'
|
||||
)
|
||||
]))]
|
||||
|
@ -1292,7 +1292,7 @@ class AutodetectorTests(TestCase):
|
|||
"testapp", "model", [("id", models.AutoField(primary_key=True, validators=[
|
||||
RegexValidator(
|
||||
re.compile('^[a-z]+\\Z', 32),
|
||||
"Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens.",
|
||||
'Enter a valid “slug” consisting of letters, numbers, underscores or hyphens.',
|
||||
'invalid'
|
||||
)
|
||||
]))]
|
||||
|
|
|
@ -21,7 +21,7 @@ class DecimalFieldTests(TestCase):
|
|||
# Uses default rounding of ROUND_HALF_EVEN.
|
||||
self.assertEqual(f.to_python(2.0625), Decimal('2.062'))
|
||||
self.assertEqual(f.to_python(2.1875), Decimal('2.188'))
|
||||
msg = "'abc' value must be a decimal number."
|
||||
msg = '“abc” value must be a decimal number.'
|
||||
with self.assertRaisesMessage(ValidationError, msg):
|
||||
f.to_python('abc')
|
||||
|
||||
|
|
|
@ -74,8 +74,8 @@ class TestValidation(SimpleTestCase):
|
|||
self.assertEqual(cm.exception.code, 'invalid')
|
||||
self.assertEqual(
|
||||
cm.exception.message % cm.exception.params,
|
||||
"'not a datetime' value has an invalid format. "
|
||||
"It must be in [DD] [[HH:]MM:]ss[.uuuuuu] format."
|
||||
'“not a datetime” value has an invalid format. '
|
||||
'It must be in [DD] [[HH:]MM:]ss[.uuuuuu] format.'
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -133,7 +133,7 @@ class TestValidation(SimpleTestCase):
|
|||
with self.assertRaises(exceptions.ValidationError) as cm:
|
||||
field.clean('550e8400', None)
|
||||
self.assertEqual(cm.exception.code, 'invalid')
|
||||
self.assertEqual(cm.exception.message % cm.exception.params, "'550e8400' is not a valid UUID.")
|
||||
self.assertEqual(cm.exception.message % cm.exception.params, '“550e8400” is not a valid UUID.')
|
||||
|
||||
def test_uuid_instance_ok(self):
|
||||
field = models.UUIDField()
|
||||
|
|
|
@ -29,5 +29,5 @@ class ModelFormBaseTest(TestCase):
|
|||
|
||||
def test_model_multiple_choice_field_uuid_pk(self):
|
||||
f = forms.ModelMultipleChoiceField(UUIDPK.objects.all())
|
||||
with self.assertRaisesMessage(ValidationError, "'invalid_uuid' is not a valid UUID."):
|
||||
with self.assertRaisesMessage(ValidationError, '“invalid_uuid” is not a valid UUID.'):
|
||||
f.clean(['invalid_uuid'])
|
||||
|
|
|
@ -1358,7 +1358,7 @@ class ModelFormBasicTests(TestCase):
|
|||
self.assertEqual(f.errors['name'], ['This field is required.'])
|
||||
self.assertEqual(
|
||||
f.errors['slug'],
|
||||
["Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens."]
|
||||
['Enter a valid “slug” consisting of letters, numbers, underscores or hyphens.']
|
||||
)
|
||||
self.assertEqual(f.cleaned_data, {'url': 'foo'})
|
||||
msg = "The Category could not be created because the data didn't validate."
|
||||
|
|
|
@ -251,7 +251,7 @@ class TestValidation(PostgreSQLSimpleTestCase):
|
|||
with self.assertRaises(exceptions.ValidationError) as cm:
|
||||
field.clean({'a': 1}, None)
|
||||
self.assertEqual(cm.exception.code, 'not_a_string')
|
||||
self.assertEqual(cm.exception.message % cm.exception.params, 'The value of "a" is not a string or null.')
|
||||
self.assertEqual(cm.exception.message % cm.exception.params, 'The value of “a” is not a string or null.')
|
||||
|
||||
def test_none_allowed_as_value(self):
|
||||
field = HStoreField()
|
||||
|
|
|
@ -426,7 +426,7 @@ class TestFormField(PostgreSQLSimpleTestCase):
|
|||
field = forms.JSONField()
|
||||
with self.assertRaises(exceptions.ValidationError) as cm:
|
||||
field.clean('{some badly formed: json}')
|
||||
self.assertEqual(cm.exception.messages[0], "'{some badly formed: json}' value must be valid JSON.")
|
||||
self.assertEqual(cm.exception.messages[0], '“{some badly formed: json}” value must be valid JSON.')
|
||||
|
||||
def test_formfield(self):
|
||||
model_field = JSONField()
|
||||
|
|
|
@ -1103,8 +1103,8 @@ class NewFormsTests(TestCase):
|
|||
self.assertFalse(form.is_valid())
|
||||
self.assertEqual(
|
||||
form.errors['dt'], [
|
||||
"2011-03-27 02:30:00 couldn't be interpreted in time zone "
|
||||
"Europe/Paris; it may be ambiguous or it may not exist."
|
||||
'2011-03-27 02:30:00 couldn’t be interpreted in time zone '
|
||||
'Europe/Paris; it may be ambiguous or it may not exist.'
|
||||
]
|
||||
)
|
||||
|
||||
|
@ -1114,8 +1114,8 @@ class NewFormsTests(TestCase):
|
|||
self.assertFalse(form.is_valid())
|
||||
self.assertEqual(
|
||||
form.errors['dt'], [
|
||||
"2011-10-30 02:30:00 couldn't be interpreted in time zone "
|
||||
"Europe/Paris; it may be ambiguous or it may not exist."
|
||||
'2011-10-30 02:30:00 couldn’t be interpreted in time zone '
|
||||
'Europe/Paris; it may be ambiguous or it may not exist.'
|
||||
]
|
||||
)
|
||||
|
||||
|
|
|
@ -250,7 +250,7 @@ class TestUtilsText(SimpleTestCase):
|
|||
|
||||
# The format string can be lazy. (string comes from contrib.admin)
|
||||
s = format_lazy(
|
||||
gettext_lazy("Added {name} \"{object}\"."),
|
||||
gettext_lazy('Added {name} “{object}”.'),
|
||||
name='article', object='My first try',
|
||||
)
|
||||
with override('fr'):
|
||||
|
|
|
@ -13,49 +13,49 @@ class ValidationMessagesTest(TestCase):
|
|||
|
||||
def test_autofield_field_raises_error_message(self):
|
||||
f = models.AutoField(primary_key=True)
|
||||
self._test_validation_messages(f, 'fõo', ["'fõo' value must be an integer."])
|
||||
self._test_validation_messages(f, 'fõo', ['“fõo” value must be an integer.'])
|
||||
|
||||
def test_integer_field_raises_error_message(self):
|
||||
f = models.IntegerField()
|
||||
self._test_validation_messages(f, 'fõo', ["'fõo' value must be an integer."])
|
||||
self._test_validation_messages(f, 'fõo', ['“fõo” value must be an integer.'])
|
||||
|
||||
def test_boolean_field_raises_error_message(self):
|
||||
f = models.BooleanField()
|
||||
self._test_validation_messages(f, 'fõo', ["'fõo' value must be either True or False."])
|
||||
self._test_validation_messages(f, 'fõo', ['“fõo” value must be either True or False.'])
|
||||
|
||||
def test_nullable_boolean_field_raises_error_message(self):
|
||||
f = models.BooleanField(null=True)
|
||||
self._test_validation_messages(f, 'fõo', ["'fõo' value must be either True, False, or None."])
|
||||
self._test_validation_messages(f, 'fõo', ['“fõo” value must be either True, False, or None.'])
|
||||
|
||||
def test_float_field_raises_error_message(self):
|
||||
f = models.FloatField()
|
||||
self._test_validation_messages(f, 'fõo', ["'fõo' value must be a float."])
|
||||
self._test_validation_messages(f, 'fõo', ['“fõo” value must be a float.'])
|
||||
|
||||
def test_decimal_field_raises_error_message(self):
|
||||
f = models.DecimalField()
|
||||
self._test_validation_messages(f, 'fõo', ["'fõo' value must be a decimal number."])
|
||||
self._test_validation_messages(f, 'fõo', ['“fõo” value must be a decimal number.'])
|
||||
|
||||
def test_null_boolean_field_raises_error_message(self):
|
||||
f = models.NullBooleanField()
|
||||
self._test_validation_messages(f, 'fõo', ["'fõo' value must be either None, True or False."])
|
||||
self._test_validation_messages(f, 'fõo', ['“fõo” value must be either None, True or False.'])
|
||||
|
||||
def test_date_field_raises_error_message(self):
|
||||
f = models.DateField()
|
||||
self._test_validation_messages(
|
||||
f, 'fõo',
|
||||
["'fõo' value has an invalid date format. It must be in YYYY-MM-DD format."]
|
||||
['“fõo” value has an invalid date format. It must be in YYYY-MM-DD format.']
|
||||
)
|
||||
self._test_validation_messages(
|
||||
f, 'aaaa-10-10',
|
||||
["'aaaa-10-10' value has an invalid date format. It must be in YYYY-MM-DD format."]
|
||||
['“aaaa-10-10” value has an invalid date format. It must be in YYYY-MM-DD format.']
|
||||
)
|
||||
self._test_validation_messages(
|
||||
f, '2011-13-10',
|
||||
["'2011-13-10' value has the correct format (YYYY-MM-DD) but it is an invalid date."]
|
||||
['“2011-13-10” value has the correct format (YYYY-MM-DD) but it is an invalid date.']
|
||||
)
|
||||
self._test_validation_messages(
|
||||
f, '2011-10-32',
|
||||
["'2011-10-32' value has the correct format (YYYY-MM-DD) but it is an invalid date."]
|
||||
['“2011-10-32” value has the correct format (YYYY-MM-DD) but it is an invalid date.']
|
||||
)
|
||||
|
||||
def test_datetime_field_raises_error_message(self):
|
||||
|
@ -63,18 +63,18 @@ class ValidationMessagesTest(TestCase):
|
|||
# Wrong format
|
||||
self._test_validation_messages(
|
||||
f, 'fõo',
|
||||
["'fõo' value has an invalid format. It must be in YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] format."]
|
||||
['“fõo” value has an invalid format. It must be in YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] format.']
|
||||
)
|
||||
# Correct format but invalid date
|
||||
self._test_validation_messages(
|
||||
f, '2011-10-32',
|
||||
["'2011-10-32' value has the correct format (YYYY-MM-DD) but it is an invalid date."]
|
||||
['“2011-10-32” value has the correct format (YYYY-MM-DD) but it is an invalid date.']
|
||||
)
|
||||
# Correct format but invalid date/time
|
||||
self._test_validation_messages(
|
||||
f, '2011-10-32 10:10',
|
||||
["'2011-10-32 10:10' value has the correct format (YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]) "
|
||||
"but it is an invalid date/time."]
|
||||
['“2011-10-32 10:10” value has the correct format (YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]) '
|
||||
'but it is an invalid date/time.']
|
||||
)
|
||||
|
||||
def test_time_field_raises_error_message(self):
|
||||
|
@ -82,10 +82,10 @@ class ValidationMessagesTest(TestCase):
|
|||
# Wrong format
|
||||
self._test_validation_messages(
|
||||
f, 'fõo',
|
||||
["'fõo' value has an invalid format. It must be in HH:MM[:ss[.uuuuuu]] format."]
|
||||
['“fõo” value has an invalid format. It must be in HH:MM[:ss[.uuuuuu]] format.']
|
||||
)
|
||||
# Correct format but invalid time
|
||||
self._test_validation_messages(
|
||||
f, '25:50',
|
||||
["'25:50' value has the correct format (HH:MM[:ss[.uuuuuu]]) but it is an invalid time."]
|
||||
['“25:50” value has the correct format (HH:MM[:ss[.uuuuuu]]) but it is an invalid time.']
|
||||
)
|
||||
|
|
|
@ -44,22 +44,22 @@ class CsrfViewTests(SimpleTestCase):
|
|||
self.assertContains(
|
||||
response,
|
||||
'You are seeing this message because this HTTPS site requires a '
|
||||
''Referer header' to be sent by your Web browser, but '
|
||||
'“Referer header” to be sent by your Web browser, but '
|
||||
'none was sent.',
|
||||
status_code=403,
|
||||
)
|
||||
self.assertContains(
|
||||
response,
|
||||
'If you have configured your browser to disable 'Referer' '
|
||||
'If you have configured your browser to disable “Referer” '
|
||||
'headers, please re-enable them, at least for this site, or for '
|
||||
'HTTPS connections, or for 'same-origin' requests.',
|
||||
'HTTPS connections, or for “same-origin” requests.',
|
||||
status_code=403,
|
||||
)
|
||||
self.assertContains(
|
||||
response,
|
||||
'If you are using the <meta name="referrer" '
|
||||
'content="no-referrer"> tag or including the '
|
||||
''Referrer-Policy: no-referrer' header, please remove them.',
|
||||
'“Referrer-Policy: no-referrer” header, please remove them.',
|
||||
status_code=403,
|
||||
)
|
||||
|
||||
|
|
Loading…
Reference in New Issue