diff options
| -rw-r--r-- | docs/api-guide/versioning.md | 2 | ||||
| -rw-r--r-- | docs/topics/release-notes.md | 33 | ||||
| -rw-r--r-- | rest_framework/__init__.py | 2 | ||||
| -rw-r--r-- | rest_framework/authtoken/serializers.py | 2 | ||||
| -rw-r--r-- | rest_framework/authtoken/views.py | 3 | ||||
| -rw-r--r-- | rest_framework/locale/fr/LC_MESSAGES/django.mo | bin | 6975 -> 9198 bytes | |||
| -rw-r--r-- | rest_framework/locale/fr/LC_MESSAGES/django.po | 46 | ||||
| -rw-r--r-- | rest_framework/locale/pt_PT/LC_MESSAGES/django.mo | bin | 0 -> 509 bytes | |||
| -rw-r--r-- | rest_framework/locale/pt_PT/LC_MESSAGES/django.po | 324 | ||||
| -rw-r--r-- | rest_framework/locale/vi/LC_MESSAGES/django.mo | bin | 0 -> 485 bytes | |||
| -rw-r--r-- | rest_framework/locale/vi/LC_MESSAGES/django.po | 324 | ||||
| -rw-r--r-- | rest_framework/renderers.py | 28 | ||||
| -rw-r--r-- | rest_framework/static/rest_framework/js/default.js | 4 |
13 files changed, 739 insertions, 29 deletions
diff --git a/docs/api-guide/versioning.md b/docs/api-guide/versioning.md index a227a4a3..846698fc 100644 --- a/docs/api-guide/versioning.md +++ b/docs/api-guide/versioning.md @@ -31,6 +31,8 @@ How you vary the API behavior is up to you, but one example you might typically The `reverse` function included by REST framework ties in with the versioning scheme. You need to make sure to include the current `request` as a keyword argument, like so. + from rest_framework.reverse import reverse + reverse('bookings-list', request=request) The above function will apply any URL transformations appropriate to the request version. For example: diff --git a/docs/topics/release-notes.md b/docs/topics/release-notes.md index 84d310c2..535fb463 100644 --- a/docs/topics/release-notes.md +++ b/docs/topics/release-notes.md @@ -40,6 +40,23 @@ You can determine your currently installed version using `pip freeze`: ## 3.0.x series +### 3.1.1 + +**Date**: [19th March 2015][3.1.1-milestone]. + +* **Security fix**: Escape tab switching cookie name in browsable API. +* Display input forms in browsable API if `serializer_class` is used, even when `get_serializer` method does not exist on the view. ([#2743](gh2743)) +* Use a password input for the AuthTokenSerializer. ([#2741](gh2741)) +* Fix missing anchor closing tag after next button. ([#2691][gh2691]) +* Fix `lookup_url_kwarg` handling in viewsets. ([#2685][gh2685], [#2591][gh2591]) +* Fix problem with imporing `rest_framework.views` in `apps.py` ([#2678][gh2678]) +* LimitOffsetPagination raises `TypeError` if PAGE_SIZE not set ([#2667][gh2667], [#2700][gh2700]) +* German translation for `min_value` field error message references `max_value`. ([#2645][gh2645]) +* Remove `MergeDict`. ([#2640][gh2640]) +* Support serializing unsaved models with related fields. ([#2637][gh2637], [#2641][gh2641]) +* Allow blank/null on radio.html choices. ([#2631][gh2631]) + + ### 3.1.0 **Date**: [5th March 2015][3.1.0-milestone]. @@ -161,6 +178,8 @@ For older release notes, [please see the version 2.x documentation](old-release- [3.0.3-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.0.3+Release%22 [3.0.4-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.0.4+Release%22 [3.0.5-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.0.5+Release%22 +[3.1.0-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.1.0+Release%22 +[3.1.1-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.1.1+Release%22 <!-- 3.0.1 --> [gh2013]: https://github.com/tomchristie/django-rest-framework/issues/2013 @@ -259,3 +278,17 @@ For older release notes, [please see the version 2.x documentation](old-release- [gh2519]: https://github.com/tomchristie/django-rest-framework/issues/2519 [gh2524]: https://github.com/tomchristie/django-rest-framework/issues/2524 [gh2530]: https://github.com/tomchristie/django-rest-framework/issues/2530 +<!-- 3.1.1 --> +[gh2691]: https://github.com/tomchristie/django-rest-framework/issues/2691 +[gh2685]: https://github.com/tomchristie/django-rest-framework/issues/2685 +[gh2591]: https://github.com/tomchristie/django-rest-framework/issues/2591 +[gh2678]: https://github.com/tomchristie/django-rest-framework/issues/2678 +[gh2667]: https://github.com/tomchristie/django-rest-framework/issues/2667 +[gh2700]: https://github.com/tomchristie/django-rest-framework/issues/2700 +[gh2645]: https://github.com/tomchristie/django-rest-framework/issues/2645 +[gh2640]: https://github.com/tomchristie/django-rest-framework/issues/2640 +[gh2637]: https://github.com/tomchristie/django-rest-framework/issues/2637 +[gh2641]: https://github.com/tomchristie/django-rest-framework/issues/2641 +[gh2631]: https://github.com/tomchristie/django-rest-framework/issues/2631 +[gh2741]: https://github.com/tomchristie/django-rest-framework/issues/2641 +[gh2743]: https://github.com/tomchristie/django-rest-framework/issues/2643
\ No newline at end of file diff --git a/rest_framework/__init__.py b/rest_framework/__init__.py index f8bbeee3..62bdd2c5 100644 --- a/rest_framework/__init__.py +++ b/rest_framework/__init__.py @@ -8,7 +8,7 @@ ______ _____ _____ _____ __ """ __title__ = 'Django REST framework' -__version__ = '3.1.0' +__version__ = '3.1.1' __author__ = 'Tom Christie' __license__ = 'BSD 2-Clause' __copyright__ = 'Copyright 2011-2015 Tom Christie' diff --git a/rest_framework/authtoken/serializers.py b/rest_framework/authtoken/serializers.py index 37ade255..597aeed2 100644 --- a/rest_framework/authtoken/serializers.py +++ b/rest_framework/authtoken/serializers.py @@ -6,7 +6,7 @@ from rest_framework import exceptions, serializers class AuthTokenSerializer(serializers.Serializer): username = serializers.CharField() - password = serializers.CharField() + password = serializers.CharField(style={'input_type': 'password'}) def validate(self, attrs): username = attrs.get('username') diff --git a/rest_framework/authtoken/views.py b/rest_framework/authtoken/views.py index b75c2e25..66bbc49b 100644 --- a/rest_framework/authtoken/views.py +++ b/rest_framework/authtoken/views.py @@ -11,9 +11,10 @@ class ObtainAuthToken(APIView): permission_classes = () parser_classes = (parsers.FormParser, parsers.MultiPartParser, parsers.JSONParser,) renderer_classes = (renderers.JSONRenderer,) + serializer_class = AuthTokenSerializer def post(self, request): - serializer = AuthTokenSerializer(data=request.data) + serializer = self.serializer_class(data=request.data) serializer.is_valid(raise_exception=True) user = serializer.validated_data['user'] token, created = Token.objects.get_or_create(user=user) diff --git a/rest_framework/locale/fr/LC_MESSAGES/django.mo b/rest_framework/locale/fr/LC_MESSAGES/django.mo Binary files differindex 68519d45..0b5224a5 100644 --- a/rest_framework/locale/fr/LC_MESSAGES/django.mo +++ b/rest_framework/locale/fr/LC_MESSAGES/django.mo diff --git a/rest_framework/locale/fr/LC_MESSAGES/django.po b/rest_framework/locale/fr/LC_MESSAGES/django.po index e8597c30..a942af6d 100644 --- a/rest_framework/locale/fr/LC_MESSAGES/django.po +++ b/rest_framework/locale/fr/LC_MESSAGES/django.po @@ -5,13 +5,15 @@ # Translators: # Etienne Desgagné <etienne.desgagne@evimbec.ca>, 2015 # Martin Maillard <martin.maillard@gmail.com>, 2015 +# Martin Maillard <martin.maillard@gmail.com>, 2015 +# Xavier Ordoquy <xordoquy@linovia.com>, 2015 msgid "" msgstr "" "Project-Id-Version: Django REST framework\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-01-30 16:23+0000\n" -"PO-Revision-Date: 2015-01-30 16:27+0000\n" -"Last-Translator: Thomas Christie <tom@tomchristie.com>\n" +"PO-Revision-Date: 2015-03-19 22:23+0000\n" +"Last-Translator: Xavier Ordoquy <xordoquy@linovia.com>\n" "Language-Team: French (http://www.transifex.com/projects/p/django-rest-framework/language/fr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -73,7 +75,7 @@ msgstr "Vous n'avez pas la permission d'effectuer cette action." #: exceptions.py:93 msgid "Not found." -msgstr "" +msgstr "Pas trouvé." #: exceptions.py:98 msgid "Method \"{method}\" not allowed." @@ -81,15 +83,15 @@ msgstr "Méthode \"{method}\" non autorisée." #: exceptions.py:109 msgid "Could not satisfy the request Accept header." -msgstr "" +msgstr "L'en-tête « Accept » n'a pas pu être satisfaite." #: exceptions.py:121 msgid "Unsupported media type \"{media_type}\" in request." -msgstr "" +msgstr "Type de média \"{media_type}\" non supporté." #: exceptions.py:134 msgid "Request was throttled." -msgstr "" +msgstr "Requête ralentie." #: fields.py:153 relations.py:132 relations.py:156 validators.py:77 #: validators.py:155 @@ -136,11 +138,11 @@ msgstr "Saisissez une URL valide." #: fields.py:638 msgid "\"{value}\" is not a valid UUID." -msgstr "" +msgstr "\"{value}\" n'est pas un UUID valide." #: fields.py:657 msgid "A valid integer is required." -msgstr "Saisissez un nombre entier valide." +msgstr "Un nombre entier valide est requis." #: fields.py:658 fields.py:692 fields.py:725 msgid "Ensure this value is less than or equal to {max_value}." @@ -175,23 +177,23 @@ msgstr "Assurez-vous qu'il n'y a pas plus de {max_whole_digits} chiffres avant l #: fields.py:813 msgid "Datetime has wrong format. Use one of these formats instead: {format}." -msgstr "" +msgstr "La date + heure n'a pas le bon format. Utilisez un des formats suivants : {format}." #: fields.py:814 msgid "Expected a datetime but got a date." -msgstr "" +msgstr "Attendait une date + heure mais a reçu une date." #: fields.py:878 msgid "Date has wrong format. Use one of these formats instead: {format}." -msgstr "" +msgstr "La date n'a pas le bon format. Utilisez un des formats suivants : {format}." #: fields.py:879 msgid "Expected a date but got a datetime." -msgstr "" +msgstr "Attendait une date mais a reçu une date + heure." #: fields.py:936 msgid "Time has wrong format. Use one of these formats instead: {format}." -msgstr "" +msgstr "L'heure n'a pas le bon format. Utilisez un des formats suivants : {format}." #: fields.py:992 fields.py:1036 msgid "\"{input}\" is not a valid choice." @@ -199,7 +201,7 @@ msgstr "\"{input}\" n'est pas un choix valide." #: fields.py:1037 fields.py:1151 serializers.py:482 msgid "Expected a list of items but got type \"{input_type}\"." -msgstr "" +msgstr "Attendait une liste d'éléments mais a reçu \"{input_type}\"." #: fields.py:1067 msgid "No file was submitted." @@ -231,7 +233,7 @@ msgstr "Transférez une image valide. Le fichier que vous avez transféré n'est #: fields.py:1188 msgid "Expected a dictionary of items but got type \"{input_type}\"." -msgstr "" +msgstr "Attendait un dictionnaire d'éléments mais a reçu \"{input_type}\"." #: pagination.py:221 msgid "Invalid page \"{page_number}\": {message}." @@ -239,7 +241,7 @@ msgstr "Page \"{page_number}\" non valide : {message}." #: pagination.py:442 msgid "Invalid cursor" -msgstr "" +msgstr "Curseur non valide" #: relations.py:133 msgid "Invalid pk \"{pk_value}\" - object does not exist." @@ -247,23 +249,23 @@ msgstr "Clé primaire \"{pk_value}\" non valide - l'objet n'existe pas." #: relations.py:134 msgid "Incorrect type. Expected pk value, received {data_type}." -msgstr "" +msgstr "Type incorrect. Attendait une clé primaire, a reçu {data_type}." #: relations.py:157 msgid "Invalid hyperlink - No URL match." -msgstr "" +msgstr "Lien non valide : pas d'URL correspondante." #: relations.py:158 msgid "Invalid hyperlink - Incorrect URL match." -msgstr "" +msgstr "Lien non valide : URL correspondante incorrecte." #: relations.py:159 msgid "Invalid hyperlink - Object does not exist." -msgstr "" +msgstr "Lien non valide : l'objet n'existe pas." #: relations.py:160 msgid "Incorrect type. Expected URL string, received {data_type}." -msgstr "" +msgstr "Type incorrect. Attendait une URL, a reçu {data_type}." #: relations.py:295 msgid "Object with {slug_name}={value} does not exist." @@ -275,7 +277,7 @@ msgstr "Valeur non valide." #: serializers.py:299 msgid "Invalid data. Expected a dictionary, but got {datatype}." -msgstr "" +msgstr "Donnée non valide. Attendait un dictionnaire, a reçu {datatype}." #: validators.py:22 msgid "This field must be unique." diff --git a/rest_framework/locale/pt_PT/LC_MESSAGES/django.mo b/rest_framework/locale/pt_PT/LC_MESSAGES/django.mo Binary files differnew file mode 100644 index 00000000..35db0dd7 --- /dev/null +++ b/rest_framework/locale/pt_PT/LC_MESSAGES/django.mo diff --git a/rest_framework/locale/pt_PT/LC_MESSAGES/django.po b/rest_framework/locale/pt_PT/LC_MESSAGES/django.po new file mode 100644 index 00000000..9da496fe --- /dev/null +++ b/rest_framework/locale/pt_PT/LC_MESSAGES/django.po @@ -0,0 +1,324 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Django REST framework\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-01-30 16:23+0000\n" +"PO-Revision-Date: 2015-01-02 10:46+0000\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: Portuguese (Portugal) (http://www.transifex.com/projects/p/django-rest-framework/language/pt_PT/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: pt_PT\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: authentication.py:69 +msgid "Invalid basic header. No credentials provided." +msgstr "" + +#: authentication.py:72 +msgid "Invalid basic header. Credentials string should not contain spaces." +msgstr "" + +#: authentication.py:78 +msgid "Invalid basic header. Credentials not correctly base64 encoded." +msgstr "" + +#: authentication.py:90 +msgid "Invalid username/password." +msgstr "" + +#: authentication.py:156 +msgid "Invalid token header. No credentials provided." +msgstr "" + +#: authentication.py:159 +msgid "Invalid token header. Token string should not contain spaces." +msgstr "" + +#: authentication.py:168 +msgid "Invalid token." +msgstr "" + +#: authentication.py:171 +msgid "User inactive or deleted." +msgstr "" + +#: exceptions.py:38 +msgid "A server error occurred." +msgstr "" + +#: exceptions.py:73 +msgid "Malformed request." +msgstr "" + +#: exceptions.py:78 +msgid "Incorrect authentication credentials." +msgstr "" + +#: exceptions.py:83 +msgid "Authentication credentials were not provided." +msgstr "" + +#: exceptions.py:88 +msgid "You do not have permission to perform this action." +msgstr "" + +#: exceptions.py:93 +msgid "Not found." +msgstr "" + +#: exceptions.py:98 +msgid "Method \"{method}\" not allowed." +msgstr "" + +#: exceptions.py:109 +msgid "Could not satisfy the request Accept header." +msgstr "" + +#: exceptions.py:121 +msgid "Unsupported media type \"{media_type}\" in request." +msgstr "" + +#: exceptions.py:134 +msgid "Request was throttled." +msgstr "" + +#: fields.py:153 relations.py:132 relations.py:156 validators.py:77 +#: validators.py:155 +msgid "This field is required." +msgstr "" + +#: fields.py:154 +msgid "This field may not be null." +msgstr "" + +#: fields.py:487 fields.py:515 +msgid "\"{input}\" is not a valid boolean." +msgstr "" + +#: fields.py:550 +msgid "This field may not be blank." +msgstr "" + +#: fields.py:551 fields.py:1324 +msgid "Ensure this field has no more than {max_length} characters." +msgstr "" + +#: fields.py:552 +msgid "Ensure this field has at least {min_length} characters." +msgstr "" + +#: fields.py:587 +msgid "Enter a valid email address." +msgstr "" + +#: fields.py:604 +msgid "This value does not match the required pattern." +msgstr "" + +#: fields.py:615 +msgid "" +"Enter a valid \"slug\" consisting of letters, numbers, underscores or " +"hyphens." +msgstr "" + +#: fields.py:627 +msgid "Enter a valid URL." +msgstr "" + +#: fields.py:638 +msgid "\"{value}\" is not a valid UUID." +msgstr "" + +#: fields.py:657 +msgid "A valid integer is required." +msgstr "" + +#: fields.py:658 fields.py:692 fields.py:725 +msgid "Ensure this value is less than or equal to {max_value}." +msgstr "" + +#: fields.py:659 fields.py:693 fields.py:726 +msgid "Ensure this value is greater than or equal to {min_value}." +msgstr "" + +#: fields.py:660 fields.py:694 fields.py:730 +msgid "String value too large." +msgstr "" + +#: fields.py:691 fields.py:724 +msgid "A valid number is required." +msgstr "" + +#: fields.py:727 +msgid "Ensure that there are no more than {max_digits} digits in total." +msgstr "" + +#: fields.py:728 +msgid "" +"Ensure that there are no more than {max_decimal_places} decimal places." +msgstr "" + +#: fields.py:729 +msgid "" +"Ensure that there are no more than {max_whole_digits} digits before the " +"decimal point." +msgstr "" + +#: fields.py:813 +msgid "Datetime has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:814 +msgid "Expected a datetime but got a date." +msgstr "" + +#: fields.py:878 +msgid "Date has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:879 +msgid "Expected a date but got a datetime." +msgstr "" + +#: fields.py:936 +msgid "Time has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:992 fields.py:1036 +msgid "\"{input}\" is not a valid choice." +msgstr "" + +#: fields.py:1037 fields.py:1151 serializers.py:482 +msgid "Expected a list of items but got type \"{input_type}\"." +msgstr "" + +#: fields.py:1067 +msgid "No file was submitted." +msgstr "" + +#: fields.py:1068 +msgid "" +"The submitted data was not a file. Check the encoding type on the form." +msgstr "" + +#: fields.py:1069 +msgid "No filename could be determined." +msgstr "" + +#: fields.py:1070 +msgid "The submitted file is empty." +msgstr "" + +#: fields.py:1071 +msgid "" +"Ensure this filename has at most {max_length} characters (it has {length})." +msgstr "" + +#: fields.py:1113 +msgid "" +"Upload a valid image. The file you uploaded was either not an image or a " +"corrupted image." +msgstr "" + +#: fields.py:1188 +msgid "Expected a dictionary of items but got type \"{input_type}\"." +msgstr "" + +#: pagination.py:221 +msgid "Invalid page \"{page_number}\": {message}." +msgstr "" + +#: pagination.py:442 +msgid "Invalid cursor" +msgstr "" + +#: relations.py:133 +msgid "Invalid pk \"{pk_value}\" - object does not exist." +msgstr "" + +#: relations.py:134 +msgid "Incorrect type. Expected pk value, received {data_type}." +msgstr "" + +#: relations.py:157 +msgid "Invalid hyperlink - No URL match." +msgstr "" + +#: relations.py:158 +msgid "Invalid hyperlink - Incorrect URL match." +msgstr "" + +#: relations.py:159 +msgid "Invalid hyperlink - Object does not exist." +msgstr "" + +#: relations.py:160 +msgid "Incorrect type. Expected URL string, received {data_type}." +msgstr "" + +#: relations.py:295 +msgid "Object with {slug_name}={value} does not exist." +msgstr "" + +#: relations.py:296 +msgid "Invalid value." +msgstr "" + +#: serializers.py:299 +msgid "Invalid data. Expected a dictionary, but got {datatype}." +msgstr "" + +#: validators.py:22 +msgid "This field must be unique." +msgstr "" + +#: validators.py:76 +msgid "The fields {field_names} must make a unique set." +msgstr "" + +#: validators.py:219 +msgid "This field must be unique for the \"{date_field}\" date." +msgstr "" + +#: validators.py:234 +msgid "This field must be unique for the \"{date_field}\" month." +msgstr "" + +#: validators.py:247 +msgid "This field must be unique for the \"{date_field}\" year." +msgstr "" + +#: versioning.py:39 +msgid "Invalid version in \"Accept\" header." +msgstr "" + +#: versioning.py:70 versioning.py:112 +msgid "Invalid version in URL path." +msgstr "" + +#: versioning.py:138 +msgid "Invalid version in hostname." +msgstr "" + +#: versioning.py:160 +msgid "Invalid version in query parameter." +msgstr "" + +#: authtoken/serializers.py:20 +msgid "User account is disabled." +msgstr "" + +#: authtoken/serializers.py:23 +msgid "Unable to log in with provided credentials." +msgstr "" + +#: authtoken/serializers.py:26 +msgid "Must include \"username\" and \"password\"." +msgstr "" diff --git a/rest_framework/locale/vi/LC_MESSAGES/django.mo b/rest_framework/locale/vi/LC_MESSAGES/django.mo Binary files differnew file mode 100644 index 00000000..dea3a362 --- /dev/null +++ b/rest_framework/locale/vi/LC_MESSAGES/django.mo diff --git a/rest_framework/locale/vi/LC_MESSAGES/django.po b/rest_framework/locale/vi/LC_MESSAGES/django.po new file mode 100644 index 00000000..b378e4de --- /dev/null +++ b/rest_framework/locale/vi/LC_MESSAGES/django.po @@ -0,0 +1,324 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: Django REST framework\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-01-30 16:23+0000\n" +"PO-Revision-Date: 2015-01-02 10:46+0000\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: Vietnamese (http://www.transifex.com/projects/p/django-rest-framework/language/vi/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: vi\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: authentication.py:69 +msgid "Invalid basic header. No credentials provided." +msgstr "" + +#: authentication.py:72 +msgid "Invalid basic header. Credentials string should not contain spaces." +msgstr "" + +#: authentication.py:78 +msgid "Invalid basic header. Credentials not correctly base64 encoded." +msgstr "" + +#: authentication.py:90 +msgid "Invalid username/password." +msgstr "" + +#: authentication.py:156 +msgid "Invalid token header. No credentials provided." +msgstr "" + +#: authentication.py:159 +msgid "Invalid token header. Token string should not contain spaces." +msgstr "" + +#: authentication.py:168 +msgid "Invalid token." +msgstr "" + +#: authentication.py:171 +msgid "User inactive or deleted." +msgstr "" + +#: exceptions.py:38 +msgid "A server error occurred." +msgstr "" + +#: exceptions.py:73 +msgid "Malformed request." +msgstr "" + +#: exceptions.py:78 +msgid "Incorrect authentication credentials." +msgstr "" + +#: exceptions.py:83 +msgid "Authentication credentials were not provided." +msgstr "" + +#: exceptions.py:88 +msgid "You do not have permission to perform this action." +msgstr "" + +#: exceptions.py:93 +msgid "Not found." +msgstr "" + +#: exceptions.py:98 +msgid "Method \"{method}\" not allowed." +msgstr "" + +#: exceptions.py:109 +msgid "Could not satisfy the request Accept header." +msgstr "" + +#: exceptions.py:121 +msgid "Unsupported media type \"{media_type}\" in request." +msgstr "" + +#: exceptions.py:134 +msgid "Request was throttled." +msgstr "" + +#: fields.py:153 relations.py:132 relations.py:156 validators.py:77 +#: validators.py:155 +msgid "This field is required." +msgstr "" + +#: fields.py:154 +msgid "This field may not be null." +msgstr "" + +#: fields.py:487 fields.py:515 +msgid "\"{input}\" is not a valid boolean." +msgstr "" + +#: fields.py:550 +msgid "This field may not be blank." +msgstr "" + +#: fields.py:551 fields.py:1324 +msgid "Ensure this field has no more than {max_length} characters." +msgstr "" + +#: fields.py:552 +msgid "Ensure this field has at least {min_length} characters." +msgstr "" + +#: fields.py:587 +msgid "Enter a valid email address." +msgstr "" + +#: fields.py:604 +msgid "This value does not match the required pattern." +msgstr "" + +#: fields.py:615 +msgid "" +"Enter a valid \"slug\" consisting of letters, numbers, underscores or " +"hyphens." +msgstr "" + +#: fields.py:627 +msgid "Enter a valid URL." +msgstr "" + +#: fields.py:638 +msgid "\"{value}\" is not a valid UUID." +msgstr "" + +#: fields.py:657 +msgid "A valid integer is required." +msgstr "" + +#: fields.py:658 fields.py:692 fields.py:725 +msgid "Ensure this value is less than or equal to {max_value}." +msgstr "" + +#: fields.py:659 fields.py:693 fields.py:726 +msgid "Ensure this value is greater than or equal to {min_value}." +msgstr "" + +#: fields.py:660 fields.py:694 fields.py:730 +msgid "String value too large." +msgstr "" + +#: fields.py:691 fields.py:724 +msgid "A valid number is required." +msgstr "" + +#: fields.py:727 +msgid "Ensure that there are no more than {max_digits} digits in total." +msgstr "" + +#: fields.py:728 +msgid "" +"Ensure that there are no more than {max_decimal_places} decimal places." +msgstr "" + +#: fields.py:729 +msgid "" +"Ensure that there are no more than {max_whole_digits} digits before the " +"decimal point." +msgstr "" + +#: fields.py:813 +msgid "Datetime has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:814 +msgid "Expected a datetime but got a date." +msgstr "" + +#: fields.py:878 +msgid "Date has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:879 +msgid "Expected a date but got a datetime." +msgstr "" + +#: fields.py:936 +msgid "Time has wrong format. Use one of these formats instead: {format}." +msgstr "" + +#: fields.py:992 fields.py:1036 +msgid "\"{input}\" is not a valid choice." +msgstr "" + +#: fields.py:1037 fields.py:1151 serializers.py:482 +msgid "Expected a list of items but got type \"{input_type}\"." +msgstr "" + +#: fields.py:1067 +msgid "No file was submitted." +msgstr "" + +#: fields.py:1068 +msgid "" +"The submitted data was not a file. Check the encoding type on the form." +msgstr "" + +#: fields.py:1069 +msgid "No filename could be determined." +msgstr "" + +#: fields.py:1070 +msgid "The submitted file is empty." +msgstr "" + +#: fields.py:1071 +msgid "" +"Ensure this filename has at most {max_length} characters (it has {length})." +msgstr "" + +#: fields.py:1113 +msgid "" +"Upload a valid image. The file you uploaded was either not an image or a " +"corrupted image." +msgstr "" + +#: fields.py:1188 +msgid "Expected a dictionary of items but got type \"{input_type}\"." +msgstr "" + +#: pagination.py:221 +msgid "Invalid page \"{page_number}\": {message}." +msgstr "" + +#: pagination.py:442 +msgid "Invalid cursor" +msgstr "" + +#: relations.py:133 +msgid "Invalid pk \"{pk_value}\" - object does not exist." +msgstr "" + +#: relations.py:134 +msgid "Incorrect type. Expected pk value, received {data_type}." +msgstr "" + +#: relations.py:157 +msgid "Invalid hyperlink - No URL match." +msgstr "" + +#: relations.py:158 +msgid "Invalid hyperlink - Incorrect URL match." +msgstr "" + +#: relations.py:159 +msgid "Invalid hyperlink - Object does not exist." +msgstr "" + +#: relations.py:160 +msgid "Incorrect type. Expected URL string, received {data_type}." +msgstr "" + +#: relations.py:295 +msgid "Object with {slug_name}={value} does not exist." +msgstr "" + +#: relations.py:296 +msgid "Invalid value." +msgstr "" + +#: serializers.py:299 +msgid "Invalid data. Expected a dictionary, but got {datatype}." +msgstr "" + +#: validators.py:22 +msgid "This field must be unique." +msgstr "" + +#: validators.py:76 +msgid "The fields {field_names} must make a unique set." +msgstr "" + +#: validators.py:219 +msgid "This field must be unique for the \"{date_field}\" date." +msgstr "" + +#: validators.py:234 +msgid "This field must be unique for the \"{date_field}\" month." +msgstr "" + +#: validators.py:247 +msgid "This field must be unique for the \"{date_field}\" year." +msgstr "" + +#: versioning.py:39 +msgid "Invalid version in \"Accept\" header." +msgstr "" + +#: versioning.py:70 versioning.py:112 +msgid "Invalid version in URL path." +msgstr "" + +#: versioning.py:138 +msgid "Invalid version in hostname." +msgstr "" + +#: versioning.py:160 +msgid "Invalid version in query parameter." +msgstr "" + +#: authtoken/serializers.py:20 +msgid "User account is disabled." +msgstr "" + +#: authtoken/serializers.py:23 +msgid "Unable to log in with provided credentials." +msgstr "" + +#: authtoken/serializers.py:26 +msgid "Must include \"username\" and \"password\"." +msgstr "" diff --git a/rest_framework/renderers.py b/rest_framework/renderers.py index 920d2bc4..2350344c 100644 --- a/rest_framework/renderers.py +++ b/rest_framework/renderers.py @@ -421,6 +421,14 @@ class BrowsableAPIRenderer(BaseRenderer): return False # Doesn't have permissions return True + def _get_serializer(self, serializer_class, view_instance, request, *args, **kwargs): + kwargs['context'] = { + 'request': request, + 'format': self.format, + 'view': view_instance + } + return serializer_class(*args, **kwargs) + def get_rendered_html_form(self, data, view, method, request): """ Return a string representing a rendered HTML form, possibly bound to @@ -457,8 +465,11 @@ class BrowsableAPIRenderer(BaseRenderer): if method in ('DELETE', 'OPTIONS'): return True # Don't actually need to return a form + has_serializer = getattr(view, 'get_serializer', None) + has_serializer_class = getattr(view, 'serializer_class', None) + if ( - not getattr(view, 'get_serializer', None) or + (not has_serializer and not has_serializer_class) or not any(is_form_media_type(parser.media_type) for parser in view.parser_classes) ): return @@ -466,10 +477,19 @@ class BrowsableAPIRenderer(BaseRenderer): if existing_serializer is not None: serializer = existing_serializer else: - if method in ('PUT', 'PATCH'): - serializer = view.get_serializer(instance=instance, **kwargs) + if has_serializer: + if method in ('PUT', 'PATCH'): + serializer = view.get_serializer(instance=instance, **kwargs) + else: + serializer = view.get_serializer(**kwargs) else: - serializer = view.get_serializer(**kwargs) + # at this point we must have a serializer_class + if method in ('PUT', 'PATCH'): + serializer = self._get_serializer(view.serializer_class, view, + request, instance=instance, **kwargs) + else: + serializer = self._get_serializer(view.serializer_class, view, + request, **kwargs) if hasattr(serializer, 'initial_data'): serializer.is_valid() diff --git a/rest_framework/static/rest_framework/js/default.js b/rest_framework/static/rest_framework/js/default.js index c8812132..22e5efde 100644 --- a/rest_framework/static/rest_framework/js/default.js +++ b/rest_framework/static/rest_framework/js/default.js @@ -45,6 +45,10 @@ var selectedTab = null; var selectedTabName = getCookie('tabstyle'); if (selectedTabName) { + selectedTabName = selectedTabName.replace(/[^a-z-]/g, ''); +} + +if (selectedTabName) { selectedTab = $('.form-switcher a[name=' + selectedTabName + ']'); } |
