Internationalization docs

This commit is contained in:
Tom Christie 2015-02-06 11:37:29 +00:00
parent 09488ad4da
commit 53716f6152
5 changed files with 113 additions and 412 deletions

View File

@ -199,7 +199,6 @@ General guides to using REST framework.
* [3.1 Announcement][3.1-announcement] * [3.1 Announcement][3.1-announcement]
* [Kickstarter Announcement][kickstarter-announcement] * [Kickstarter Announcement][kickstarter-announcement]
* [Release Notes][release-notes] * [Release Notes][release-notes]
* [Credits][credits]
## Development ## Development
@ -314,7 +313,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[3.1-announcement]: topics/3.1-announcement.md [3.1-announcement]: topics/3.1-announcement.md
[kickstarter-announcement]: topics/kickstarter-announcement.md [kickstarter-announcement]: topics/kickstarter-announcement.md
[release-notes]: topics/release-notes.md [release-notes]: topics/release-notes.md
[credits]: topics/credits.md
[tox]: http://testrun.org/tox/latest/ [tox]: http://testrun.org/tox/latest/

View File

@ -10,7 +10,7 @@ The pagination API has been improved, making it both easier to use, and more pow
Until now, there has only been a single built-in pagination style in REST framework. We now have page, limit/offset and cursor based schemes included by default. Until now, there has only been a single built-in pagination style in REST framework. We now have page, limit/offset and cursor based schemes included by default.
The cursor based pagination scheme is particularly smart, and is a better approach for clients iterating through large or frequently changing result sets. The scheme supports paging against non-unique indexes, by using both cursor and limit/offset information. Credit to David Cramer for [this blog post](http://cramer.io/2011/03/08/building-cursors-for-the-disqus-api/) on the subject. The cursor based pagination scheme is particularly smart, and is a better approach for clients iterating through large or frequently changing result sets. The scheme supports paging against non-unique indexes, by using both cursor and limit/offset information. It also allows for both forward and reverse cursor pagination. Much credit goes to David Cramer for [this blog post](http://cramer.io/2011/03/08/building-cursors-for-the-disqus-api/) on the subject.
#### Pagination controls in the browsable API. #### Pagination controls in the browsable API.
@ -34,15 +34,74 @@ We've made it easier to build versioned APIs. Built-in schemes for versioning in
When using a URL based scheme, hyperlinked serializers will resolve relationships to the same API version as used on the incoming request. When using a URL based scheme, hyperlinked serializers will resolve relationships to the same API version as used on the incoming request.
**TODO**: Example. For example, when using `NamespaceVersioning`, and the following hyperlinked serializer:
class AccountsSerializer(serializer.HyperlinkedModelSerializer):
class Meta:
model = Accounts
fields = ('account_name', 'users')
The output representation would match the version used on the incoming request. Like so:
GET http://example.org/v2/accounts/10 # Version 'v2'
{
"account_name": "europa",
"users": [
"http://example.org/v2/users/12", # Version 'v2'
"http://example.org/v2/users/54",
"http://example.org/v2/users/87"
]
}
## Internationalization ## Internationalization
REST framework now includes a built-in set of translations, and supports internationalized error responses. This allows you to either change the default language, or to allow clients to specify the language via the `Accept-Language` header. REST framework now includes a built-in set of translations, and supports internationalized error responses. This allows you to either change the default language, or to allow clients to specify the language via the `Accept-Language` header.
**TODO**: Example. You can change the default language by using the standard Django `LANGUAGE_CODE` setting:
**TODO**: Credit. LANGUAGE_CODE = "es-es"
You can turn on per-request language requests by adding `LocalMiddleware` to your `MIDDLEWARE_CLASSES` setting:
MIDDLEWARE_CLASSES = [
...
'django.middleware.locale.LocaleMiddleware'
]
When per-request internationalization is enabled, client requests will respect the `Accept-Language` header where possible. For example, let's make a request for an unsupported media type:
**Request**
GET /api/users HTTP/1.1
Accept: application/xml
Accept-Language: es-es
Host: example.org
**Response**
HTTP/1.0 406 NOT ACCEPTABLE
{
"detail": "No se ha podido satisfacer la solicitud de cabecera de Accept."
}
Note that the structure of the error responses is still the same. We still have a `details` key in the response. If needed you can modify this behavior too, by using a [custom exception handler][custom-exception-handler].
We include built-in translations both for standard exception cases, and for serializer validation errors.
The full list of supported languages can be found on our [Transifex project page](https://www.transifex.com/projects/p/django-rest-framework/).
If you only wish to support a subset of the supported languages, use Django's standard `LANGUAGES` setting:
LANGUAGES = [
('de', _('German')),
('en', _('English')),
]
For more details, see the [internationalization documentation](internationalization.md).
Many thanks to [Craig Blaszczyk](https://github.com/jakul) for helping push this through.
## New field types ## New field types
@ -50,6 +109,10 @@ Django 1.8's new `ArrayField`, `HStoreField` and `UUIDField` are now all fully s
This work also means that we now have both `serializers.DictField()`, and `serializers.ListField()` types, allowing you to express and validate a wider set of representations. This work also means that we now have both `serializers.DictField()`, and `serializers.ListField()` types, allowing you to express and validate a wider set of representations.
If you're building a new 1.8 project, then you should probably consider using `UUIDField` as the primary keys for all your models. This style will work automatically with hyperlinked serializers, returning URLs in the following style:
http://example.org/api/purchases/9b1a433f-e90d-4948-848b-300fdc26365d
## ModelSerializer API ## ModelSerializer API
The serializer redesign in 3.0 did not include any public API for modifying how ModelSerializer classes automatically generate a set of fields from a given mode class. We've now re-introduced an API for this, allowing you to create new ModelSerializer base classes that behave differently, such as using a different default style for relationships. The serializer redesign in 3.0 did not include any public API for modifying how ModelSerializer classes automatically generate a set of fields from a given mode class. We've now re-introduced an API for this, allowing you to create new ModelSerializer base classes that behave differently, such as using a different default style for relationships.
@ -85,6 +148,8 @@ And modify your settings, like so:
] ]
} }
Thanks go to the latest member of our maintenance team, [José Padilla](https://github.com/jpadilla/), for handling this work and taking on ownership of these packages.
# What's next? # What's next?
The next focus will be on HTML renderings of API output and will include: The next focus will be on HTML renderings of API output and will include:
@ -93,4 +158,6 @@ The next focus will be on HTML renderings of API output and will include:
* Filtering controls built-in to the browsable API. * Filtering controls built-in to the browsable API.
* An alternative admin-style interface. * An alternative admin-style interface.
This will either be made as a single 3.2 release, or split across two separate releases, with the HTML forms and filter controls coming in 3.2, and the admin-style interface coming in a 3.3 release. This will either be made as a single 3.2 release, or split across two separate releases, with the HTML forms and filter controls coming in 3.2, and the admin-style interface coming in a 3.3 release.
[custom-exception-handler]: ../api-guide/exceptions.md#custom-exception-handling

View File

@ -1,404 +0,0 @@
# Credits
The following people have helped make REST framework great.
* Tom Christie - [tomchristie]
* Marko Tibold - [markotibold]
* Paul Miller - [paulmillr]
* Sébastien Piquemal - [sebpiq]
* Carmen Wick - [cwick]
* Alex Ehlke - [aehlke]
* Alen Mujezinovic - [flashingpumpkin]
* Carles Barrobés - [txels]
* Michael Fötsch - [mfoetsch]
* David Larlet - [david]
* Andrew Straw - [astraw]
* Zeth - [zeth]
* Fernando Zunino - [fzunino]
* Jens Alm - [ulmus]
* Craig Blaszczyk - [jakul]
* Garcia Solero - [garciasolero]
* Tom Drummond - [devioustree]
* Danilo Bargen - [dbrgn]
* Andrew McCloud - [amccloud]
* Thomas Steinacher - [thomasst]
* Meurig Freeman - [meurig]
* Anthony Nemitz - [anemitz]
* Ewoud Kohl van Wijngaarden - [ekohl]
* Michael Ding - [yandy]
* Mjumbe Poe - [mjumbewu]
* Natim - [natim]
* Sebastian Żurek - [sebzur]
* Benoit C - [dzen]
* Chris Pickett - [bunchesofdonald]
* Ben Timby - [btimby]
* Michele Lazzeri - [michelelazzeri-nextage]
* Camille Harang - [mammique]
* Paul Oswald - [poswald]
* Sean C. Farley - [scfarley]
* Daniel Izquierdo - [izquierdo]
* Can Yavuz - [tschan]
* Shawn Lewis - [shawnlewis]
* Alec Perkins - [alecperkins]
* Michael Barrett - [phobologic]
* Mathieu Dhondt - [laundromat]
* Johan Charpentier - [cyberj]
* Jamie Matthews - [j4mie]
* Mattbo - [mattbo]
* Max Hurl - [maximilianhurl]
* Tomi Pajunen - [eofs]
* Rob Dobson - [rdobson]
* Daniel Vaca Araujo - [diviei]
* Madis Väin - [madisvain]
* Stephan Groß - [minddust]
* Pavel Savchenko - [asfaltboy]
* Otto Yiu - [ottoyiu]
* Jacob Magnusson - [jmagnusson]
* Osiloke Harold Emoekpere - [osiloke]
* Michael Shepanski - [mjs7231]
* Toni Michel - [tonimichel]
* Ben Konrath - [benkonrath]
* Marc Aymerich - [glic3rinu]
* Ludwig Kraatz - [ludwigkraatz]
* Rob Romano - [robromano]
* Eugene Mechanism - [mechanism]
* Jonas Liljestrand - [jonlil]
* Justin Davis - [irrelative]
* Dustin Bachrach - [dbachrach]
* Mark Shirley - [maspwr]
* Olivier Aubert - [oaubert]
* Yuri Prezument - [yprez]
* Fabian Buechler - [fabianbuechler]
* Mark Hughes - [mhsparks]
* Michael van de Waeter - [mvdwaeter]
* Reinout van Rees - [reinout]
* Michael Richards - [justanotherbody]
* Ben Roberts - [roberts81]
* Venkata Subramanian Mahalingam - [annacoder]
* George Kappel - [gkappel]
* Colin Murtaugh - [cmurtaugh]
* Simon Pantzare - [pilt]
* Szymon Teżewski - [sunscrapers]
* Joel Marcotte - [joual]
* Trey Hunner - [treyhunner]
* Roman Akinfold - [akinfold]
* Toran Billups - [toranb]
* Sébastien Béal - [sebastibe]
* Andrew Hankinson - [ahankinson]
* Juan Riaza - [juanriaza]
* Michael Mior - [michaelmior]
* Marc Tamlyn - [mjtamlyn]
* Richard Wackerbarth - [wackerbarth]
* Johannes Spielmann - [shezi]
* James Cleveland - [radiosilence]
* Steve Gregory - [steve-gregory]
* Federico Capoano - [nemesisdesign]
* Bruno Renié - [brutasse]
* Kevin Stone - [kevinastone]
* Guglielmo Celata - [guglielmo]
* Mike Tums - [mktums]
* Michael Elovskikh - [wronglink]
* Michał Jaworski - [swistakm]
* Andrea de Marco - [z4r]
* Fernando Rocha - [fernandogrd]
* Xavier Ordoquy - [xordoquy]
* Adam Wentz - [floppya]
* Andreas Pelme - [pelme]
* Ryan Detzel - [ryanrdetzel]
* Omer Katz - [thedrow]
* Wiliam Souza - [waa]
* Jonas Braun - [iekadou]
* Ian Dash - [bitmonkey]
* Bouke Haarsma - [bouke]
* Pierre Dulac - [dulaccc]
* Dave Kuhn - [kuhnza]
* Sitong Peng - [stoneg]
* Victor Shih - [vshih]
* Atle Frenvik Sveen - [atlefren]
* J Paul Reed - [preed]
* Matt Majewski - [forgingdestiny]
* Jerome Chen - [chenjyw]
* Andrew Hughes - [eyepulp]
* Daniel Hepper - [dhepper]
* Hamish Campbell - [hamishcampbell]
* Marlon Bailey - [avinash240]
* James Summerfield - [jsummerfield]
* Andy Freeland - [rouge8]
* Craig de Stigter - [craigds]
* Pablo Recio - [pyriku]
* Brian Zambrano - [brianz]
* Òscar Vilaplana - [grimborg]
* Ryan Kaskel - [ryankask]
* Andy McKay - [andymckay]
* Matteo Suppo - [matteosuppo]
* Karol Majta - [lolek09]
* David Jones - [commonorgarden]
* Andrew Tarzwell - [atarzwell]
* Michal Dvořák - [mikee2185]
* Markus Törnqvist - [mjtorn]
* Pascal Borreli - [pborreli]
* Alex Burgel - [aburgel]
* David Medina - [copitux]
* Areski Belaid - [areski]
* Ethan Freman - [mindlace]
* David Sanders - [davesque]
* Philip Douglas - [freakydug]
* Igor Kalat - [trwired]
* Rudolf Olah - [omouse]
* Gertjan Oude Lohuis - [gertjanol]
* Matthias Jacob - [cyroxx]
* Pavel Zinovkin - [pzinovkin]
* Will Kahn-Greene - [willkg]
* Kevin Brown - [kevin-brown]
* Rodrigo Martell - [coderigo]
* James Rutherford - [jimr]
* Ricky Rosario - [rlr]
* Veronica Lynn - [kolvia]
* Dan Stephenson - [etos]
* Martin Clement - [martync]
* Jeremy Satterfield - [jsatt]
* Christopher Paolini - [chrispaolini]
* Filipe A Ximenes - [filipeximenes]
* Ramiro Morales - [ramiro]
* Krzysztof Jurewicz - [krzysiekj]
* Eric Buehl - [ericbuehl]
* Kristian Øllegaard - [kristianoellegaard]
* Alexander Akhmetov - [alexander-akhmetov]
* Andrey Antukh - [niwibe]
* Mathieu Pillard - [diox]
* Edmond Wong - [edmondwong]
* Ben Reilly - [bwreilly]
* Tai Lee - [mrmachine]
* Markus Kaiserswerth - [mkai]
* Henry Clifford - [hcliff]
* Thomas Badaud - [badale]
* Colin Huang - [tamakisquare]
* Ross McFarland - [ross]
* Jacek Bzdak - [jbzdak]
* Alexander Lukanin - [alexanderlukanin13]
* Yamila Moreno - [yamila-moreno]
* Rob Hudson - [robhudson]
* Alex Good - [alexjg]
* Ian Foote - [ian-foote]
* Chuck Harmston - [chuckharmston]
* Philip Forget - [philipforget]
* Artem Mezhenin - [amezhenin]
Many thanks to everyone who's contributed to the project.
## Additional thanks
The documentation is built with [Bootstrap] and [Markdown].
Project hosting is with [GitHub].
Continuous integration testing is managed with [Travis CI][travis-ci].
The [live sandbox][sandbox] is hosted on [Heroku].
Various inspiration taken from the [Rails], [Piston], [Tastypie], [Dagny] and [django-viewsets] projects.
Development of REST framework 2.0 was sponsored by [DabApps].
## Contact
For usage questions please see the [REST framework discussion group][group].
You can also contact [@_tomchristie][twitter] directly on twitter.
[twitter]: http://twitter.com/_tomchristie
[bootstrap]: http://twitter.github.com/bootstrap/
[markdown]: http://daringfireball.net/projects/markdown/
[github]: https://github.com/tomchristie/django-rest-framework
[travis-ci]: https://secure.travis-ci.org/tomchristie/django-rest-framework
[rails]: http://rubyonrails.org/
[piston]: https://bitbucket.org/jespern/django-piston
[tastypie]: https://github.com/toastdriven/django-tastypie
[dagny]: https://github.com/zacharyvoase/dagny
[django-viewsets]: https://github.com/BertrandBordage/django-viewsets
[dabapps]: http://lab.dabapps.com
[sandbox]: http://restframework.herokuapp.com/
[heroku]: http://www.heroku.com/
[group]: https://groups.google.com/forum/?fromgroups#!forum/django-rest-framework
[tomchristie]: https://github.com/tomchristie
[markotibold]: https://github.com/markotibold
[paulmillr]: https://github.com/paulmillr
[sebpiq]: https://github.com/sebpiq
[cwick]: https://github.com/cwick
[aehlke]: https://github.com/aehlke
[flashingpumpkin]: https://github.com/flashingpumpkin
[txels]: https://github.com/txels
[mfoetsch]: https://github.com/mfoetsch
[david]: https://github.com/david
[astraw]: https://github.com/astraw
[zeth]: https://github.com/zeth
[fzunino]: https://github.com/fzunino
[ulmus]: https://github.com/ulmus
[jakul]: https://github.com/jakul
[garciasolero]: https://github.com/garciasolero
[devioustree]: https://github.com/devioustree
[dbrgn]: https://github.com/dbrgn
[amccloud]: https://github.com/amccloud
[thomasst]: https://github.com/thomasst
[meurig]: https://github.com/meurig
[anemitz]: https://github.com/anemitz
[ekohl]: https://github.com/ekohl
[yandy]: https://github.com/yandy
[mjumbewu]: https://github.com/mjumbewu
[natim]: https://github.com/natim
[sebzur]: https://github.com/sebzur
[dzen]: https://github.com/dzen
[bunchesofdonald]: https://github.com/bunchesofdonald
[btimby]: https://github.com/btimby
[michelelazzeri-nextage]: https://github.com/michelelazzeri-nextage
[mammique]: https://github.com/mammique
[poswald]: https://github.com/poswald
[scfarley]: https://github.com/scfarley
[izquierdo]: https://github.com/izquierdo
[tschan]: https://github.com/tschan
[shawnlewis]: https://github.com/shawnlewis
[alecperkins]: https://github.com/alecperkins
[phobologic]: https://github.com/phobologic
[laundromat]: https://github.com/laundromat
[cyberj]: https://github.com/cyberj
[j4mie]: https://github.com/j4mie
[mattbo]: https://github.com/mattbo
[maximilianhurl]: https://github.com/maximilianhurl
[eofs]: https://github.com/eofs
[rdobson]: https://github.com/rdobson
[diviei]: https://github.com/diviei
[madisvain]: https://github.com/madisvain
[minddust]: https://github.com/minddust
[asfaltboy]: https://github.com/asfaltboy
[ottoyiu]: https://github.com/OttoYiu
[jmagnusson]: https://github.com/jmagnusson
[osiloke]: https://github.com/osiloke
[mjs7231]: https://github.com/mjs7231
[tonimichel]: https://github.com/tonimichel
[benkonrath]: https://github.com/benkonrath
[glic3rinu]: https://github.com/glic3rinu
[ludwigkraatz]: https://github.com/ludwigkraatz
[robromano]: https://github.com/robromano
[mechanism]: https://github.com/mechanism
[jonlil]: https://github.com/jonlil
[irrelative]: https://github.com/irrelative
[dbachrach]: https://github.com/dbachrach
[maspwr]: https://github.com/maspwr
[oaubert]: https://github.com/oaubert
[yprez]: https://github.com/yprez
[fabianbuechler]: https://github.com/fabianbuechler
[mhsparks]: https://github.com/mhsparks
[mvdwaeter]: https://github.com/mvdwaeter
[reinout]: https://github.com/reinout
[justanotherbody]: https://github.com/justanotherbody
[roberts81]: https://github.com/roberts81
[annacoder]: https://github.com/annacoder
[gkappel]: https://github.com/gkappel
[cmurtaugh]: https://github.com/cmurtaugh
[pilt]: https://github.com/pilt
[sunscrapers]: https://github.com/sunscrapers
[joual]: https://github.com/joual
[treyhunner]: https://github.com/treyhunner
[akinfold]: https://github.com/akinfold
[toranb]: https://github.com/toranb
[sebastibe]: https://github.com/sebastibe
[ahankinson]: https://github.com/ahankinson
[juanriaza]: https://github.com/juanriaza
[michaelmior]: https://github.com/michaelmior
[mjtamlyn]: https://github.com/mjtamlyn
[wackerbarth]: https://github.com/wackerbarth
[shezi]: https://github.com/shezi
[radiosilence]: https://github.com/radiosilence
[steve-gregory]: https://github.com/steve-gregory
[nemesisdesign]: https://github.com/nemesisdesign
[brutasse]: https://github.com/brutasse
[kevinastone]: https://github.com/kevinastone
[guglielmo]: https://github.com/guglielmo
[mktums]: https://github.com/mktums
[wronglink]: https://github.com/wronglink
[swistakm]: https://github.com/swistakm
[z4r]: https://github.com/z4r
[fernandogrd]: https://github.com/fernandogrd
[xordoquy]: https://github.com/xordoquy
[floppya]: https://github.com/floppya
[pelme]: https://github.com/pelme
[ryanrdetzel]: https://github.com/ryanrdetzel
[thedrow]: https://github.com/thedrow
[waa]: https://github.com/wiliamsouza
[iekadou]: https://github.com/iekadou
[bitmonkey]: https://github.com/bitmonkey
[bouke]: https://github.com/bouke
[dulaccc]: https://github.com/dulaccc
[kuhnza]: https://github.com/kuhnza
[stoneg]: https://github.com/stoneg
[vshih]: https://github.com/vshih
[atlefren]: https://github.com/atlefren
[preed]: https://github.com/preed
[forgingdestiny]: https://github.com/forgingdestiny
[chenjyw]: https://github.com/chenjyw
[eyepulp]: https://github.com/eyepulp
[dhepper]: https://github.com/dhepper
[hamishcampbell]: https://github.com/hamishcampbell
[avinash240]: https://github.com/avinash240
[jsummerfield]: https://github.com/jsummerfield
[rouge8]: https://github.com/rouge8
[craigds]: https://github.com/craigds
[pyriku]: https://github.com/pyriku
[brianz]: https://github.com/brianz
[grimborg]: https://github.com/grimborg
[ryankask]: https://github.com/ryankask
[andymckay]: https://github.com/andymckay
[matteosuppo]: https://github.com/matteosuppo
[lolek09]: https://github.com/lolek09
[commonorgarden]: https://github.com/commonorgarden
[atarzwell]: https://github.com/atarzwell
[mikee2185]: https://github.com/mikee2185
[mjtorn]: https://github.com/mjtorn
[pborreli]: https://github.com/pborreli
[aburgel]: https://github.com/aburgel
[copitux]: https://github.com/copitux
[areski]: https://github.com/areski
[mindlace]: https://github.com/mindlace
[davesque]: https://github.com/davesque
[freakydug]: https://github.com/freakydug
[trwired]: https://github.com/trwired
[omouse]: https://github.com/omouse
[gertjanol]: https://github.com/gertjanol
[cyroxx]: https://github.com/cyroxx
[pzinovkin]: https://github.com/pzinovkin
[coderigo]: https://github.com/coderigo
[willkg]: https://github.com/willkg
[kevin-brown]: https://github.com/kevin-brown
[jimr]: https://github.com/jimr
[rlr]: https://github.com/rlr
[kolvia]: https://github.com/kolvia
[etos]: https://github.com/etos
[martync]: https://github.com/martync
[jsatt]: https://github.com/jsatt
[chrispaolini]: https://github.com/chrispaolini
[filipeximenes]: https://github.com/filipeximenes
[ramiro]: https://github.com/ramiro
[krzysiekj]: https://github.com/krzysiekj
[ericbuehl]: https://github.com/ericbuehl
[kristianoellegaard]: https://github.com/kristianoellegaard
[alexander-akhmetov]: https://github.com/alexander-akhmetov
[niwibe]: https://github.com/niwibe
[diox]: https://github.com/diox
[edmondwong]: https://github.com/edmondwong
[bwreilly]: https://github.com/bwreilly
[mrmachine]: https://github.com/mrmachine
[mkai]: https://github.com/mkai
[hcliff]: https://github.com/hcliff
[badale]: https://github.com/badale
[tamakisquare]: https://github.com/tamakisquare
[ross]: https://github.com/ross
[jbzdak]: https://github.com/jbzdak
[alexanderlukanin13]: https://github.com/alexanderlukanin13
[yamila-moreno]: https://github.com/yamila-moreno
[robhudson]: https://github.com/robhudson
[alexjg]: https://github.com/alexjg
[ian-foote]: https://github.com/ian-foote
[chuckharmston]: https://github.com/chuckharmston
[philipforget]: https://github.com/philipforget
[amezhenin]: https://github.com/amezhenin

View File

@ -11,12 +11,53 @@ Doing so will allow you to:
* Select a language other than English as the default, using the standard `LANGUAGE_CODE` Django setting. * Select a language other than English as the default, using the standard `LANGUAGE_CODE` Django setting.
* Allow clients to choose a language themselves, using the `LocaleMiddleware` included with Django. A typical usage for API clients would be to include an `Accept-Language` request header. * Allow clients to choose a language themselves, using the `LocaleMiddleware` included with Django. A typical usage for API clients would be to include an `Accept-Language` request header.
## Enabling internationalized APIs
You can change the default language by using the standard Django `LANGUAGE_CODE` setting:
LANGUAGE_CODE = "es-es"
You can turn on per-request language requests by adding `LocalMiddleware` to your `MIDDLEWARE_CLASSES` setting:
MIDDLEWARE_CLASSES = [
...
'django.middleware.locale.LocaleMiddleware'
]
When per-request internationalization is enabled, client requests will respect the `Accept-Language` header where possible. For example, let's make a request for an unsupported media type:
**Request**
GET /api/users HTTP/1.1
Accept: application/xml
Accept-Language: es-es
Host: example.org
**Response**
HTTP/1.0 406 NOT ACCEPTABLE
{"detail": "No se ha podido satisfacer la solicitud de cabecera de Accept."}
REST framework includes these built-in translations both for standard exception cases, and for serializer validation errors.
Note that the translations only apply to the error strings themselves. The format of error messages, and the keys of field names will remain the same. An example `400 Bad Request` response body might look like this: Note that the translations only apply to the error strings themselves. The format of error messages, and the keys of field names will remain the same. An example `400 Bad Request` response body might look like this:
{"detail": {"username": ["Esse campo deve ser unico."]}} {"detail": {"username": ["Esse campo deve ser unico."]}}
If you want to use different string for parts of the response such as `detail` and `non_field_errors` then you can modify this behavior by using a [custom exception handler][custom-exception-handler]. If you want to use different string for parts of the response such as `detail` and `non_field_errors` then you can modify this behavior by using a [custom exception handler][custom-exception-handler].
#### Specifying the set of supported languages.
By default all available languages will be supported.
If you only wish to support a subset of the available languages, use Django's standard `LANGUAGES` setting:
LANGUAGES = [
('de', _('German')),
('en', _('English')),
]
## Adding new translations ## Adding new translations
REST framework translations are managed online using [Transifex][transifex-project]. You can use the Transifex service to add new translation languages. The maintenance team will then ensure that these translation strings are included in the REST framework package. REST framework translations are managed online using [Transifex][transifex-project]. You can use the Transifex service to add new translation languages. The maintenance team will then ensure that these translation strings are included in the REST framework package.

View File

@ -54,4 +54,3 @@ pages:
- ['topics/3.1-announcement.md', 'Topics', '3.1 Announcement'] - ['topics/3.1-announcement.md', 'Topics', '3.1 Announcement']
- ['topics/kickstarter-announcement.md', 'Topics', 'Kickstarter Announcement'] - ['topics/kickstarter-announcement.md', 'Topics', 'Kickstarter Announcement']
- ['topics/release-notes.md', 'Topics', 'Release Notes'] - ['topics/release-notes.md', 'Topics', 'Release Notes']
- ['topics/credits.md', 'Topics', 'Credits']