aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/api-guide/versioning.md2
-rw-r--r--docs/topics/release-notes.md33
-rw-r--r--rest_framework/__init__.py2
-rw-r--r--rest_framework/authtoken/serializers.py2
-rw-r--r--rest_framework/authtoken/views.py3
-rw-r--r--rest_framework/locale/fr/LC_MESSAGES/django.mobin6975 -> 9198 bytes
-rw-r--r--rest_framework/locale/fr/LC_MESSAGES/django.po46
-rw-r--r--rest_framework/locale/pt_PT/LC_MESSAGES/django.mobin0 -> 509 bytes
-rw-r--r--rest_framework/locale/pt_PT/LC_MESSAGES/django.po324
-rw-r--r--rest_framework/locale/vi/LC_MESSAGES/django.mobin0 -> 485 bytes
-rw-r--r--rest_framework/locale/vi/LC_MESSAGES/django.po324
-rw-r--r--rest_framework/renderers.py28
-rw-r--r--rest_framework/static/rest_framework/js/default.js4
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
index 68519d45..0b5224a5 100644
--- a/rest_framework/locale/fr/LC_MESSAGES/django.mo
+++ b/rest_framework/locale/fr/LC_MESSAGES/django.mo
Binary files differ
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
new file mode 100644
index 00000000..35db0dd7
--- /dev/null
+++ b/rest_framework/locale/pt_PT/LC_MESSAGES/django.mo
Binary files differ
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
new file mode 100644
index 00000000..dea3a362
--- /dev/null
+++ b/rest_framework/locale/vi/LC_MESSAGES/django.mo
Binary files differ
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 + ']');
}