Version 3.4 release

This commit is contained in:
Tom Christie 2016-07-12 16:51:23 +01:00
parent bff84a2534
commit 13b76eb81e
4 changed files with 95 additions and 109 deletions

View File

@ -89,7 +89,7 @@ The following versions of Python and Django are now supported:
--- ---
## Deprecations and behavioral changes ## Deprecations and changes
The 3.4 release includes very limited deprecation or behavioral changes, and The 3.4 release includes very limited deprecation or behavioral changes, and
should present a straightforward upgrade. should present a straightforward upgrade.
@ -120,6 +120,15 @@ and `TIME_FORMAT` settings.
The renderer behavior can be modified by setting a custom `encoder_class` The renderer behavior can be modified by setting a custom `encoder_class`
attribute on a `JSONRenderer` subclass. attribute on a `JSONRenderer` subclass.
---
## Bug fixes and other functionality
This release includes work from across [67 different pull requests][milestone].
The full set of itemized release notes [are available here][release-notes].
[sponsors]: https://fund.django-rest-framework.org/topics/funding/#our-sponsors [sponsors]: https://fund.django-rest-framework.org/topics/funding/#our-sponsors
[moss]: mozilla-grant.md [moss]: mozilla-grant.md
[funding]: funding.md [funding]: funding.md
@ -127,3 +136,5 @@ attribute on a `JSONRenderer` subclass.
[tut-7]: ../../tutorial/7-schemas-and-client-libraries/ [tut-7]: ../../tutorial/7-schemas-and-client-libraries/
[schema-generation]: ../../api-guide/schemas/ [schema-generation]: ../../api-guide/schemas/
[api-clients]: api-clients.md [api-clients]: api-clients.md
[milestone]: https://github.com/tomchristie/django-rest-framework/pulls?q=is%3Apr+is%3Aclosed+milestone%3A%223.4.0+Release%22
[release-notes]: release-notes.md

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-03-01 18:38+0100\n" "POT-Creation-Date: 2016-07-12 16:13+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -17,40 +17,40 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: authentication.py:71 #: authentication.py:73
msgid "Invalid basic header. No credentials provided." msgid "Invalid basic header. No credentials provided."
msgstr "" msgstr ""
#: authentication.py:74 #: authentication.py:76
msgid "Invalid basic header. Credentials string should not contain spaces." msgid "Invalid basic header. Credentials string should not contain spaces."
msgstr "" msgstr ""
#: authentication.py:80 #: authentication.py:82
msgid "Invalid basic header. Credentials not correctly base64 encoded." msgid "Invalid basic header. Credentials not correctly base64 encoded."
msgstr "" msgstr ""
#: authentication.py:97 #: authentication.py:99
msgid "Invalid username/password." msgid "Invalid username/password."
msgstr "" msgstr ""
#: authentication.py:100 authentication.py:195 #: authentication.py:102 authentication.py:198
msgid "User inactive or deleted." msgid "User inactive or deleted."
msgstr "" msgstr ""
#: authentication.py:173 #: authentication.py:176
msgid "Invalid token header. No credentials provided." msgid "Invalid token header. No credentials provided."
msgstr "" msgstr ""
#: authentication.py:176 #: authentication.py:179
msgid "Invalid token header. Token string should not contain spaces." msgid "Invalid token header. Token string should not contain spaces."
msgstr "" msgstr ""
#: authentication.py:182 #: authentication.py:185
msgid "" msgid ""
"Invalid token header. Token string should not contain invalid characters." "Invalid token header. Token string should not contain invalid characters."
msgstr "" msgstr ""
#: authentication.py:192 #: authentication.py:195
msgid "Invalid token." msgid "Invalid token."
msgstr "" msgstr ""
@ -58,23 +58,23 @@ msgstr ""
msgid "Auth Token" msgid "Auth Token"
msgstr "" msgstr ""
#: authtoken/models.py:21 #: authtoken/models.py:15
msgid "Key" msgid "Key"
msgstr "" msgstr ""
#: authtoken/models.py:23 #: authtoken/models.py:18
msgid "User" msgid "User"
msgstr "" msgstr ""
#: authtoken/models.py:24 #: authtoken/models.py:20
msgid "Created" msgid "Created"
msgstr "" msgstr ""
#: authtoken/models.py:33 #: authtoken/models.py:29
msgid "Token" msgid "Token"
msgstr "" msgstr ""
#: authtoken/models.py:34 #: authtoken/models.py:30
msgid "Tokens" msgid "Tokens"
msgstr "" msgstr ""
@ -123,7 +123,6 @@ msgid "Not found."
msgstr "" msgstr ""
#: exceptions.py:109 #: exceptions.py:109
#, python-brace-format
msgid "Method \"{method}\" not allowed." msgid "Method \"{method}\" not allowed."
msgstr "" msgstr ""
@ -132,7 +131,6 @@ msgid "Could not satisfy the request Accept header."
msgstr "" msgstr ""
#: exceptions.py:132 #: exceptions.py:132
#, python-brace-format
msgid "Unsupported media type \"{media_type}\" in request." msgid "Unsupported media type \"{media_type}\" in request."
msgstr "" msgstr ""
@ -140,212 +138,199 @@ msgstr ""
msgid "Request was throttled." msgid "Request was throttled."
msgstr "" msgstr ""
#: fields.py:266 relations.py:206 relations.py:239 validators.py:79 #: fields.py:269 relations.py:206 relations.py:239 validators.py:98
#: validators.py:162 #: validators.py:181
msgid "This field is required." msgid "This field is required."
msgstr "" msgstr ""
#: fields.py:267 #: fields.py:270
msgid "This field may not be null." msgid "This field may not be null."
msgstr "" msgstr ""
#: fields.py:603 fields.py:634 #: fields.py:608 fields.py:639
#, python-brace-format
msgid "\"{input}\" is not a valid boolean." msgid "\"{input}\" is not a valid boolean."
msgstr "" msgstr ""
#: fields.py:669 #: fields.py:674
msgid "This field may not be blank." msgid "This field may not be blank."
msgstr "" msgstr ""
#: fields.py:670 fields.py:1664 #: fields.py:675 fields.py:1675
#, python-brace-format
msgid "Ensure this field has no more than {max_length} characters." msgid "Ensure this field has no more than {max_length} characters."
msgstr "" msgstr ""
#: fields.py:671 #: fields.py:676
#, python-brace-format
msgid "Ensure this field has at least {min_length} characters." msgid "Ensure this field has at least {min_length} characters."
msgstr "" msgstr ""
#: fields.py:708 #: fields.py:713
msgid "Enter a valid email address." msgid "Enter a valid email address."
msgstr "" msgstr ""
#: fields.py:719 #: fields.py:724
msgid "This value does not match the required pattern." msgid "This value does not match the required pattern."
msgstr "" msgstr ""
#: fields.py:730 #: fields.py:735
msgid "" msgid ""
"Enter a valid \"slug\" consisting of letters, numbers, underscores or " "Enter a valid \"slug\" consisting of letters, numbers, underscores or "
"hyphens." "hyphens."
msgstr "" msgstr ""
#: fields.py:742 #: fields.py:747
msgid "Enter a valid URL." msgid "Enter a valid URL."
msgstr "" msgstr ""
#: fields.py:755 #: fields.py:760
#, python-brace-format
msgid "\"{value}\" is not a valid UUID." msgid "\"{value}\" is not a valid UUID."
msgstr "" msgstr ""
#: fields.py:791 #: fields.py:796
msgid "Enter a valid IPv4 or IPv6 address." msgid "Enter a valid IPv4 or IPv6 address."
msgstr "" msgstr ""
#: fields.py:816 #: fields.py:821
msgid "A valid integer is required." msgid "A valid integer is required."
msgstr "" msgstr ""
#: fields.py:817 fields.py:852 fields.py:885 #: fields.py:822 fields.py:857 fields.py:891
#, python-brace-format
msgid "Ensure this value is less than or equal to {max_value}." msgid "Ensure this value is less than or equal to {max_value}."
msgstr "" msgstr ""
#: fields.py:818 fields.py:853 fields.py:886 #: fields.py:823 fields.py:858 fields.py:892
#, python-brace-format
msgid "Ensure this value is greater than or equal to {min_value}." msgid "Ensure this value is greater than or equal to {min_value}."
msgstr "" msgstr ""
#: fields.py:819 fields.py:854 fields.py:890 #: fields.py:824 fields.py:859 fields.py:896
msgid "String value too large." msgid "String value too large."
msgstr "" msgstr ""
#: fields.py:851 fields.py:884 #: fields.py:856 fields.py:890
msgid "A valid number is required." msgid "A valid number is required."
msgstr "" msgstr ""
#: fields.py:887 #: fields.py:893
#, python-brace-format
msgid "Ensure that there are no more than {max_digits} digits in total." msgid "Ensure that there are no more than {max_digits} digits in total."
msgstr "" msgstr ""
#: fields.py:888 #: fields.py:894
#, python-brace-format
msgid "Ensure that there are no more than {max_decimal_places} decimal places." msgid "Ensure that there are no more than {max_decimal_places} decimal places."
msgstr "" msgstr ""
#: fields.py:889 #: fields.py:895
#, python-brace-format
msgid "" msgid ""
"Ensure that there are no more than {max_whole_digits} digits before the " "Ensure that there are no more than {max_whole_digits} digits before the "
"decimal point." "decimal point."
msgstr "" msgstr ""
#: fields.py:1004 #: fields.py:1025
#, python-brace-format
msgid "Datetime has wrong format. Use one of these formats instead: {format}." msgid "Datetime has wrong format. Use one of these formats instead: {format}."
msgstr "" msgstr ""
#: fields.py:1005 #: fields.py:1026
msgid "Expected a datetime but got a date." msgid "Expected a datetime but got a date."
msgstr "" msgstr ""
#: fields.py:1082 #: fields.py:1103
#, python-brace-format
msgid "Date has wrong format. Use one of these formats instead: {format}." msgid "Date has wrong format. Use one of these formats instead: {format}."
msgstr "" msgstr ""
#: fields.py:1083 #: fields.py:1104
msgid "Expected a date but got a datetime." msgid "Expected a date but got a datetime."
msgstr "" msgstr ""
#: fields.py:1151 #: fields.py:1170
#, python-brace-format
msgid "Time has wrong format. Use one of these formats instead: {format}." msgid "Time has wrong format. Use one of these formats instead: {format}."
msgstr "" msgstr ""
#: fields.py:1215 #: fields.py:1232
#, python-brace-format
msgid "Duration has wrong format. Use one of these formats instead: {format}." msgid "Duration has wrong format. Use one of these formats instead: {format}."
msgstr "" msgstr ""
#: fields.py:1240 fields.py:1289 #: fields.py:1251 fields.py:1300
#, python-brace-format
msgid "\"{input}\" is not a valid choice." msgid "\"{input}\" is not a valid choice."
msgstr "" msgstr ""
#: fields.py:1243 relations.py:71 relations.py:442 #: fields.py:1254 relations.py:71 relations.py:441
#, python-brace-format
msgid "More than {count} items..." msgid "More than {count} items..."
msgstr "" msgstr ""
#: fields.py:1290 fields.py:1437 relations.py:438 serializers.py:520 #: fields.py:1301 fields.py:1448 relations.py:437 serializers.py:524
#, python-brace-format
msgid "Expected a list of items but got type \"{input_type}\"." msgid "Expected a list of items but got type \"{input_type}\"."
msgstr "" msgstr ""
#: fields.py:1291 #: fields.py:1302
msgid "This selection may not be empty." msgid "This selection may not be empty."
msgstr "" msgstr ""
#: fields.py:1328 #: fields.py:1339
#, python-brace-format
msgid "\"{input}\" is not a valid path choice." msgid "\"{input}\" is not a valid path choice."
msgstr "" msgstr ""
#: fields.py:1347 #: fields.py:1358
msgid "No file was submitted." msgid "No file was submitted."
msgstr "" msgstr ""
#: fields.py:1348 #: fields.py:1359
msgid "The submitted data was not a file. Check the encoding type on the form." msgid "The submitted data was not a file. Check the encoding type on the form."
msgstr "" msgstr ""
#: fields.py:1349 #: fields.py:1360
msgid "No filename could be determined." msgid "No filename could be determined."
msgstr "" msgstr ""
#: fields.py:1350 #: fields.py:1361
msgid "The submitted file is empty." msgid "The submitted file is empty."
msgstr "" msgstr ""
#: fields.py:1351 #: fields.py:1362
#, python-brace-format
msgid "" msgid ""
"Ensure this filename has at most {max_length} characters (it has {length})." "Ensure this filename has at most {max_length} characters (it has {length})."
msgstr "" msgstr ""
#: fields.py:1399 #: fields.py:1410
msgid "" msgid ""
"Upload a valid image. The file you uploaded was either not an image or a " "Upload a valid image. The file you uploaded was either not an image or a "
"corrupted image." "corrupted image."
msgstr "" msgstr ""
#: fields.py:1438 relations.py:439 serializers.py:521 #: fields.py:1449 relations.py:438 serializers.py:525
msgid "This list may not be empty." msgid "This list may not be empty."
msgstr "" msgstr ""
#: fields.py:1491 #: fields.py:1502
#, python-brace-format
msgid "Expected a dictionary of items but got type \"{input_type}\"." msgid "Expected a dictionary of items but got type \"{input_type}\"."
msgstr "" msgstr ""
#: fields.py:1538 #: fields.py:1549
msgid "Value must be valid JSON." msgid "Value must be valid JSON."
msgstr "" msgstr ""
#: filters.py:35 templates/rest_framework/filters/django_filter.html.py:5 #: filters.py:36 templates/rest_framework/filters/django_filter.html:5
msgid "Submit" msgid "Submit"
msgstr "" msgstr ""
#: pagination.py:189 #: filters.py:336
msgid "ascending"
msgstr ""
#: filters.py:337
msgid "descending"
msgstr ""
#: pagination.py:193
msgid "Invalid page." msgid "Invalid page."
msgstr "" msgstr ""
#: pagination.py:407 #: pagination.py:427
msgid "Invalid cursor" msgid "Invalid cursor"
msgstr "" msgstr ""
#: relations.py:207 #: relations.py:207
#, python-brace-format
msgid "Invalid pk \"{pk_value}\" - object does not exist." msgid "Invalid pk \"{pk_value}\" - object does not exist."
msgstr "" msgstr ""
#: relations.py:208 #: relations.py:208
#, python-brace-format
msgid "Incorrect type. Expected pk value, received {data_type}." msgid "Incorrect type. Expected pk value, received {data_type}."
msgstr "" msgstr ""
@ -362,25 +347,22 @@ msgid "Invalid hyperlink - Object does not exist."
msgstr "" msgstr ""
#: relations.py:243 #: relations.py:243
#, python-brace-format
msgid "Incorrect type. Expected URL string, received {data_type}." msgid "Incorrect type. Expected URL string, received {data_type}."
msgstr "" msgstr ""
#: relations.py:402 #: relations.py:401
#, python-brace-format
msgid "Object with {slug_name}={value} does not exist." msgid "Object with {slug_name}={value} does not exist."
msgstr "" msgstr ""
#: relations.py:403 #: relations.py:402
msgid "Invalid value." msgid "Invalid value."
msgstr "" msgstr ""
#: serializers.py:326 #: serializers.py:326
#, python-brace-format
msgid "Invalid data. Expected a dictionary, but got {datatype}." msgid "Invalid data. Expected a dictionary, but got {datatype}."
msgstr "" msgstr ""
#: templates/rest_framework/admin.html:118 #: templates/rest_framework/admin.html:116
#: templates/rest_framework/base.html:128 #: templates/rest_framework/base.html:128
msgid "Filters" msgid "Filters"
msgstr "" msgstr ""
@ -410,27 +392,23 @@ msgstr ""
msgid "No items to select." msgid "No items to select."
msgstr "" msgstr ""
#: validators.py:24 #: validators.py:43
msgid "This field must be unique." msgid "This field must be unique."
msgstr "" msgstr ""
#: validators.py:78 #: validators.py:97
#, python-brace-format
msgid "The fields {field_names} must make a unique set." msgid "The fields {field_names} must make a unique set."
msgstr "" msgstr ""
#: validators.py:226 #: validators.py:245
#, python-brace-format
msgid "This field must be unique for the \"{date_field}\" date." msgid "This field must be unique for the \"{date_field}\" date."
msgstr "" msgstr ""
#: validators.py:241 #: validators.py:260
#, python-brace-format
msgid "This field must be unique for the \"{date_field}\" month." msgid "This field must be unique for the \"{date_field}\" month."
msgstr "" msgstr ""
#: validators.py:254 #: validators.py:273
#, python-brace-format
msgid "This field must be unique for the \"{date_field}\" year." msgid "This field must be unique for the \"{date_field}\" year."
msgstr "" msgstr ""
@ -438,15 +416,19 @@ msgstr ""
msgid "Invalid version in \"Accept\" header." msgid "Invalid version in \"Accept\" header."
msgstr "" msgstr ""
#: versioning.py:73 versioning.py:115 #: versioning.py:73
msgid "Invalid version in URL path." msgid "Invalid version in URL path."
msgstr "" msgstr ""
#: versioning.py:144 #: versioning.py:115
msgid "Invalid version in URL path. Does not match any version namespace."
msgstr ""
#: versioning.py:147
msgid "Invalid version in hostname." msgid "Invalid version in hostname."
msgstr "" msgstr ""
#: versioning.py:166 #: versioning.py:169
msgid "Invalid version in query parameter." msgid "Invalid version in query parameter."
msgstr "" msgstr ""

View File

@ -19,8 +19,6 @@ back to the defaults.
""" """
from __future__ import unicode_literals from __future__ import unicode_literals
import warnings
from django.conf import settings from django.conf import settings
from django.test.signals import setting_changed from django.test.signals import setting_changed
from django.utils import six from django.utils import six

View File

@ -1,7 +1,5 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import warnings
from django.test import TestCase from django.test import TestCase
from rest_framework.settings import APISettings from rest_framework.settings import APISettings
@ -25,13 +23,10 @@ class TestSettings(TestCase):
Make sure user is alerted with an error when a removed setting Make sure user is alerted with an error when a removed setting
is set. is set.
""" """
with warnings.catch_warnings(record=True) as w: with self.assertRaises(RuntimeError):
warnings.simplefilter("always")
APISettings({ APISettings({
'MAX_PAGINATE_BY': 100 'MAX_PAGINATE_BY': 100
}) })
self.assertEqual(len(w), 1)
self.assertTrue(issubclass(w[-1].category, DeprecationWarning))
class TestSettingTypes(TestCase): class TestSettingTypes(TestCase):